Wire up the DesignWare APB timer to the K230 SoC with num-timers=6 and a 50 MHz clock. Connect timer IRQs to the PLIC. Remove the previous unimplemented timer stub.
Signed-off-by: raoyi <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> --- hw/riscv/Kconfig | 1 + hw/riscv/k230.c | 33 ++++++++++++++++++++++++++++++--- include/hw/riscv/k230.h | 8 ++++++++ 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index d89fdfcc86..dea1430b94 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -181,6 +181,7 @@ config K230 select K230_WDT select K230_GSDMA select K230_DECOMP_GZIP + select DW_APB_TIMER config SOPHGO_CV1800B bool diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c index 1e4ca38579..a5d789c070 100644 --- a/hw/riscv/k230.c +++ b/hw/riscv/k230.c @@ -24,6 +24,8 @@ #include "target/riscv/cpu.h" #include "hw/core/loader.h" #include "hw/core/sysbus.h" +#include "hw/core/clock.h" +#include "hw/core/qdev-clock.h" #include "hw/riscv/k230.h" #include "hw/riscv/boot.h" #include "hw/intc/riscv_aclint.h" @@ -36,6 +38,9 @@ #define K230_DIRECT_KERNEL_ADDR 0x8200000 #define K230_DIRECT_DTB_ADDR 0xa000000 +#define K230_TIMER_NUM_CHANNELS 6 +#define K230_TIMER_DEFAULT_FREQ 50000000 + static const MemMapEntry memmap[] = { [K230_DEV_DDRC] = { 0x00000000, 0x80000000 }, [K230_DEV_KPU_L2_CACHE] = { 0x80000000, 0x00200000 }, @@ -118,6 +123,19 @@ static void k230_soc_init(Object *obj) object_initialize_child(obj, "k230-gsdma", &s->gsdma, TYPE_K230_GSDMA); object_initialize_child(obj, "k230-decomp-gzip", &s->decomp_gzip, TYPE_K230_DECOMP_GZIP); + object_initialize_child(obj, "dw-apb-timer", &s->timer, + TYPE_DW_APB_TIMER); + + qdev_prop_set_uint32(DEVICE(&s->timer), "num-timers", + K230_TIMER_NUM_CHANNELS); + + Clock *timer_clk = clock_new(OBJECT(s), "timer-clk"); + clock_set_hz(timer_clk, K230_TIMER_DEFAULT_FREQ); + for (int i = 0; i < K230_TIMER_NUM_CHANNELS; i++) { + g_autofree char *clock_name = g_strdup_printf("timer[%d]", i); + + qdev_connect_clock_in(DEVICE(&s->timer), clock_name, timer_clk); + } qdev_prop_set_uint32(DEVICE(cpu0), "hartid-base", 0); qdev_prop_set_string(DEVICE(cpu0), "cpu-type", TYPE_RISCV_CPU_THEAD_C908); @@ -212,6 +230,18 @@ static void k230_soc_realize(DeviceState *dev, Error **errp) k230_create_uart(sys_mem, DEVICE(s->c908_plic), i); } + /* Timer */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->timer), errp)) { + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer), 0, memmap[K230_DEV_TIMER].base); + + for (int i = 0; i < K230_TIMER_NUM_CHANNELS; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer), i, + qdev_get_gpio_in(DEVICE(s->c908_plic), + K230_TIMER0_IRQ + i)); + } + /* Watchdog */ for (int i = 0; i < 2; i++) { if (!sysbus_realize(SYS_BUS_DEVICE(&s->wdt[i]), errp)) { @@ -325,9 +355,6 @@ static void k230_soc_realize(DeviceState *dev, Error **errp) create_unimplemented_device("iomux", memmap[K230_DEV_IOMUX].base, memmap[K230_DEV_IOMUX].size); - create_unimplemented_device("timer", memmap[K230_DEV_TIMER].base, - memmap[K230_DEV_TIMER].size); - create_unimplemented_device("wdt0", memmap[K230_DEV_WDT0].base, memmap[K230_DEV_WDT0].size); diff --git a/include/hw/riscv/k230.h b/include/hw/riscv/k230.h index 8679d09891..4c416573eb 100644 --- a/include/hw/riscv/k230.h +++ b/include/hw/riscv/k230.h @@ -21,6 +21,7 @@ #include "hw/watchdog/k230_wdt.h" #include "hw/dma/k230_gsdma.h" #include "hw/misc/k230_decomp_gzip.h" +#include "hw/timer/dw-apb-timer.h" #define C908_CPU_HARTID (0) @@ -40,6 +41,7 @@ typedef struct K230SoCState { K230WdtState wdt[2]; K230GSDMAState gsdma; K230DecompGzipState decomp_gzip; + DWAPBTimerState timer; MemoryRegion sram; MemoryRegion bootrom; @@ -135,6 +137,12 @@ enum { K230_UART2_IRQ = 18, K230_UART3_IRQ = 19, K230_UART4_IRQ = 20, + K230_TIMER0_IRQ = 101, + K230_TIMER1_IRQ = 102, + K230_TIMER2_IRQ = 103, + K230_TIMER3_IRQ = 104, + K230_TIMER4_IRQ = 105, + K230_TIMER5_IRQ = 106, K230_WDT0_IRQ = 107, K230_WDT1_IRQ = 108, K230_GSDMA_IRQ = 140, -- 2.53.0
