Wire up the DesignWare APB timer to the K230 SoC with num-timers=6 and a 6.25 MHz clock. Connect timer IRQs to the PLIC. Remove the previous unimplemented timer stub.
Signed-off-by: raoyi <[email protected]> --- hw/riscv/Kconfig | 1 + hw/riscv/k230.c | 32 +++++++++++++++++++++++++++++--- include/hw/riscv/k230.h | 12 ++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index de37c08cae..c2c01af6ee 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -162,3 +162,4 @@ config K230 select SERIAL_MM select UNIMP select K230_WDT + select DW_APB_TIMER diff --git a/hw/riscv/k230.c b/hw/riscv/k230.c index 656f28190c..a3457e79ff 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/riscv/machines-qom.h" @@ -110,6 +112,21 @@ static void k230_soc_init(Object *obj) object_initialize_child(obj, "c908-cpu", cpu0, TYPE_RISCV_HART_ARRAY); object_initialize_child(obj, "k230-wdt0", &s->wdt[0], TYPE_K230_WDT); object_initialize_child(obj, "k230-wdt1", &s->wdt[1], TYPE_K230_WDT); + 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); + qdev_prop_set_uint32(DEVICE(&s->timer), "comp-version", + K230_TIMER_COMP_VERSION); + + 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); @@ -191,6 +208,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)) { @@ -283,9 +312,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 592e1c26bf..0f872554c8 100644 --- a/include/hw/riscv/k230.h +++ b/include/hw/riscv/k230.h @@ -18,9 +18,14 @@ #include "hw/core/boards.h" #include "hw/riscv/riscv_hart.h" #include "hw/watchdog/k230_wdt.h" +#include "hw/timer/dw-apb-timer.h" #define C908_CPU_HARTID (0) +#define K230_TIMER_NUM_CHANNELS 6 +#define K230_TIMER_DEFAULT_FREQ 6250000 +#define K230_TIMER_COMP_VERSION 0x3231312A + #define TYPE_RISCV_K230_SOC "riscv.k230.soc" #define RISCV_K230_SOC(obj) \ OBJECT_CHECK(K230SoCState, (obj), TYPE_RISCV_K230_SOC) @@ -33,6 +38,7 @@ typedef struct K230SoCState { RISCVHartArrayState c908_cpu; /* Small core */ K230WdtState wdt[2]; + DWAPBTimerState timer; MemoryRegion sram; MemoryRegion bootrom; @@ -127,6 +133,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, }; -- 2.53.0
