git: 9257fe124f0e - main - riscv: aw_timer enablement for D1
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 27 Jan 2025 20:07:00 UTC
The branch main has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=9257fe124f0e640ca5cab77754117bd2e55f28d5 commit 9257fe124f0e640ca5cab77754117bd2e55f28d5 Author: Mitchell Horne <mhorne@FreeBSD.org> AuthorDate: 2025-01-27 20:00:21 +0000 Commit: Mitchell Horne <mhorne@FreeBSD.org> CommitDate: 2025-01-27 20:04:14 +0000 riscv: aw_timer enablement for D1 The SBI timer functionality is partially broken on the Allwinner D1, so we require this driver to provide an eventtimer/system timer interrupts. The timecounter interface, on the other hand, is not required. The generic RISC-V timer driver uses the native rdtime instruction, and implements vdso, so this should be preferred. Reviewed by: manu, ganbold MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D48672 --- sys/arm/allwinner/aw_timer.c | 39 +++++++++++++++++++++++++++---------- sys/riscv/allwinner/files.allwinner | 1 + sys/riscv/conf/std.allwinner | 1 + 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/sys/arm/allwinner/aw_timer.c b/sys/arm/allwinner/aw_timer.c index a7317e299871..ae609f96f1d3 100644 --- a/sys/arm/allwinner/aw_timer.c +++ b/sys/arm/allwinner/aw_timer.c @@ -45,7 +45,7 @@ #include <dev/clk/clk.h> -#if defined(__aarch64__) +#if defined(__aarch64__) || defined(__riscv) #include "opt_soc.h" #else #include <arm/allwinner/aw_machdep.h> @@ -88,6 +88,7 @@ enum aw_timer_type { A10_TIMER = 1, A23_TIMER, + D1_TIMER, }; struct aw_timer_softc { @@ -109,7 +110,10 @@ struct aw_timer_softc { static u_int a10_timer_get_timecount(struct timecounter *); static uint64_t a10_timer_read_counter64(struct aw_timer_softc *sc); static void a10_timer_timecounter_setup(struct aw_timer_softc *sc); +#endif +#if defined(__arm__) || defined(__riscv) +#define USE_EVENTTIMER static void aw_timer_eventtimer_setup(struct aw_timer_softc *sc); static int aw_timer_eventtimer_start(struct eventtimer *, sbintime_t first, sbintime_t period); @@ -126,6 +130,8 @@ static int aw_timer_probe(device_t); static int aw_timer_attach(device_t); #if defined(__arm__) +#define AW_TIMER_QUALITY 1000 + static delay_func a10_timer_delay; static struct timecounter a10_timer_timecounter = { @@ -133,21 +139,28 @@ static struct timecounter a10_timer_timecounter = { .tc_get_timecount = a10_timer_get_timecount, .tc_counter_mask = ~0u, .tc_frequency = 0, - .tc_quality = 1000, + .tc_quality = AW_TIMER_QUALITY, }; #endif #if defined(__aarch64__) +/* We want it to be selected over the arm generic timecounter */ +#define AW_TIMER_QUALITY 2000 + static struct timecounter a23_timer_timecounter = { .tc_name = "aw_timer timer0", .tc_get_timecount = a23_timer_get_timecount, .tc_counter_mask = ~0u, .tc_frequency = 0, - /* We want it to be selected over the arm generic timecounter */ - .tc_quality = 2000, + .tc_quality = AW_TIMER_QUALITY, }; #endif +#if defined(__riscv) +/* We want it to be selected over the generic RISC-V eventtimer */ +#define AW_TIMER_QUALITY 2000 +#endif + #define AW_TIMER_MEMRES 0 #define AW_TIMER_IRQRES 1 @@ -161,6 +174,8 @@ static struct ofw_compat_data compat_data[] = { {"allwinner,sun4i-a10-timer", A10_TIMER}, #if defined(__aarch64__) {"allwinner,sun8i-a23-timer", A23_TIMER}, +#elif defined(__riscv) + {"allwinner,sun20i-d1-timer", D1_TIMER}, #endif {NULL, 0}, }; @@ -224,8 +239,13 @@ aw_timer_attach(device_t dev) stathz); } -#if defined(__arm__) + /* Set up eventtimer (if applicable) */ +#if defined(USE_EVENTTIMER) aw_timer_eventtimer_setup(sc); +#endif + + /* Set up timercounter (if applicable) */ +#if defined(__arm__) a10_timer_timecounter_setup(sc); #elif defined(__aarch64__) a23_timer_timecounter_setup(sc); @@ -269,10 +289,9 @@ aw_timer_irq(void *arg) } /* - * Event timer function for A10 and A13 + * Event timer function for A10, A13, and D1. */ - -#if defined(__arm__) +#if defined(USE_EVENTTIMER) static void aw_timer_eventtimer_setup(struct aw_timer_softc *sc) { @@ -293,7 +312,7 @@ aw_timer_eventtimer_setup(struct aw_timer_softc *sc) sc->et.et_frequency = sc->timer0_freq; sc->et.et_name = "aw_timer Eventtimer"; sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC; - sc->et.et_quality = 1000; + sc->et.et_quality = AW_TIMER_QUALITY; sc->et.et_min_period = (0x00000005LLU << 32) / sc->et.et_frequency; sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency; sc->et.et_start = aw_timer_eventtimer_start; @@ -362,7 +381,7 @@ aw_timer_eventtimer_stop(struct eventtimer *et) return (0); } -#endif /* __arm__ */ +#endif /* USE_EVENTTIMER */ /* * Timecounter functions for A23 and above diff --git a/sys/riscv/allwinner/files.allwinner b/sys/riscv/allwinner/files.allwinner index a87d79dfda2a..73fa9660e2d2 100644 --- a/sys/riscv/allwinner/files.allwinner +++ b/sys/riscv/allwinner/files.allwinner @@ -3,6 +3,7 @@ arm/allwinner/aw_gpio.c optional gpio aw_gpio fdt arm/allwinner/aw_rtc.c optional aw_rtc fdt arm/allwinner/aw_syscon.c optional syscon arm/allwinner/aw_sid.c optional aw_sid nvmem +arm/allwinner/aw_timer.c optional aw_timer fdt arm/allwinner/aw_usbphy.c optional ehci aw_usbphy fdt arm/allwinner/aw_wdog.c optional aw_wdog arm/allwinner/if_awg.c optional awg syscon diff --git a/sys/riscv/conf/std.allwinner b/sys/riscv/conf/std.allwinner index 5e7a6c0e0a52..2b1e0d4e09dc 100644 --- a/sys/riscv/conf/std.allwinner +++ b/sys/riscv/conf/std.allwinner @@ -9,6 +9,7 @@ device aw_ccu # Allwinner clock controller device aw_gpio # Allwinner GPIO controller device aw_rtc # Allwinner Real-time Clock device aw_sid # Allwinner Secure ID EFUSE +device aw_timer # Allwinner Timer device aw_usbphy # Allwinner USB PHY device aw_wdog # Allwinner Watchdog device awg # Allwinner EMAC Gigabit Ethernet