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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.