Merge https://source.denx.de/u-boot/custodians/u-boot-riscv

+ ae350: modify memory layout and target name
+ ae350: use generic RISC-V timer driver in S-mode
+ Support bootstage report for RISC-V
+ Support C extension exception command for RISC-V
+ Add Starfive timer support
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 1c62c23..183885e 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -8,8 +8,8 @@
 	prompt "Target select"
 	optional
 
-config TARGET_AE350
-	bool "Support ae350"
+config TARGET_ANDES_AE350
+	bool "Support Andes ae350"
 
 config TARGET_MICROCHIP_ICICLE
 	bool "Support Microchip PolarFire-SoC Icicle Board"
@@ -141,6 +141,7 @@
 
 config RISCV_SMODE
 	bool "Supervisor"
+	imply DEBUG_UART
 	help
 	  Choose this option to build U-Boot for RISC-V S-Mode.
 
diff --git a/arch/riscv/cpu/andesv5/Kconfig b/arch/riscv/cpu/andesv5/Kconfig
index 82bb5a2..f311291 100644
--- a/arch/riscv/cpu/andesv5/Kconfig
+++ b/arch/riscv/cpu/andesv5/Kconfig
@@ -4,8 +4,9 @@
 	imply CPU
 	imply CPU_RISCV
 	imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE)
+	imply ANDES_PLMT_TIMER
+	imply SPL_ANDES_PLMT_TIMER
 	imply ANDES_PLICSW if (RISCV_MMODE || SPL_RISCV_MMODE)
-	imply ANDES_PLMT_TIMER if (RISCV_MMODE || SPL_RISCV_MMODE)
 	imply V5L2_CACHE
 	imply SPL_CPU
 	imply SPL_OPENSBI
diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile
index f1525cb..be6c8a4 100644
--- a/arch/riscv/dts/Makefile
+++ b/arch/riscv/dts/Makefile
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0+
 
-dtb-$(CONFIG_TARGET_AE350) += ae350_32.dtb ae350_64.dtb
+dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb
 dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += mpfs-icicle-kit.dtb
 dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt32.dtb qemu-virt64.dtb
 dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb
diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c
index 276677a..cc30efc 100644
--- a/arch/riscv/lib/bootm.c
+++ b/arch/riscv/lib/bootm.c
@@ -42,7 +42,7 @@
 #ifdef CONFIG_BOOTSTAGE_FDT
 	bootstage_fdt_add_report();
 #endif
-#ifdef CONFIG_BOOTSTAGE_REPORT
+#if CONFIG_IS_ENABLED(BOOTSTAGE_REPORT)
 	bootstage_report();
 #endif
 
diff --git a/board/AndesTech/ae350/Kconfig b/board/AndesTech/ae350/Kconfig
index 75815bf..a85e7d6 100644
--- a/board/AndesTech/ae350/Kconfig
+++ b/board/AndesTech/ae350/Kconfig
@@ -1,4 +1,4 @@
-if TARGET_AE350
+if TARGET_ANDES_AE350
 
 config SYS_CPU
 	default "andesv5"
diff --git a/cmd/riscv/exception.c b/cmd/riscv/exception.c
index 7a08061..f38f454 100644
--- a/cmd/riscv/exception.c
+++ b/cmd/riscv/exception.c
@@ -8,6 +8,15 @@
 #include <common.h>
 #include <command.h>
 
+static int do_compressed(struct cmd_tbl *cmdtp, int flag, int argc,
+			 char *const argv[])
+{
+	/* c.li a0, 0; c.li a0, 0 */
+	asm volatile (".long 0x45014501\n");
+	printf("The system supports compressed instructions.\n");
+	return CMD_RET_SUCCESS;
+}
+
 static int do_ebreak(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
@@ -15,6 +24,19 @@
 	return CMD_RET_FAILURE;
 }
 
+static int do_ialign16(struct cmd_tbl *cmdtp, int flag, int argc,
+		       char *const argv[])
+{
+	asm volatile (
+		/* jump skipping 2 bytes */
+		".long 0x0060006f\n"
+		".long 0x006f0000\n"
+		".long 0x00000060\n"
+	);
+	printf("The system supports 16 bit aligned instructions.\n");
+	return CMD_RET_SUCCESS;
+}
+
 static int do_unaligned(struct cmd_tbl *cmdtp, int flag, int argc,
 			char *const argv[])
 {
@@ -35,8 +57,12 @@
 }
 
 static struct cmd_tbl cmd_sub[] = {
+	U_BOOT_CMD_MKENT(compressed, CONFIG_SYS_MAXARGS, 1, do_compressed,
+			 "", ""),
 	U_BOOT_CMD_MKENT(ebreak, CONFIG_SYS_MAXARGS, 1, do_ebreak,
 			 "", ""),
+	U_BOOT_CMD_MKENT(ialign16, CONFIG_SYS_MAXARGS, 1, do_ialign16,
+			 "", ""),
 	U_BOOT_CMD_MKENT(unaligned, CONFIG_SYS_MAXARGS, 1, do_unaligned,
 			 "", ""),
 	U_BOOT_CMD_MKENT(undefined, CONFIG_SYS_MAXARGS, 1, do_undefined,
@@ -46,9 +72,11 @@
 static char exception_help_text[] =
 	"<ex>\n"
 	"  The following exceptions are available:\n"
-	"  ebreak    - breakpoint\n"
-	"  undefined - illegal instruction\n"
-	"  unaligned - load address misaligned\n"
+	"  compressed - compressed instruction\n"
+	"  ebreak     - breakpoint\n"
+	"  ialign16   - 16 bit aligned instruction\n"
+	"  undefined  - illegal instruction\n"
+	"  unaligned  - load address misaligned\n"
 	;
 
 #include <exception.h>
diff --git a/configs/ae350_rv32_defconfig b/configs/ae350_rv32_defconfig
index ce312a6..8269b8d 100644
--- a/configs/ae350_rv32_defconfig
+++ b/configs/ae350_rv32_defconfig
@@ -8,7 +8,8 @@
 CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
 CONFIG_SYS_MONITOR_LEN=786432
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
+CONFIG_FIT=y
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
 CONFIG_DISTRO_DEFAULTS=y
diff --git a/configs/ae350_rv32_spl_defconfig b/configs/ae350_rv32_spl_defconfig
index 7f7ce03..619be52 100644
--- a/configs/ae350_rv32_spl_defconfig
+++ b/configs/ae350_rv32_spl_defconfig
@@ -7,25 +7,27 @@
 CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
 CONFIG_SYS_MONITOR_LEN=786432
-CONFIG_SPL_SYS_MALLOC_F_LEN=0x100000
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000000
 CONFIG_SPL=y
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
 CONFIG_RISCV_SMODE=y
 # CONFIG_AVAILABLE_HARTS is not set
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
-CONFIG_SPL_LOAD_FIT_ADDRESS=0x00200000
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
+CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTDELAY=3
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x100000
-CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_START_ADDR=0x400000
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_CACHE=y
 CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_SPL_OPENSBI_SCRATCH_OPTIONS=0x0
 CONFIG_SYS_PBSIZE=1050
 CONFIG_SYS_BOOTM_LEN=0x4000000
 CONFIG_CMD_IMLS=y
diff --git a/configs/ae350_rv32_spl_xip_defconfig b/configs/ae350_rv32_spl_xip_defconfig
index 7b0c657..676db37 100644
--- a/configs/ae350_rv32_spl_xip_defconfig
+++ b/configs/ae350_rv32_spl_xip_defconfig
@@ -8,10 +8,10 @@
 CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
 CONFIG_SPL_TEXT_BASE=0x80000000
 CONFIG_SYS_MONITOR_LEN=786432
-CONFIG_SPL_SYS_MALLOC_F_LEN=0x100000
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000000
 CONFIG_SPL=y
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
 CONFIG_RISCV_SMODE=y
 CONFIG_SPL_XIP=y
 CONFIG_SYS_MONITOR_BASE=0x88000000
@@ -23,10 +23,11 @@
 CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x100000
-CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_START_ADDR=0x400000
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_CACHE=y
 CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_SPL_OPENSBI_SCRATCH_OPTIONS=0x0
 CONFIG_SYS_PBSIZE=1050
 CONFIG_SYS_BOOTM_LEN=0x4000000
 CONFIG_CMD_IMLS=y
diff --git a/configs/ae350_rv32_xip_defconfig b/configs/ae350_rv32_xip_defconfig
index 641c100..b90200a 100644
--- a/configs/ae350_rv32_xip_defconfig
+++ b/configs/ae350_rv32_xip_defconfig
@@ -8,7 +8,7 @@
 CONFIG_DEFAULT_DEVICE_TREE="ae350_32"
 CONFIG_SYS_MONITOR_LEN=786432
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
 CONFIG_XIP=y
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
diff --git a/configs/ae350_rv64_defconfig b/configs/ae350_rv64_defconfig
index 02d8c07..a4b9ad6 100644
--- a/configs/ae350_rv64_defconfig
+++ b/configs/ae350_rv64_defconfig
@@ -7,7 +7,7 @@
 CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
 CONFIG_ARCH_RV64I=y
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
diff --git a/configs/ae350_rv64_spl_defconfig b/configs/ae350_rv64_spl_defconfig
index 4655050..f67fe80 100644
--- a/configs/ae350_rv64_spl_defconfig
+++ b/configs/ae350_rv64_spl_defconfig
@@ -6,26 +6,29 @@
 CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x10000000
 CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
-CONFIG_SPL_SYS_MALLOC_F_LEN=0x100000
+CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000000
 CONFIG_SPL=y
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
 CONFIG_ARCH_RV64I=y
 CONFIG_RISCV_SMODE=y
 # CONFIG_AVAILABLE_HARTS is not set
 CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_FIT=y
-CONFIG_SPL_LOAD_FIT_ADDRESS=0x00200000
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
+CONFIG_SYS_MONITOR_BASE=0x88000000
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTDELAY=3
 CONFIG_DISPLAY_CPUINFO=y
 CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x100000
-CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_START_ADDR=0x400000
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_CACHE=y
 CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_SPL_OPENSBI_SCRATCH_OPTIONS=0x0
 CONFIG_SYS_PBSIZE=1050
 CONFIG_SYS_BOOTM_LEN=0x4000000
 CONFIG_CMD_IMLS=y
diff --git a/configs/ae350_rv64_spl_xip_defconfig b/configs/ae350_rv64_spl_xip_defconfig
index ad721d1..6f8f9f5 100644
--- a/configs/ae350_rv64_spl_xip_defconfig
+++ b/configs/ae350_rv64_spl_xip_defconfig
@@ -7,10 +7,11 @@
 CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
 CONFIG_SPL_TEXT_BASE=0x80000000
-CONFIG_SPL_SYS_MALLOC_F_LEN=0x100000
+CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000000
 CONFIG_SPL=y
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
 CONFIG_ARCH_RV64I=y
 CONFIG_RISCV_SMODE=y
 CONFIG_SPL_XIP=y
@@ -23,10 +24,11 @@
 CONFIG_DISPLAY_BOARDINFO=y
 CONFIG_BOARD_EARLY_INIT_F=y
 CONFIG_SPL_MAX_SIZE=0x100000
-CONFIG_SPL_BSS_START_ADDR=0x4000000
+CONFIG_SPL_BSS_START_ADDR=0x400000
 CONFIG_SPL_BOARD_INIT=y
 CONFIG_SPL_CACHE=y
 CONFIG_SYS_PROMPT="RISC-V # "
+CONFIG_SPL_OPENSBI_SCRATCH_OPTIONS=0x0
 CONFIG_SYS_PBSIZE=1050
 CONFIG_SYS_BOOTM_LEN=0x4000000
 CONFIG_CMD_IMLS=y
diff --git a/configs/ae350_rv64_xip_defconfig b/configs/ae350_rv64_xip_defconfig
index 042d876..cc5e751 100644
--- a/configs/ae350_rv64_xip_defconfig
+++ b/configs/ae350_rv64_xip_defconfig
@@ -7,7 +7,7 @@
 CONFIG_ENV_SECT_SIZE=0x1000
 CONFIG_DEFAULT_DEVICE_TREE="ae350_64"
 CONFIG_SYS_LOAD_ADDR=0x100000
-CONFIG_TARGET_AE350=y
+CONFIG_TARGET_ANDES_AE350=y
 CONFIG_ARCH_RV64I=y
 CONFIG_XIP=y
 CONFIG_SYS_MONITOR_BASE=0x88000000
diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig
index 867611b..71c0fb3 100644
--- a/configs/sifive_unmatched_defconfig
+++ b/configs/sifive_unmatched_defconfig
@@ -47,6 +47,7 @@
 CONFIG_CMD_PWM=y
 CONFIG_CMD_GPT_RENAME=y
 CONFIG_CMD_PCI=y
+CONFIG_CMD_POWEROFF=y
 CONFIG_CMD_USB=y
 CONFIG_ENV_SPI_BUS=1
 CONFIG_SYS_RELOC_GD_ENV_ADDR=y
diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig
index 915b2af..60519c3 100644
--- a/drivers/timer/Kconfig
+++ b/drivers/timer/Kconfig
@@ -59,7 +59,14 @@
 
 config ANDES_PLMT_TIMER
 	bool
-	depends on RISCV_MMODE || SPL_RISCV_MMODE
+	depends on RISCV_MMODE
+	help
+	  The Andes PLMT block holds memory-mapped mtime register
+	  associated with timer tick.
+
+config SPL_ANDES_PLMT_TIMER
+	bool
+	depends on SPL_RISCV_MMODE
 	help
 	  The Andes PLMT block holds memory-mapped mtime register
 	  associated with timer tick.
@@ -326,4 +333,11 @@
 	  Select this to enable support for the timer found on
 	  any Xilinx boards (axi timer).
 
+config STARFIVE_TIMER
+	bool "Starfive timer support"
+	depends on TIMER
+	help
+	  Select this to enable support for the timer found on
+	  Starfive SoC.
+
 endmenu
diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile
index 1ca7480..b93145e 100644
--- a/drivers/timer/Makefile
+++ b/drivers/timer/Makefile
@@ -4,7 +4,7 @@
 
 obj-y += timer-uclass.o
 obj-$(CONFIG_ALTERA_TIMER)	+= altera_timer.o
-obj-$(CONFIG_ANDES_PLMT_TIMER) += andes_plmt_timer.o
+obj-$(CONFIG_$(SPL_)ANDES_PLMT_TIMER) += andes_plmt_timer.o
 obj-$(CONFIG_ARC_TIMER)	+= arc_timer.o
 obj-$(CONFIG_ARM_TWD_TIMER)	+= arm_twd_timer.o
 obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
@@ -34,3 +34,4 @@
 obj-$(CONFIG_MCHP_PIT64B_TIMER)	+= mchp-pit64b-timer.o
 obj-$(CONFIG_IMX_GPT_TIMER)	+= imx-gpt-timer.o
 obj-$(CONFIG_XILINX_TIMER)	+= xilinx-timer.o
+obj-$(CONFIG_STARFIVE_TIMER)	+= starfive-timer.o
diff --git a/drivers/timer/riscv_aclint_timer.c b/drivers/timer/riscv_aclint_timer.c
index e29d527..73fb879 100644
--- a/drivers/timer/riscv_aclint_timer.c
+++ b/drivers/timer/riscv_aclint_timer.c
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <clk.h>
+#include <div64.h>
 #include <dm.h>
 #include <timer.h>
 #include <asm/io.h>
@@ -44,6 +45,28 @@
 }
 #endif
 
+#if CONFIG_IS_ENABLED(RISCV_MMODE) && CONFIG_IS_ENABLED(BOOTSTAGE)
+ulong timer_get_boot_us(void)
+{
+	int ret;
+	u64 ticks = 0;
+	u32 rate;
+
+	ret = dm_timer_init();
+	if (!ret) {
+		rate = timer_get_rate(gd->timer);
+		timer_get_count(gd->timer, &ticks);
+	} else {
+		rate = RISCV_MMODE_TIMER_FREQ;
+		ticks = readq((void __iomem *)MTIME_REG(RISCV_MMODE_TIMERBASE,
+							RISCV_MMODE_TIMEROFF));
+	}
+
+	/* Below is converted from time(us) = (tick / rate) * 10000000 */
+	return lldiv(ticks * 1000, (rate / 1000));
+}
+#endif
+
 static const struct timer_ops riscv_aclint_timer_ops = {
 	.get_count = riscv_aclint_timer_get_count,
 };
diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
index 28a6a68..169c03d 100644
--- a/drivers/timer/riscv_timer.c
+++ b/drivers/timer/riscv_timer.c
@@ -11,6 +11,7 @@
  */
 
 #include <common.h>
+#include <div64.h>
 #include <dm.h>
 #include <errno.h>
 #include <fdt_support.h>
@@ -51,6 +52,27 @@
 }
 #endif
 
+#if CONFIG_IS_ENABLED(RISCV_SMODE) && CONFIG_IS_ENABLED(BOOTSTAGE)
+ulong timer_get_boot_us(void)
+{
+	int ret;
+	u64 ticks = 0;
+	u32 rate;
+
+	ret = dm_timer_init();
+	if (!ret) {
+		rate = timer_get_rate(gd->timer);
+		timer_get_count(gd->timer, &ticks);
+	} else {
+		rate = RISCV_SMODE_TIMER_FREQ;
+		ticks = riscv_timer_get_count(NULL);
+	}
+
+	/* Below is converted from time(us) = (tick / rate) * 10000000 */
+	return lldiv(ticks * 1000, (rate / 1000));
+}
+#endif
+
 static int riscv_timer_probe(struct udevice *dev)
 {
 	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
diff --git a/drivers/timer/starfive-timer.c b/drivers/timer/starfive-timer.c
new file mode 100644
index 0000000..816402f
--- /dev/null
+++ b/drivers/timer/starfive-timer.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022 StarFive, Inc. All rights reserved.
+ *   Author: Lee Kuan Lim <kuanlim.lee@starfivetech.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <time.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <dm/device-internal.h>
+#include <linux/err.h>
+
+#define	STF_TIMER_INT_STATUS	0x00
+#define STF_TIMER_CTL		0x04
+#define STF_TIMER_LOAD		0x08
+#define STF_TIMER_ENABLE	0x10
+#define STF_TIMER_RELOAD	0x14
+#define STF_TIMER_VALUE		0x18
+#define STF_TIMER_INT_CLR	0x20
+#define STF_TIMER_INT_MASK	0x24
+
+struct starfive_timer_priv {
+	void __iomem *base;
+	u32 timer_size;
+};
+
+static u64 notrace starfive_get_count(struct udevice *dev)
+{
+	struct starfive_timer_priv *priv = dev_get_priv(dev);
+
+	/* Read decrement timer value and convert to increment value */
+	return priv->timer_size - readl(priv->base + STF_TIMER_VALUE);
+}
+
+static const struct timer_ops starfive_ops = {
+	.get_count = starfive_get_count,
+};
+
+static int starfive_probe(struct udevice *dev)
+{
+	struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+	struct starfive_timer_priv *priv = dev_get_priv(dev);
+	int timer_channel;
+	struct clk clk;
+	int ret;
+
+	priv->base = dev_read_addr_ptr(dev);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	timer_channel = dev_read_u32_default(dev, "channel", 0);
+	priv->base = priv->base + (0x40 * timer_channel);
+
+	/* Get clock rate from channel selectecd*/
+	ret = clk_get_by_index(dev, timer_channel, &clk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(&clk);
+	if (ret)
+		return ret;
+	uc_priv->clock_rate = clk_get_rate(&clk);
+
+	/* Initiate timer, channel 0 */
+	/* Unmask Interrupt Mask */
+	writel(0, priv->base + STF_TIMER_INT_MASK);
+	/* Single run mode Setting */
+	if (dev_read_bool(dev, "single-run"))
+		writel(1, priv->base + STF_TIMER_CTL);
+	/* Set Reload value */
+	priv->timer_size = dev_read_u32_default(dev, "timer-size", 0xffffffff);
+	writel(priv->timer_size, priv->base + STF_TIMER_LOAD);
+	/* Enable to start timer */
+	writel(1, priv->base + STF_TIMER_ENABLE);
+
+	return 0;
+}
+
+static const struct udevice_id starfive_ids[] = {
+	{ .compatible = "starfive,jh8100-timers" },
+	{ }
+};
+
+U_BOOT_DRIVER(jh8100_starfive_timer) = {
+	.name		= "jh8100_starfive_timer",
+	.id		= UCLASS_TIMER,
+	.of_match	= starfive_ids,
+	.probe		= starfive_probe,
+	.ops		= &starfive_ops,
+	.priv_auto	= sizeof(struct starfive_timer_priv),
+};