SG2042: add virtual global timer device driver
Add a virtual global timer device driver. It uses a global timer
register as timer counter, and it uses mtimecmp CSR of clint as
interrupt source.
Using this virtul timer resolves dual way timer sync issue.
On dual way system, we should enable this driver and on single way
system, we should use standard risc-v clint timer.
1. Add a virtual global timer device driver, it is probed by fdt
sg2042-global-mtimer@70300101c0 {
compatible = "sophgo,sg2042-global-mtimer";
reg = < 0x00000070 0x300101c0 0x00000000 0x00000008
0x00000070 0xac000000 0x00000000 0x00200000>;
clock-frequency = <50000000 50000000>;
};
Its compatible should be "sophgo,sg2042-global-mtimer".
And the first region delcared in reg prop is the address of global
timer. The second region delcared in reg prop is the base of clint
timers.
The first clock in clock-frequency is the actual frequency of global
timer, the second clock is the actual frequency of clint timer.
2. Add a quirk in platform specific code.
Add a function sbi_platform_force_emulate_time_csr, it indicates if
opensbi should skip time CSR detection and make software in
supervisor and user mode use emulated time CSR.
Signed-off-by: Chao Wei <chao.wei@sophgo.com>
This commit is contained in:
@@ -42,4 +42,5 @@ CONFIG_FDT_SERIAL_XILINX_UARTLITE=y
|
||||
CONFIG_FDT_TIMER=y
|
||||
CONFIG_FDT_TIMER_MTIMER=y
|
||||
CONFIG_FDT_TIMER_PLMT=y
|
||||
CONFIG_FDT_TIMER_SG2042_GMT=y
|
||||
CONFIG_SERIAL_SEMIHOSTING=y
|
||||
|
||||
@@ -19,6 +19,7 @@ struct platform_override {
|
||||
u64 (*features)(const struct fdt_match *match);
|
||||
u64 (*tlbr_flush_limit)(const struct fdt_match *match);
|
||||
bool (*cold_boot_allowed)(u32 hartid, const struct fdt_match *match);
|
||||
bool (*force_emulate_time_csr)(const struct fdt_match *match);
|
||||
int (*early_init)(bool cold_boot, const struct fdt_match *match);
|
||||
int (*final_init)(bool cold_boot, const struct fdt_match *match);
|
||||
void (*early_exit)(const struct fdt_match *match);
|
||||
|
||||
@@ -134,6 +134,14 @@ static bool generic_cold_boot_allowed(u32 hartid)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool generic_force_emulate_time_csr(void)
|
||||
{
|
||||
if (generic_plat && generic_plat->force_emulate_time_csr)
|
||||
return generic_plat->force_emulate_time_csr(generic_plat_match);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int generic_nascent_init(void)
|
||||
{
|
||||
if (platform_has_mlevel_imsic)
|
||||
@@ -284,6 +292,7 @@ static int generic_console_init(void)
|
||||
|
||||
const struct sbi_platform_operations platform_ops = {
|
||||
.cold_boot_allowed = generic_cold_boot_allowed,
|
||||
.force_emulate_time_csr = generic_force_emulate_time_csr,
|
||||
.nascent_init = generic_nascent_init,
|
||||
.early_init = generic_early_init,
|
||||
.final_init = generic_final_init,
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
#include <sbi/sbi_platform.h>
|
||||
#include <sbi_utils/fdt/fdt_helper.h>
|
||||
#include <sbi_utils/timer/aclint_mtimer.h>
|
||||
#include <libfdt.h>
|
||||
|
||||
#define SOPHGO_MANGO_TIMER_BASE 0x70ac000000UL
|
||||
#define SOPHGO_MANGO_TIMER_OFFSET 0x10000UL
|
||||
|
||||
extern struct sbi_platform platform;
|
||||
static u32 selected_hartid = -1;
|
||||
static bool force_emulate_time_csr;
|
||||
|
||||
static bool mango_cold_boot_allowed(u32 hartid,
|
||||
const struct fdt_match *match)
|
||||
@@ -69,6 +71,16 @@ static int mango_extensions_init(const struct fdt_match *match,
|
||||
static void mango_fw_init(void *fdt, const struct fdt_match *match)
|
||||
{
|
||||
platform.hart_stack_size = 16384;
|
||||
|
||||
if (fdt_node_offset_by_compatible(fdt, 0, "sophgo,sg2042-global-mtimer") > 0)
|
||||
force_emulate_time_csr = true;
|
||||
else
|
||||
force_emulate_time_csr = false;
|
||||
}
|
||||
|
||||
static bool mango_force_emulate_time_csr(const struct fdt_match *match)
|
||||
{
|
||||
return force_emulate_time_csr;
|
||||
}
|
||||
|
||||
static const struct fdt_match sophgo_mango_match[] = {
|
||||
@@ -78,8 +90,9 @@ static const struct fdt_match sophgo_mango_match[] = {
|
||||
|
||||
const struct platform_override sophgo_mango = {
|
||||
.match_table = sophgo_mango_match,
|
||||
.fw_init = mango_fw_init,
|
||||
.cold_boot_allowed = mango_cold_boot_allowed,
|
||||
.fw_init = mango_fw_init,
|
||||
.cold_boot_allowed = mango_cold_boot_allowed,
|
||||
.force_emulate_time_csr = mango_force_emulate_time_csr,
|
||||
.early_init = mango_early_init,
|
||||
.extensions_init = mango_extensions_init,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user