Re: [PATCH v4 2/3] hw/riscv: add DesignWare APB timer to K230 board
Bin Meng <[email protected]>
| Newsgroups | org.nongnu.qemu-riscv,org.nongnu.qemu-devel |
|---|---|
| Message-ID | <CAEUhbmV5biKom60BZf9QD+gTCJ67Dw+iW4sBoVWj8Oa+8q0mZg@mail.gmail.com> |
On Thu, Aug 13, 2026 at 9:37 PM raoyi <[email protected]> wrote: > > 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 | 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 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..78a05492ad 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" > @@ -37,6 +39,9 @@ > #define K230_DIRECT_KERNEL_ADDR 0x8200000 > #define K230_DIRECT_DTB_ADDR 0xa000000 > > +#define K230_TIMER_NUM_CHANNELS 6 > +#define K230_TIMER_DEFAULT_FREQ 6250000 The TRM says the timer frequency is 50MHz. Where is this 6250000 coming from? > + > static const MemMapEntry memmap[] = { > [K230_DEV_DDRC] = { 0x00000000, 0x80000000 }, > [K230_DEV_KPU_L2_CACHE] = { 0x80000000, 0x00200000 }, > @@ -110,6 +115,19 @@ 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); > + > + 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 +209,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 +313,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..42a36664eb 100644 > --- a/include/hw/riscv/k230.h > +++ b/include/hw/riscv/k230.h > @@ -18,6 +18,7 @@ > #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) > > @@ -33,6 +34,7 @@ typedef struct K230SoCState { > RISCVHartArrayState c908_cpu; /* Small core */ > > K230WdtState wdt[2]; > + DWAPBTimerState timer; > MemoryRegion sram; > MemoryRegion bootrom; > > @@ -127,6 +129,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, > }; > -- Regards, Bin