lkml.org 
[lkml]   [2024]   [May]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
Subject回复: 回复: [PATCH v10 2/3] clocksource: Add JH7110 timer driver
Date


> -----邮件原件-----
> 发件人: Emil Renner Berthing <emil.renner.berthing@canonical.com>
> 发送时间: 2024年4月30日 18:19
> 收件人: Ziv Xu <ziv.xu@starfivetech.com>; Daniel Lezcano
> <daniel.lezcano@linaro.org>; Thomas Gleixner <tglx@linutronix.de>
> 抄送: linux-riscv@lists.infradead.org; devicetree@vger.kernel.org; Rob Herring
> <robh+dt@kernel.org>; Krzysztof Kozlowski
> <krzysztof.kozlowski+dt@linaro.org>; Paul Walmsley
> <paul.walmsley@sifive.com>; Palmer Dabbelt <palmer@dabbelt.com>; Albert
> Ou <aou@eecs.berkeley.edu>; Philipp Zabel <p.zabel@pengutronix.de>; Walker
> Chen <walker.chen@starfivetech.com>; Xingyu Wu
> <xingyu.wu@starfivetech.com>; linux-kernel@vger.kernel.org; Conor Dooley
> <conor@kernel.org>
> 主题: Re: 回复: [PATCH v10 2/3] clocksource: Add JH7110 timer driver
>
> Ziv Xu wrote:
> >
> >
> > > -----邮件原件-----
> > > 发件人: Ziv Xu
> > > 发送时间: 2024年4月12日 16:46
> > > 收件人: Daniel Lezcano <daniel.lezcano@linaro.org>; Thomas Gleixner
> > > <tglx@linutronix.de>; Emil Renner Berthing
> > > <emil.renner.berthing@canonical.com>; Christophe JAILLET
> > > <christophe.jaillet@wanadoo.fr>
> > > 抄送: linux-riscv@lists.infradead.org; devicetree@vger.kernel.org; Rob
> > > Herring <robh+dt@kernel.org>; Krzysztof Kozlowski
> > > <krzysztof.kozlowski+dt@linaro.org>; Paul Walmsley
> > > <paul.walmsley@sifive.com>; Palmer Dabbelt <palmer@dabbelt.com>;
> > > Albert Ou <aou@eecs.berkeley.edu>; Philipp Zabel
> > > <p.zabel@pengutronix.de>; Walker Chen
> > > <walker.chen@starfivetech.com>; Xingyu Wu
> > > <xingyu.wu@starfivetech.com>; linux-kernel@vger.kernel.org; Conor
> > > Dooley <conor@kernel.org>
> > > 主题: [PATCH v10 2/3] clocksource: Add JH7110 timer driver
> > >
> > > From: Xingyu Wu <xingyu.wu@starfivetech.com>
> > >
> > > Add timer driver for the StarFive JH7110 SoC.
> > >
> > > This timer has four free-running and independent 32-bit counters.
> > > Each channel(counter) can trigger an interrupt when timeout even CPU
> > > is sleeping. So this timer is used as global timer and register
> > > clockevent for each CPU core after riscv-timer registration on the StarFive
> JH7110 SoC.
> > >
> > > Signed-off-by: Ziv Xu <ziv.xu@starfivetech.com>
> > > Signed-off-by: Xingyu Wu <xingyu.wu@starfivetech.com>
> > > ---
> > > MAINTAINERS | 7 +
> > > drivers/clocksource/Kconfig | 11 +
> > > drivers/clocksource/Makefile | 1 +
> > > drivers/clocksource/timer-jh7110.c | 345
> +++++++++++++++++++++++++++++
> > > include/linux/cpuhotplug.h | 1 +
> > > 5 files changed, 365 insertions(+)
> > > create mode 100644 drivers/clocksource/timer-jh7110.c
> > >
> > > diff --git a/MAINTAINERS b/MAINTAINERS index
> > > 7c121493f43d..ef9b5f5bad9e 100644
> > > --- a/MAINTAINERS
> > > +++ b/MAINTAINERS
> > > @@ -21043,6 +21043,13 @@ S: Maintained
> > > F: Documentation/devicetree/bindings/sound/starfive,jh7110-tdm.yaml
> > > F: sound/soc/starfive/jh7110_tdm.c
> > >
> > > +STARFIVE JH7110 TIMER DRIVER
> > > +M: Samin Guo <samin.guo@starfivetech.com>
> > > +M: Xingyu Wu <xingyu.wu@starfivetech.com>
> > > +S: Supported
> > > +F: Documentation/devicetree/bindings/timer/starfive,jh7110-timer.yaml
> > > +F: drivers/clocksource/timer-jh7110.c
> > > +
> > > STARFIVE JH71X0 CLOCK DRIVERS
> > > M: Emil Renner Berthing <kernel@esmil.dk>
> > > M: Hal Feng <hal.feng@starfivetech.com>
> > > diff --git a/drivers/clocksource/Kconfig
> > > b/drivers/clocksource/Kconfig index
> > > 34faa0320ece..2dc97201dee1 100644
> > > --- a/drivers/clocksource/Kconfig
> > > +++ b/drivers/clocksource/Kconfig
> > > @@ -641,6 +641,17 @@ config RISCV_TIMER
> > > is accessed via both the SBI and the rdcycle instruction. This is
> > > required for all RISC-V systems.
> > >
> > > +config STARFIVE_JH7110_TIMER
> > > + bool "Timer for the STARFIVE JH7110 SoC"
> > > + depends on ARCH_STARFIVE || COMPILE_TEST
> > > + select TIMER_OF
> > > + select CLKSRC_MMIO
> > > + default ARCH_STARFIVE
> > > + help
> > > + This enables the timer for StarFive JH7110 SoC. On RISC-V platform,
> > > + the system has started RISCV_TIMER, but you can also use this
> timer
> > > + which can provide four channels to do a lot more things on JH7110
> SoC.
> > > +
> > > config CLINT_TIMER
> > > bool "CLINT Timer for the RISC-V platform" if COMPILE_TEST
> > > depends on GENERIC_SCHED_CLOCK && RISCV diff --git
> > > a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index
> > > 4bb856e4df55..8dc2f0ea2d0f 100644
> > > --- a/drivers/clocksource/Makefile
> > > +++ b/drivers/clocksource/Makefile
> > > @@ -80,6 +80,7 @@ obj-$(CONFIG_INGENIC_TIMER) +=
> ingenic-timer.o
> > > obj-$(CONFIG_CLKSRC_ST_LPC) += clksrc_st_lpc.o
> > > obj-$(CONFIG_X86_NUMACHIP) += numachip.o
> > > obj-$(CONFIG_RISCV_TIMER) += timer-riscv.o
> > > +obj-$(CONFIG_STARFIVE_JH7110_TIMER) += timer-jh7110.o
> > > obj-$(CONFIG_CLINT_TIMER) += timer-clint.o
> > > obj-$(CONFIG_CSKY_MP_TIMER) += timer-mp-csky.o
> > > obj-$(CONFIG_GX6605S_TIMER) += timer-gx6605s.o
> > > diff --git a/drivers/clocksource/timer-jh7110.c
> > > b/drivers/clocksource/timer-jh7110.c
> > > new file mode 100644
> > > index 000000000000..dc770507f209
> > > --- /dev/null
> > > +++ b/drivers/clocksource/timer-jh7110.c
> > > @@ -0,0 +1,345 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Starfive JH7110 Timer driver
> > > + *
> > > + * Copyright (C) 2023 StarFive Technology Co., Ltd.
> > > + *
> > > + * This timer has four free-running and independent 32-bit counters
> > > +and runs in 24MHz
> > > + * clock on the StarFive JH7110 SoC. Each channel(counter) can
> > > +trigger an interrupt
> > > + * when timeout even CPU is sleeping. They support one-shot mode
> > > +and
> > > continuous-run mode.
> > > + *
> > > + * Each channel is used as a global timer that serves each cpu core:
> > > + * JH7110 Timer Channel 0 -- CPU 0
> > > + * JH7110 Timer Channel 1 -- CPU 1
> > > + * JH7110 Timer Channel 2 -- CPU 2
> > > + * JH7110 Timer Channel 3 -- CPU 3
> > > + */
> > > +
> > > +#include <linux/clk.h>
> > > +#include <linux/clockchips.h>
> > > +#include <linux/cpu.h>
> > > +#include <linux/iopoll.h>
> > > +#include <linux/irq.h>
> > > +#include <linux/platform_device.h>
> > > +#include <linux/reset.h>
> > > +
> > > +/* Bias: Ch0-0x0, Ch1-0x40, Ch2-0x80, and so on. */
> > > +#define JH7110_TIMER_CH_LEN 0x40
> > > +#define JH7110_TIMER_CH_BASE(x) ((x) *
> JH7110_TIMER_CH_LEN)
> > > +#define JH7110_TIMER_CH_MAX 4
> > > +
> > > +#define JH7110_DELAY_US 0
> > > +#define JH7110_TIMEOUT_US 10000
> > > +#define JH7110_CLOCKEVENT_RATING 300
> > > +#define JH7110_TIMER_MAX_TICKS 0xffffffff
> > > +#define JH7110_TIMER_MIN_TICKS 0xf
> > > +
> > > +#define JH7110_TIMER_INT_STATUS 0x00 /* RO[0:4]: Interrupt
> Status
> > > for channel0~4 */
> > > +#define JH7110_TIMER_CTL 0x04 /* RW[0]: 0-continuous run,
> 1-single run
> > > */
> > > +#define JH7110_TIMER_LOAD 0x08 /* RW: load value to counter
> */
> > > +#define JH7110_TIMER_ENABLE 0x10 /* RW[0]: timer enable
> register */
> > > +#define JH7110_TIMER_RELOAD 0x14 /* RW: write 1 or 0 both
> reload
> > > counter */
> > > +#define JH7110_TIMER_VALUE 0x18 /* RO: timer value register */
> > > +#define JH7110_TIMER_INT_CLR 0x20 /* RW: timer interrupt clear
> > > register */
> > > +#define JH7110_TIMER_INT_MASK 0x24 /* RW[0]: timer
> interrupt
> > > mask register */
> > > +
> > > +#define JH7110_TIMER_INT_CLR_ENA BIT(0)
> > > +#define JH7110_TIMER_INT_CLR_AVA_MASK BIT(1)
> > > +
> > > +#define JH7110_PERCPU_GET_CLKEVT
> > > (&jh7110_timer_info.clkevt[smp_processor_id()])
> > > +
> > > +/**
> > > + * struct jh7110_clkevt - Description of each timer channel
> > > + * @clk: Clock of each timer channel
> > > + * @rst: Reset of each timer channel
> > > + * @base: Virtual address of each timer channel
> > > + * @irq: Interrupt number of each timer channel
> > > + * @timer_enabled: Enabled flag for each timer channel
> > > + * @name: Name of each timer channel
> > > + */
> > > +struct jh7110_clkevt {
> > > + struct clk *clk;
> > > + struct reset_control *rst;
> > > + void __iomem *base;
> > > + int irq;
> > > + bool timer_enabled;
> > > + char name[sizeof("jh7110-timer.chX")];
> > > +};
> > > +
> > > +struct jh7110_timer_priv {
> > > + struct clk *pclk;
> > > + struct reset_control *prst;
> > > + struct device *dev;
> > > + struct jh7110_clkevt clkevt[JH7110_TIMER_CH_MAX];
> > > +};
> > > +
> > > +static struct jh7110_timer_priv jh7110_timer_info;
> > > +
> > > +/* 0:continuous-run mode, 1:single-run mode */ enum jh7110_timer_mode
> {
> > > + JH7110_TIMER_MODE_CONTIN,
> > > + JH7110_TIMER_MODE_SINGLE,
> > > +};
> > > +
> > > +/* Interrupt Mask, 0:Unmask, 1:Mask */ enum jh7110_timer_int_mask {
> > > + JH7110_TIMER_INT_ENA,
> > > + JH7110_TIMER_INT_DIS,
> > > +};
> > > +
> > > +enum jh7110_timer_enable {
> > > + JH7110_TIMER_DIS,
> > > + JH7110_TIMER_ENA,
> > > +};
> > > +
> > > +/*
> > > + * BIT(0): Read value represent channel int status.
> > > + * Write 1 to this bit to clear interrupt. Write 0 has no effects.
> > > + * BIT(1): "1" means that it is clearing interrupt. BIT(0) can not be written.
> > > + */
> > > +static inline int jh7110_timer_int_clear(struct jh7110_clkevt
> > > +*clkevt) {
> > > + u32 value;
> > > + int ret;
> > > +
> > > + /* Waiting interrupt can be cleared */
> > > + ret = readl_poll_timeout_atomic(clkevt->base +
> > > +JH7110_TIMER_INT_CLR,
> > > value,
> > > + !(value & JH7110_TIMER_INT_CLR_AVA_MASK),
> > > + JH7110_DELAY_US, JH7110_TIMEOUT_US);
> > > + if (!ret)
> > > + writel(JH7110_TIMER_INT_CLR_ENA, clkevt->base +
> > > +JH7110_TIMER_INT_CLR);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int jh7110_timer_start(struct jh7110_clkevt *clkevt) {
> > > + int ret;
> > > +
> > > + /* Disable and clear interrupt first */
> > > + writel(JH7110_TIMER_INT_DIS, clkevt->base +
> > > JH7110_TIMER_INT_MASK);
> > > + ret = jh7110_timer_int_clear(clkevt);
> > > +
> > > + writel(JH7110_TIMER_INT_ENA, clkevt->base +
> > > JH7110_TIMER_INT_MASK);
> > > + writel(JH7110_TIMER_ENA, clkevt->base + JH7110_TIMER_ENABLE);
> > > +
> > > + return ret;
> > > +}
> > > +
> > > +static int jh7110_timer_shutdown(struct clock_event_device *evt) {
> > > + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT;
> > > +
> > > + writel(JH7110_TIMER_DIS, clkevt->base + JH7110_TIMER_ENABLE);
> > > + return jh7110_timer_int_clear(clkevt); }
> > > +
> > > +/* IRQ handler for the timer */
> > > +static irqreturn_t jh7110_timer_interrupt(int irq, void *data) {
> > > + struct clock_event_device *evt = (struct clock_event_device *)data;
> > > + struct jh7110_clkevt *clkevt = &jh7110_timer_info.clkevt[0];
> > > + u32 reg = readl(clkevt->base + JH7110_TIMER_INT_STATUS);
> > > + u8 cpu_id = smp_processor_id();
> > > +
> > > + /* Check interrupt status and channel(cpu) ID */
> > > + if (!(reg & BIT(cpu_id)))
> > > + return IRQ_NONE;
> > > +
> > > + clkevt = &jh7110_timer_info.clkevt[cpu_id];
> > > + writel(JH7110_TIMER_INT_CLR_ENA, (clkevt->base +
> > > +JH7110_TIMER_INT_CLR));
> > > +
> > > + if (evt->event_handler)
> > > + evt->event_handler(evt);
> > > +
> > > + return IRQ_HANDLED;
> > > +}
> > > +
> > > +static int jh7110_timer_set_periodic(struct clock_event_device *evt) {
> > > + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT;
> > > +
> > > + writel(JH7110_TIMER_MODE_CONTIN, clkevt->base +
> > > JH7110_TIMER_CTL);
> > > + return 0;
> > > +}
> > > +
> > > +static int jh7110_timer_set_oneshot(struct clock_event_device *evt) {
> > > + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT;
> > > +
> > > + writel(JH7110_TIMER_MODE_SINGLE, clkevt->base +
> > > JH7110_TIMER_CTL);
> > > + return 0;
> > > +}
> > > +
> > > +static int jh7110_timer_set_next_event(unsigned long next,
> > > + struct clock_event_device *evt) {
> > > + struct jh7110_clkevt *clkevt = JH7110_PERCPU_GET_CLKEVT;
> > > +
> > > + writel(JH7110_TIMER_MODE_SINGLE, clkevt->base +
> > > JH7110_TIMER_CTL);
> > > + writel(next, clkevt->base + JH7110_TIMER_LOAD);
> > > +
> > > + return jh7110_timer_start(clkevt); }
> > > +
> > > +static DEFINE_PER_CPU(struct clock_event_device, jh7110_clock_event) =
> {
> > > + .features = CLOCK_EVT_FEAT_PERIODIC |
> > > + CLOCK_EVT_FEAT_ONESHOT,
> > > + .rating = JH7110_CLOCKEVENT_RATING,
> > > + .set_state_shutdown = jh7110_timer_shutdown,
> > > + .set_state_periodic = jh7110_timer_set_periodic,
> > > + .set_state_oneshot = jh7110_timer_set_oneshot,
> > > + .set_state_oneshot_stopped = jh7110_timer_shutdown,
> > > + .set_next_event = jh7110_timer_set_next_event,
> > > +};
> > > +
> > > +static int jh7110_timer_dying_cpu(unsigned int cpu) {
> > > + struct jh7110_timer_priv *priv = &jh7110_timer_info;
> > > +
> > > + if (!priv->clkevt[cpu].timer_enabled)
> > > + return 0;
> > > +
> > > + writel(JH7110_TIMER_DIS, priv->clkevt[cpu].base +
> > > JH7110_TIMER_ENABLE);
> > > + jh7110_timer_int_clear(&priv->clkevt[cpu]);
> > > + reset_control_assert(priv->clkevt[cpu].rst);
> > > + clk_disable_unprepare(priv->clkevt[cpu].clk);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static int jh7110_timer_starting_cpu(unsigned int cpu) {
> > > + struct clock_event_device *evt = per_cpu_ptr(&jh7110_clock_event,
> cpu);
> > > + struct jh7110_timer_priv *priv = &jh7110_timer_info;
> > > + int err;
> > > + u32 rate;
> > > +
> > > + if (cpu >= JH7110_TIMER_CH_MAX)
> > > + return -ENOMEM;
> > > +
> > > + err = clk_prepare_enable(priv->clkevt[cpu].clk);
> > > + if (err)
> > > + goto err_starting_cpu;
> > > +
> > > + err = reset_control_deassert(priv->clkevt[cpu].rst);
> > > + if (err)
> > > + goto err_soft_reset;
> > > +
> > > + rate = clk_get_rate(priv->clkevt[cpu].clk);
> > > + evt->cpumask = cpumask_of(cpu);
> > > + evt->irq = priv->clkevt[cpu].irq;
> > > +
> > > + err = irq_force_affinity(evt->irq, cpumask_of(cpu));
> > > + if (err)
> > > + goto err_affinity;
> > > +
> > > + clockevents_config_and_register(evt, rate,
> JH7110_TIMER_MIN_TICKS,
> > > + JH7110_TIMER_MAX_TICKS);
> > > +
> > > + /* Use one-shot mode */
> > > + writel(JH7110_TIMER_MODE_SINGLE, (priv->clkevt[cpu].base +
> > > +JH7110_TIMER_CTL));
> > > +
> > > + priv->clkevt[cpu].timer_enabled = true;
> > > +
> > > + err = jh7110_timer_start(&priv->clkevt[cpu]);
> > > + if (err)
> > > + goto err_affinity;
> > > + return 0;
> > > +
> > > +err_affinity:
> > > + reset_control_assert(priv->clkevt[cpu].rst);
> > > +err_soft_reset:
> > > + clk_disable_unprepare(priv->clkevt[cpu].clk);
> > > +err_starting_cpu:
> > > + free_irq(evt->irq, evt);
> > > + return err;
> > > +}
> > > +
> > > +static int jh7110_timer_probe(struct platform_device *pdev) {
> > > + struct jh7110_timer_priv *priv = &jh7110_timer_info;
> > > + struct clock_event_device *evt;
> > > + struct jh7110_clkevt *clkevt;
> > > + char name[sizeof("chX")];
> > > + int ch;
> > > + int ret;
> > > + void __iomem *base;
> > > +
> > > + base = devm_platform_ioremap_resource(pdev, 0);
> > > + if (IS_ERR(base))
> > > + return dev_err_probe(&pdev->dev, PTR_ERR(base),
> > > + "failed to map registers\n");
> > > +
> > > + priv->prst = devm_reset_control_get_exclusive(&pdev->dev, "apb");
> > > + if (IS_ERR(priv->prst))
> > > + return dev_err_probe(&pdev->dev, PTR_ERR(priv->prst),
> > > + "failed to get apb reset\n");
> > > +
> > > + priv->pclk = devm_clk_get_enabled(&pdev->dev, "apb");
> > > + if (IS_ERR(priv->pclk))
> > > + return dev_err_probe(&pdev->dev, PTR_ERR(priv->pclk),
> > > + "failed to get & enable apb clock\n");
> > > +
> > > + ret = reset_control_deassert(priv->prst);
> > > + if (ret)
> > > + return dev_err_probe(&pdev->dev, ret, "failed to deassert apb
> > > +reset\n");
> > > +
> > > + for (ch = 0; ch < JH7110_TIMER_CH_MAX; ch++) {
> > > + evt = per_cpu_ptr(&jh7110_clock_event, ch);
> > > + clkevt = &priv->clkevt[ch];
> > > + snprintf(name, sizeof(name), "ch%d", ch);
> > > +
> > > + clkevt->base = base + JH7110_TIMER_CH_BASE(ch);
> > > + /* Ensure timer is disabled */
> > > + writel(JH7110_TIMER_DIS, clkevt->base +
> JH7110_TIMER_ENABLE);
> > > + ret = jh7110_timer_int_clear(clkevt);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + clkevt->rst = devm_reset_control_get_exclusive(&pdev->dev,
> name);
> > > + if (IS_ERR(clkevt->rst))
> > > + return PTR_ERR(clkevt->rst);
> > > +
> > > + clkevt->clk = devm_clk_get(&pdev->dev, name);
> > > + if (IS_ERR(clkevt->clk))
> > > + return PTR_ERR(clkevt->clk);
> > > +
> > > + clkevt->irq = platform_get_irq(pdev, ch);
> > > + if (clkevt->irq < 0)
> > > + return clkevt->irq;
> > > +
> > > + snprintf(clkevt->name, sizeof(clkevt->name),
> "jh7110-timer.ch%d",
> > > ch);
> > > + ret = devm_request_irq(&pdev->dev, clkevt->irq,
> > > jh7110_timer_interrupt,
> > > + IRQF_TIMER | IRQF_IRQPOLL,
> > > + clkevt->name, evt);
> > > +
> > > + if (ret)
> > > + return ret;
> > > +
> > > + clkevt->timer_enabled = false;
> > > + }
> > > +
> > > + return cpuhp_setup_state(CPUHP_AP_JH7110_TIMER_STARTING,
> > > + "clockevents/jh7110/timer:starting",
> > > + jh7110_timer_starting_cpu,
> jh7110_timer_dying_cpu); }
> > > +
> > > +static const struct of_device_id jh7110_timer_match[] = {
> > > + { .compatible = "starfive,jh7110-timer", },
> > > + { /* sentinel */ }
> > > +};
> > > +MODULE_DEVICE_TABLE(of, jh7110_timer_match);
> > > +
> > > +static struct platform_driver jh7110_timer_driver = {
> > > + .probe = jh7110_timer_probe,
> > > + .driver = {
> > > + .name = "jh7110-timer",
> > > + .of_match_table = jh7110_timer_match,
> > > + },
> > > +};
> > > +module_platform_driver(jh7110_timer_driver);
> > > +
> > > +MODULE_AUTHOR("Xingyu Wu <xingyu.wu@starfivetech.com>");
> > > +MODULE_DESCRIPTION("StarFive JH7110 timer driver");
> > > +MODULE_LICENSE("GPL");
> > > diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
> > > index 35e78ddb2b37..4a8b487c327e 100644
> > > --- a/include/linux/cpuhotplug.h
> > > +++ b/include/linux/cpuhotplug.h
> > > @@ -175,6 +175,7 @@ enum cpuhp_state {
> > > CPUHP_AP_CSKY_TIMER_STARTING,
> > > CPUHP_AP_TI_GP_TIMER_STARTING,
> > > CPUHP_AP_HYPERV_TIMER_STARTING,
> > > + CPUHP_AP_JH7110_TIMER_STARTING,
> > > /* Must be the last timer callback */
> > > CPUHP_AP_DUMMY_TIMER_STARTING,
> > > CPUHP_AP_ARM_XEN_STARTING,
> > > --
> > > 2.17.1
> >
> > Hi Daniel / Thomas
> >
> > I have submitted new version of patch for jh7110 timer driver. Could you please
> help to review and give your comments?
> > Thanks a lot!
>
> Hi Ziv
>
> I tried this on 6.9-rc6 on my VF2. It boots, but very slowly and "choppy". That is
> it repeatedly runs for <1s and then hangs for about 4s.
>
> Does this patch work for you?
>
> /Emil

Hi, Emil

I tried this on 6.9-rc7 and 6.9-rc7, but it doesn't reproduce the phenomenon you said.
The attachment is the log for 6.9-rc6. Could you please share your config file (starfive_visionfive2_defconfig or .config) with me?

Best Regards
Ziv Xu

StarFive # setenv bootfile vmlinuz; setenv fdt_addr_r 0x48000000; setenv fdt_high 0xffffffffffffffff; setenv fdtcontroladdr 0xffffffffffffffff; setenv initrd_high 0xffffffffffffffff; setenv kernel_addr_r 0x44000000; setenv fileaddr a0000000;setenv kernel_comp_addr_r 0xb0000000; setenv kernel_comp_size 0x10000000;setenv ipaddr 192.168.125.96; setenv serverip 192.168.125.171;setenv ramdisk_addr_r 0x48100000;setenv kernel_comp_addr_r 0xb0000000;setenv kernel_comp_size 0x10000000;
StarFive # tftpboot ${fdt_addr_r} ziv/upstream/linux/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dtb; tftpboot ${kernel_addr_r} ziv/upstream/linux/arch/riscv/boot/Image.gz; tftpboot ${ramdisk_addr_r} ziv/visionfive/initramfs.cpio.gz;booti ${kernel_addr_r} ${ramdisk_addr_r}:${filesize} ${fdt_addr_r};
ethernet@16030000 Waiting for PHY auto negotiation to complete...... done
Using ethernet@16030000 device
TFTP from server 192.168.125.171; our IP address is 192.168.125.96
Filename 'ziv/upstream/linux/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-v1.3b.dtb'.
Load address: 0x48000000
Loading: ###
66.4 KiB/s
done
Bytes transferred = 36396 (8e2c hex)
Using ethernet@16030000 device
TFTP from server 192.168.125.171; our IP address is 192.168.125.96
Filename 'ziv/upstream/linux/arch/riscv/boot/Image.gz'.
Load address: 0x44000000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##########
5.9 MiB/s
done
Bytes transferred = 6819280 (680dd0 hex)
Using ethernet@16030000 device
TFTP from server 192.168.125.171; our IP address is 192.168.125.96
Filename 'ziv/visionfive/initramfs.cpio.gz'.
Load address: 0x48100000
Loading: #################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
#################################################################
##############################################
7.2 MiB/s
done
Bytes transferred = 114215585 (6cecaa1 hex)
Uncompressing Kernel Image
Moving Image from 0x44000000 to 0x40200000, end=41727000
## Flattened Device Tree blob at 48000000
Booting using the fdt blob at 0x48000000
Using Device Tree in place at 0000000048000000, end 000000004800be2b

Starting kernel ...

clk u2_dw_i2c_clk_core already disabled
clk u2_dw_i2c_clk_apb already disabled
clk u5_dw_i2c_clk_core already disabled
clk u5_dw_i2c_clk_apb already disabled
Linux version 6.9.0-rc6-00003-g9385b82135ff (ziv@SD-Server) (riscv64-linux-gnu-gcc (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0, GNU ld (GNU Binutils for Ubuntu) 2.30) #17 SMP Tue May 7 16:29:45 CST 2024
Machine model: StarFive VisionFive 2 v1.3B
SBI specification v1.0 detected
SBI implementation ID=0x1 Version=0x10002
SBI TIME extension detected
SBI IPI extension detected
SBI RFENCE extension detected
SBI SRST extension detected
efi: UEFI not found.
OF: reserved mem: 0x0000000040000000..0x000000004007ffff (512 KiB) nomap non-reusable opensbi@40000000
Zone ranges:
DMA32 [mem 0x0000000040000000-0x00000000ffffffff]
Normal [mem 0x0000000100000000-0x000000013fffffff]
Movable zone start for each node
Early memory node ranges
node 0: [mem 0x0000000040000000-0x000000004007ffff]
node 0: [mem 0x0000000040080000-0x000000013fffffff]
Initmem setup node 0 [mem 0x0000000040000000-0x000000013fffffff]
SBI HSM extension detected
CPU with hartid=0 is not available
riscv: base ISA extensions acdfim
riscv: ELF capabilities acdfim
percpu: Embedded 20 pages/cpu s42664 r8192 d31064 u81920
pcpu-alloc: s42664 r8192 d31064 u81920 alloc=20*4096
pcpu-alloc: [0] 0 [0] 1 [0] 2 [0] 3
Kernel command line: console=tty1 console=ttyS0,115200 debug rootwait earlycon=sbi
Dentry cache hash table entries: 524288 (order: 10, 4194304 bytes, linear)
Inode-cache hash table entries: 262144 (order: 9, 2097152 bytes, linear)
Built 1 zonelists, mobility grouping on. Total pages: 1034240
mem auto-init: stack:off, heap alloc:off, heap free:off
software IO TLB: area num 4.
software IO TLB: mapped [mem 0x00000000fbfff000-0x00000000fffff000] (64MB)
Memory: 3929352K/4194304K available (8442K kernel code, 4781K rwdata, 4096K rodata, 2199K init, 339K bss, 264952K reserved, 0K cma-reserved)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1
rcu: Hierarchical RCU implementation.
rcu: RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=4.
rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=4
NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
riscv-intc: 64 local interrupts mapped
riscv: providing IPIs using SBI IPI extension
rcu: srcu_init: Setting srcu_struct sizes based on contention.
clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1d854df40, max_idle_ns: 881590404240 ns
sched_clock: 64 bits at 4MHz, resolution 250ns, wraps every 2199023255500ns
Calibrating delay loop (skipped), value calculated using timer frequency.. 8.00 BogoMIPS (lpj=16000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
Mountpoint-cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
CPU node for /cpus/cpu@0 exist but the possible cpu range is :0-3
ASID allocator disabled (0 bits)
rcu: Hierarchical SRCU implementation.
rcu: Max phase no-delay instances is 1000.
EFI services will not be available.
smp: Bringing up secondary CPUs ...
smp: Brought up 1 node, 4 CPUs
devtmpfs: initialized
clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
futex hash table entries: 1024 (order: 4, 65536 bytes, linear)
pinctrl core: initialized pinctrl subsystem
NET: Registered PF_NETLINK/PF_ROUTE protocol family
DMA: preallocated 512 KiB GFP_KERNEL pool for atomic allocations
DMA: preallocated 512 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
thermal_sys: Registered thermal governor 'step_wise'
cpuidle: using governor menu
cpu3: Ratio of byte access time to unaligned word access is 0.01, unaligned accesses are slow
cpu1: Ratio of byte access time to unaligned word access is 0.01, unaligned accesses are slow
cpu2: Ratio of byte access time to unaligned word access is 0.01, unaligned accesses are slow
cpu0: Ratio of byte access time to unaligned word access is 0.01, unaligned accesses are slow
CCACHE: 8 banks, 16 ways, sets/bank=256, bytes/block=64
CCACHE: Index of the largest way enabled: 15
platform soc: Fixed dependency cycle(s) with /soc/interrupt-controller@c000000
platform soc: Fixed dependency cycle(s) with /soc/interrupt-controller@c000000
platform 19800000.csi: Fixed dependency cycle(s) with /soc/isp@19840000
platform 19800000.csi: Fixed dependency cycle(s) with /soc/isp@19840000
platform 19840000.isp: Fixed dependency cycle(s) with /soc/csi@19800000
raid6: skipped pq benchmark and selected int64x8
raid6: using intx1 recovery algorithm
SCSI subsystem initialized
usbcore: registered new interface driver usbfs
usbcore: registered new interface driver hub
usbcore: registered new device driver usb
mc: Linux media interface: v0.10
videodev: Linux video capture interface: v2.00
Advanced Linux Sound Architecture Driver Initialized.
vgaarb: loaded
clocksource: Switched to clocksource riscv_clocksource
NET: Registered PF_INET protocol family
IP idents hash table entries: 65536 (order: 7, 524288 bytes, linear)
tcp_listen_portaddr_hash hash table entries: 2048 (order: 3, 32768 bytes, linear)
Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
TCP established hash table entries: 32768 (order: 6, 262144 bytes, linear)
TCP bind hash table entries: 32768 (order: 8, 1048576 bytes, linear)
TCP: Hash tables configured (established 32768 bind 32768)
UDP hash table entries: 2048 (order: 4, 65536 bytes, linear)
UDP-Lite hash table entries: 2048 (order: 4, 65536 bytes, linear)
NET: Registered PF_UNIX/PF_LOCAL protocol family
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp-with-tls transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
PCI: CLS 0 bytes, default 64
Unpacking initramfs...
workingset: timestamp_bits=62 max_order=20 bucket_order=0
NFS: Registering the id_resolver key type
Key type id_resolver registered
Key type id_legacy registered
nfs4filelayout_init: NFSv4 File Layout Driver Registering...
nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering...
ntfs3: Max link count 4000
jffs2: version 2.2. (NAND) © 2001-2006 Red Hat, Inc.
xor: measuring software checksum speed
8regs : 2340 MB/sec
8regs_prefetch : 2336 MB/sec
32regs : 2340 MB/sec
32regs_prefetch : 2333 MB/sec
xor: using function: 32regs (2340 MB/sec)
Block layer SCSI generic (bsg) driver version 0.4 loaded (major 251)
io scheduler bfq registered
riscv-plic c000000.interrupt-controller: mapped 136 interrupts with 4 handlers for 9 contexts.
Serial: 8250/16550 driver, 6 ports, IRQ sharing disabled
random: crng init done
loop: module loaded
zram: Added device: zram0
Freeing initrd memory: 111536K
4 fixed-partitions partitions found on MTD device 13010000.spi.0
Creating 4 MTD partitions on "13010000.spi.0":
0x000000000000-0x000000080000 : "spl"
0x0000000f0000-0x000000100000 : "uboot-env"
0x000000100000-0x000000500000 : "uboot"
0x000000600000-0x000001000000 : "reserved-data"
starfive-dwmac 16030000.ethernet: IRQ sfty not found
starfive-dwmac 16030000.ethernet: User ID: 0x41, Synopsys ID: 0x52
starfive-dwmac 16030000.ethernet: DWMAC4/5
starfive-dwmac 16030000.ethernet: DMA HW capability register supported
starfive-dwmac 16030000.ethernet: RX Checksum Offload Engine supported
starfive-dwmac 16030000.ethernet: Wake-Up On Lan supported
starfive-dwmac 16030000.ethernet: TSO supported
starfive-dwmac 16030000.ethernet: Enable RX Mitigation via HW Watchdog Timer
starfive-dwmac 16030000.ethernet: Enabled L3L4 Flow TC (entries=1)
starfive-dwmac 16030000.ethernet: Enabled RFS Flow TC (entries=10)
starfive-dwmac 16030000.ethernet: TSO feature enabled
starfive-dwmac 16030000.ethernet: Using 40/40 bits DMA host/device width
starfive-dwmac 16040000.ethernet: IRQ sfty not found
starfive-dwmac 16040000.ethernet: User ID: 0x41, Synopsys ID: 0x52
starfive-dwmac 16040000.ethernet: DWMAC4/5
starfive-dwmac 16040000.ethernet: DMA HW capability register supported
starfive-dwmac 16040000.ethernet: RX Checksum Offload Engine supported
starfive-dwmac 16040000.ethernet: Wake-Up On Lan supported
starfive-dwmac 16040000.ethernet: TSO supported
starfive-dwmac 16040000.ethernet: Enable RX Mitigation via HW Watchdog Timer
starfive-dwmac 16040000.ethernet: Enabled L3L4 Flow TC (entries=1)
starfive-dwmac 16040000.ethernet: Enabled RFS Flow TC (entries=10)
starfive-dwmac 16040000.ethernet: TSO feature enabled
starfive-dwmac 16040000.ethernet: Using 40/40 bits DMA host/device width
usbcore: registered new interface driver uas
usbcore: registered new interface driver usb-storage
i2c_dev: i2c /dev entries driver
sdhci: Secure Digital Host Controller Interface driver
sdhci: Copyright(c) Pierre Ossman
Synopsys Designware Multimedia Card Interface Driver
sdhci-pltfm: SDHCI platform and OF driver helper
usbcore: registered new interface driver usbhid
usbhid: USB HID core driver
riscv-pmu-sbi: SBI PMU extension is available
riscv-pmu-sbi: 16 firmware and 4 hardware counters
riscv-pmu-sbi: Perf sampling/filtering is not supported as sscof extension is not available
NET: Registered PF_INET6 protocol family
Segment Routing with IPv6
In-situ OAM (IOAM) with IPv6
NET: Registered PF_PACKET protocol family
Key type dns_resolver registered
Timer migration: 1 hierarchy levels; 8 children per group; 1 crossnode level
Btrfs loaded, zoned=no, fsverity=no
CCACHE: DataError @ 0x00000000.08040270
CCACHE: DataFail @ 0x00000000.08040074
pl08xdmac 16008000.dma-controller: initialized 8 virtual memcpy channels
pl08xdmac 16008000.dma-controller: initialized 16 virtual slave channels
debugfs: Directory '16008000.dma-controller' with parent 'dmaengine' already present!
pl08xdmac 16008000.dma-controller: DMA: PL080 rev0 at 0x16008000 irq 30
gpio gpiochip0: Static allocation of GPIO base is deprecated, use dynamic allocation.
starfive-jh7110-sys-pinctrl 13040000.pinctrl: StarFive GPIO chip registered 64 GPIOs
gpio gpiochip1: Static allocation of GPIO base is deprecated, use dynamic allocation.
starfive-jh7110-aon-pinctrl 17020000.pinctrl: StarFive GPIO chip registered 4 GPIOs
dw_axi_dmac_platform 16050000.dma-controller: DesignWare AXI DMA Controller, 4 channels
printk: legacy console [ttyS0] disabled
10000000.serial: ttyS0 at MMIO 0x10000000 (irq = 33, base_baud = 1500000) is a 16550A
printk: legacy console [ttyS0] enabled
dwmmc_starfive 16020000.mmc: IDMAC supports 32-bit address mode.
designware-i2s 100e0000.i2s: probe with driver designware-i2s failed with error -110
dwmmc_starfive 16020000.mmc: Using internal DMA controller.
dwmmc_starfive 16020000.mmc: Version ID is 290a
dwmmc_starfive 16020000.mmc: DW MMC controller at irq 40,32 bit host data width,32 deep fifo
mmc_host mmc1: card is polling.
mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 400000Hz, actual 399193HZ div = 62)
designware-i2s 120c0000.i2s: probe with driver designware-i2s failed with error -110
ssp-pl022 10060000.spi: ARM PL022 driver, device ID: 0x00041022
ssp-pl022 10060000.spi: mapped registers from 0x0000000010060000 to 00000000c0024811
axp20x-i2c 5-0036: AXP20x variant AXP15060 found
axp20x-i2c 5-0036: AXP20X driver loaded
starfive-dphy-rx 19820000.phy: supply mipi_0p9 not found, using dummy regulator
cdns-csi2rx 19800000.csi: probe with driver cdns-csi2rx failed with error -22
cpufreq: cpufreq_online: CPU0: Running at unlisted initial frequency: 1000000 KHz, changing to: 1500000 KHz
clk: Disabling unused clocks
PM: genpd: Disabling unused power domains
ALSA device list:
#0: StarFive-PWMDAC-Sound-Card
dwmmc_starfive 16010000.mmc: IDMAC supports 32-bit address mode.
dwmmc_starfive 16010000.mmc: Using internal DMA controller.
dwmmc_starfive 16010000.mmc: Version ID is 290a
dwmmc_starfive 16010000.mmc: DW MMC controller at irq 62,32 bit host data width,32 deep fifo
mmc_host mmc0: card is non-removable.
mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 300000Hz, actual 298192HZ div = 83)
mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 200000Hz, actual 199596HZ div = 124)
mmc_host mmc1: Bus speed (slot 0) = 49500000Hz (slot req 100000Hz, actual 99798HZ div = 248)
mmc_host mmc0: Bus speed (slot 0) = 49500000Hz (slot req 400000Hz, actual 399193HZ div = 62)
Freeing unused kernel image (initmem) memory: 2196K
Checked W+X mappings: passed, no W+X pages found
rodata_test: all tests were successful
Run /init as init process
with arguments:
/init
with environment:
HOME=/
TERM=linux
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Populating /dev using udev: udevd[125]: starting version 3.2.10
udevd[126]: starting eudev-3.2.10
mmc_host mmc0: Bus speed (slot 0) = 49500000Hz (slot req 52000000Hz, actual 49500000HZ div = 0)
mmc_host mmc0: Bus speed (slot 0) = 49500000Hz (slot req 100000000Hz, actual 49500000HZ div = 0)
mmc0: new HS200 MMC card at address 0001
mmcblk0: mmc0:0001 DG4032 29.1 GiB
GPT:Primary header thinks Alt. header is not at the end of the disk.
GPT:8191999 != 61071359
GPT:Alternate GPT header not at the end of the disk.
GPT:8191999 != 61071359
GPT: Use GNU Parted to correct GPT errors.
mmcblk0: p1 p2 p3 p4
mmcblk0boot0: mmc0:0001 DG4032 4.00 MiB
mmcblk0boot1: mmc0:0001 DG4032 4.00 MiB
mmcblk0rpmb: mmc0:0001 DG4032 4.00 MiB, chardev (248:0)
done
Saving random seed: OK
Starting rngd: OK
Starting system message bus: dbus[171]: Unknown username "pulse" in message bus configuration file
done
Starting rpcbind: OK
Starting iptables: OK
Starting bluetoothd: OK
Starting network: OK
Starting Network Interface Plugging Daemon:starfive-dwmac 16030000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
starfive-dwmac 16030000.ethernet eth0: PHY [stmmac-0:00] driver [YT8531 Gigabit Ethernet] (irq=POLL)
dwmac4: Master AXI performs fixed burst length
starfive-dwmac 16030000.ethernet eth0: No Safety Features support found
starfive-dwmac 16030000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
eth0starfive-dwmac 16030000.ethernet eth0: configuring for phy/rgmii-id link mode
eth1.
Starting ofono ... done.
Starting ntpd: starfive-dwmac 16040000.ethernet eth1: Register MEM_TYPE_PAGE_POOL RxQ-0
starfive-dwmac 16040000.ethernet eth1: PHY [stmmac-1:00] driver [YT8531 Gigabit Ethernet] (irq=POLL)
starfive-dwmac 16040000.ethernet: Failed to reset the dma
starfive-dwmac 16040000.ethernet eth1: stmmac_hw_setup: DMA engine initialization failed
starfive-dwmac 16040000.ethernet eth1: __stmmac_open: Hw setup failed
starfive-dwmac 16040000.ethernet eth1: Register MEM_TYPE_PAGE_POOL RxQ-0
starfive-dwmac 16040000.ethernet eth1: PHY [stmmac-1:00] driver [YT8531 Gigabit Ethernet] (irq=POLL)
dwmac4: Master AXI performs fixed burst length
starfive-dwmac 16040000.ethernet eth1: No Safety Features support found
starfive-dwmac 16040000.ethernet eth1: IEEE 1588-2008 Advanced Timestamp supported
starfive-dwmac 16040000.ethernet eth1: configuring for phy/rgmii-id link mode
OK
Starting dropbear sshd: OK
Starting multipastarfive-dwmac 16030000.ethernet eth0: Link is Up - 1Gbps/Full - flow control rx/tx
thd: OK
Starting NFS statd: OK
Starting NFS services: OK
Starting NFS daemon: rpc.nfsd: Unable to access /proc/fs/nfsd errno 2 (No such file or directory).
Please try, as root, 'mount -t nfsd nfsd /proc/fs/nfsd' and then restart rpc.nfsd to correct the problem
FAIL
Starting NFS mountd: OK
Starting isp_ctrl_daemon.sh: OK
Starting DHCP server: FAIL
No PARTLABEL=hibernation!

Welcome to Buildroot
buildroot login:
Welcome to Buildroot
buildroot login: root
Password:
# cat /proc/interrupts
CPU0 CPU1 CPU2 CPU3
10: 1049 87 28 619 RISC-V INTC 5 Edge riscv-timer
12: 0 0 0 0 SiFive PLIC 73 Edge dw_axi_dmac_platform
13: 3 0 0 0 SiFive PLIC 111 Edge 17030000.power-controller
14: 90 0 0 0 SiFive PLIC 30 Edge 1600c000.rng
15: 6 0 0 0 SiFive PLIC 25 Edge 13010000.spi
16: 17 0 0 0 SiFive PLIC 7 Edge eth0
17: 0 0 0 0 SiFive PLIC 6 Edge eth0
18: 0 0 0 0 SiFive PLIC 5 Edge eth0
19: 0 0 0 0 SiFive PLIC 78 Edge eth1
20: 0 0 0 0 SiFive PLIC 77 Edge eth1
21: 0 0 0 0 SiFive PLIC 76 Edge eth1
22: 4664 0 0 0 SiFive PLIC 69 Edge jh7110-timer.ch0
23: 0 5602 0 0 SiFive PLIC 70 Edge jh7110-timer.ch1
24: 0 0 5717 0 SiFive PLIC 71 Edge jh7110-timer.ch2
25: 0 0 0 5385 SiFive PLIC 72 Edge jh7110-timer.ch3
26: 0 0 0 0 SiFive PLIC 1 Edge ccache_ecc
27: 1 0 0 0 SiFive PLIC 3 Edge ccache_ecc
28: 1 0 0 0 SiFive PLIC 4 Edge ccache_ecc
29: 0 0 0 0 SiFive PLIC 2 Edge ccache_ecc
30: 0 0 0 0 SiFive PLIC 29 Edge pl08xdmac
33: 164 0 0 0 SiFive PLIC 32 Edge ttyS0
35: 0 0 0 0 SiFive PLIC 108 Edge 10100000.usb
36: 0 0 0 0 SiFive PLIC 110 Edge 10100000.usb
37: 0 0 0 0 SiFive PLIC 92 Edge wr_irq
38: 0 0 0 0 SiFive PLIC 87 Edge isp_irq
39: 0 0 0 0 SiFive PLIC 90 Edge line_irq
40: 383 0 0 0 SiFive PLIC 75 Edge dw-mci
41: 0 0 0 0 SiFive PLIC 38 Edge pl022
42: 0 0 0 0 SiFive PLIC 35 Edge 10030000.i2c
43: 1 0 0 0 SiFive PLIC 37 Edge 10050000.i2c
44: 90 0 0 0 SiFive PLIC 50 Edge 12050000.i2c
45: 0 0 0 0 SiFive PLIC 0 Edge axp15060
61: 0 0 0 0 SiFive PLIC 51 Edge 12060000.i2c
62: 1009 0 0 0 SiFive PLIC 74 Edge dw-mci
IPI0: 49 59 73 82 Rescheduling interrupts
IPI1: 623 743 810 952 Function call interrupts
IPI2: 0 0 0 0 CPU stop interrupts
IPI3: 0 0 0 0 CPU stop (for crash dump) interrupts
IPI4: 39 61 40 27 IRQ work interrupts
IPI5: 0 0 0 0 Timer broadcast interrupts
#
\
 
 \ /
  Last update: 2024-05-27 18:17    [W:0.117 / U:0.268 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site