Module Name: src Committed By: jmcneill Date: Sun Jun 11 16:21:41 UTC 2017
Modified Files: src/sys/arch/arm/samsung: exynos_platform.c files.exynos mct.c src/sys/arch/evbarm/conf: EXYNOS Log Message: Simplify MCT; just enable it and then attach an ARMv7 generic timer. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/samsung/exynos_platform.c cvs rdiff -u -r1.22 -r1.23 src/sys/arch/arm/samsung/files.exynos cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/samsung/mct.c cvs rdiff -u -r1.16 -r1.17 src/sys/arch/evbarm/conf/EXYNOS Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/samsung/exynos_platform.c diff -u src/sys/arch/arm/samsung/exynos_platform.c:1.4 src/sys/arch/arm/samsung/exynos_platform.c:1.5 --- src/sys/arch/arm/samsung/exynos_platform.c:1.4 Sun Jun 11 01:15:11 2017 +++ src/sys/arch/arm/samsung/exynos_platform.c Sun Jun 11 16:21:41 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: exynos_platform.c,v 1.4 2017/06/11 01:15:11 jmcneill Exp $ */ +/* $NetBSD: exynos_platform.c,v 1.5 2017/06/11 16:21:41 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared D. McNeill <jmcne...@invisible.ca> @@ -33,7 +33,7 @@ #include "ukbd.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.4 2017/06/11 01:15:11 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: exynos_platform.c,v 1.5 2017/06/11 16:21:41 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -132,9 +132,7 @@ exynos_platform_reset(void) static void exynos_platform_delay(u_int us) { - extern void mct_delay(u_int); - - mct_delay(us); + gtmr_delay(us); } static u_int Index: src/sys/arch/arm/samsung/files.exynos diff -u src/sys/arch/arm/samsung/files.exynos:1.22 src/sys/arch/arm/samsung/files.exynos:1.23 --- src/sys/arch/arm/samsung/files.exynos:1.22 Sat Jun 10 15:13:18 2017 +++ src/sys/arch/arm/samsung/files.exynos Sun Jun 11 16:21:41 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.exynos,v 1.22 2017/06/10 15:13:18 jmcneill Exp $ +# $NetBSD: files.exynos,v 1.23 2017/06/11 16:21:41 jmcneill Exp $ # # Configuration info for Samsung Exynos SoC ARM Peripherals # @@ -61,12 +61,12 @@ attach sysmmu at fdt with exynos_sysmmu file arch/arm/samsung/exynos_sysmmu.c exynos_sysmmu # real time clock -device exyortc : ftdbus +device exyortc : fdtbus attach exyortc at fdt with exynos_rtc file arch/arm/samsung/exynos_rtc.c exynos_rtc # Multi Core timer -device mct : ftdbus +device mct { } : fdtbus, mpcorebus attach mct at fdt with exyo_mct file arch/arm/samsung/mct.c exyo_mct Index: src/sys/arch/arm/samsung/mct.c diff -u src/sys/arch/arm/samsung/mct.c:1.11 src/sys/arch/arm/samsung/mct.c:1.12 --- src/sys/arch/arm/samsung/mct.c:1.11 Sun Jun 11 01:09:44 2017 +++ src/sys/arch/arm/samsung/mct.c Sun Jun 11 16:21:41 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: mct.c,v 1.11 2017/06/11 01:09:44 jmcneill Exp $ */ +/* $NetBSD: mct.c,v 1.12 2017/06/11 16:21:41 jmcneill Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.11 2017/06/11 01:09:44 jmcneill Exp $"); +__KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.12 2017/06/11 16:21:41 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -50,35 +50,24 @@ __KERNEL_RCSID(1, "$NetBSD: mct.c,v 1.11 #include <arm/samsung/mct_reg.h> #include <arm/samsung/mct_var.h> +#include <arm/cortex/gtmr_intr.h> +#include <arm/cortex/mpcore_var.h> +#include <arm/cortex/gtmr_var.h> + #include <dev/fdt/fdtvar.h> +#include <arm/fdt/arm_fdtvar.h> static int mct_match(device_t, cfdata_t, void *); static void mct_attach(device_t, device_t, void *); -static int clockhandler(void *); -static u_int mct_get_timecount(struct timecounter *); - CFATTACH_DECL_NEW(exyo_mct, 0, mct_match, mct_attach, NULL, NULL); - -static struct timecounter mct_timecounter = { - .tc_get_timecount = mct_get_timecount, - .tc_poll_pps = 0, - .tc_counter_mask = ~0u, - .tc_frequency = 0, /* set by cpu_initclocks() */ - .tc_name = NULL, /* set by cpu_initclocks() */ - .tc_quality = 500, /* why 500? */ - .tc_priv = &mct_sc, - .tc_next = NULL, -}; - static inline uint32_t mct_read_global(struct mct_softc *sc, bus_size_t o) { return bus_space_read_4(sc->sc_bst, sc->sc_bsh, o); } - static inline void mct_write_global(struct mct_softc *sc, bus_size_t o, uint32_t v) { @@ -128,6 +117,12 @@ mct_write_global(struct mct_softc *sc, b panic("MCT hangs after writing %#x at %#x", v, (uint32_t) o); } +static void +mct_fdt_cpu_hatch(void *priv, struct cpu_info *ci) +{ + gtmr_init_cpu_clock(ci); +} + static int mct_match(device_t parent, cfdata_t cf, void *aux) { @@ -138,7 +133,6 @@ mct_match(device_t parent, cfdata_t cf, return of_match_compatible(faa->faa_phandle, compatible); } - static void mct_attach(device_t parent, device_t self, void *aux) { @@ -168,145 +162,18 @@ mct_attach(device_t parent, device_t sel aprint_naive("\n"); aprint_normal(": Exynos SoC multi core timer (64 bits)\n"); - evcnt_attach_dynamic(&sc->sc_ev_missing_ticks, EVCNT_TYPE_MISC, NULL, - device_xname(self), "missing interrupts"); - - for (int i = 0; i < 12; i++) - fdtbus_intr_establish(faa->faa_phandle, i, 0, 0, - clockhandler, 0); -} - -static inline uint64_t -mct_gettime(struct mct_softc *sc) -{ - uint32_t lo, hi; - do { - hi = mct_read_global(sc, MCT_G_CNT_U); - lo = mct_read_global(sc, MCT_G_CNT_L); - } while (hi != mct_read_global(sc, MCT_G_CNT_U)); - return ((uint64_t) hi << 32) | lo; -} - -static u_int -mct_get_timecount(struct timecounter *tc) -{ - struct mct_softc *sc = tc->tc_priv; - - return (u_int)mct_gettime(sc); -} - -void -mct_delay(u_int us) -{ - struct mct_softc *sc = &mct_sc; - - if (sc->sc_bsh == (bus_space_handle_t)0) - return; - - int64_t mct_ticks = ((uint64_t)us * sc->sc_freq) / 1000000; - uint64_t ticks_prev = mct_gettime(sc); - while (mct_ticks > 0) { - uint64_t ticks_cur = mct_gettime(sc); - mct_ticks -= (ticks_cur - ticks_prev); - ticks_prev = ticks_cur; - } -} - -/* interrupt handler */ -static int -clockhandler(void *arg) -{ - struct clockframe * const cf = arg; - struct mct_softc * const sc = &mct_sc; - const uint64_t now = mct_gettime(sc); - int64_t delta = now - sc->sc_lastintr; - int64_t periods = delta / sc->sc_autoinc; - - KASSERT(delta >= 0); - KASSERT(periods >= 0); - - /* ack the interrupt */ - mct_write_global(sc, MCT_G_INT_CSTAT, G_INT_CSTAT_CLEAR); - - /* check if we missed clock interrupts */ - if (periods > 1) - sc->sc_ev_missing_ticks.ev_count += periods - 1; - - sc->sc_lastintr = now; - hardclock(cf); - - /* handled */ - return 1; -} - -void -mct_init_cpu_clock(struct cpu_info *ci) -{ - struct mct_softc * const sc = &mct_sc; - uint64_t now = mct_gettime(sc); - uint64_t then; - uint32_t tcon; - - KASSERT(ci == curcpu()); - - sc->sc_lastintr = now; - - /* get current config */ - tcon = mct_read_global(sc, MCT_G_TCON); - - /* setup auto increment */ - mct_write_global(sc, MCT_G_COMP0_ADD_INCR, sc->sc_autoinc); - - /* (re)setup comparator */ - then = now + sc->sc_autoinc; - mct_write_global(sc, MCT_G_COMP0_L, (uint32_t) then); - mct_write_global(sc, MCT_G_COMP0_U, (uint32_t) (then >> 32)); - tcon |= G_TCON_COMP0_AUTOINC; - tcon |= G_TCON_COMP0_ENABLE; - - /* start timer */ + /* Start the timer */ + uint32_t tcon = mct_read_global(sc, MCT_G_TCON); tcon |= G_TCON_START; - - /* enable interrupt */ - mct_write_global(sc, MCT_G_INT_ENB, G_INT_ENB_ENABLE); - - /* update config, starting the thing */ mct_write_global(sc, MCT_G_TCON, tcon); -} - -void -cpu_initclocks(void) -{ - struct mct_softc * const sc = &mct_sc; - - sc->sc_autoinc = sc->sc_freq / hz; - mct_init_cpu_clock(curcpu()); - mct_timecounter.tc_name = device_xname(sc->sc_dev); - mct_timecounter.tc_frequency = sc->sc_freq; + /* Attach ARMv7 generic timer */ + struct mpcore_attach_args mpcaa = { + .mpcaa_name = "armgtmr", + .mpcaa_irq = IRQ_GTMR_PPI_VTIMER + }; - tc_init(&mct_timecounter); + config_found(self, &mpcaa, NULL); -#if 0 - { - uint64_t then, now; - - printf("testing timer\n"); - for (int i = 0; i < 200; i++) { - printf("cstat %d\n", mct_read_global(sc, MCT_G_INT_CSTAT)); - then = mct_get_timecount(&mct_timecounter); - do { - now = mct_get_timecount(&mct_timecounter); - } while (now == then); - printf("\tgot %"PRIu64"\n", now); - for (int j = 0; j < 90000; j++); - } - printf("passed\n"); - } -#endif -} - -void -setstatclockrate(int newhz) -{ + arm_fdt_cpu_hatch_register(self, mct_fdt_cpu_hatch); } Index: src/sys/arch/evbarm/conf/EXYNOS diff -u src/sys/arch/evbarm/conf/EXYNOS:1.16 src/sys/arch/evbarm/conf/EXYNOS:1.17 --- src/sys/arch/evbarm/conf/EXYNOS:1.16 Sun Jun 11 11:04:20 2017 +++ src/sys/arch/evbarm/conf/EXYNOS Sun Jun 11 16:21:41 2017 @@ -1,5 +1,5 @@ # -# $NetBSD: EXYNOS,v 1.16 2017/06/11 11:04:20 jmcneill Exp $ +# $NetBSD: EXYNOS,v 1.17 2017/06/11 16:21:41 jmcneill Exp $ # # Samsung Exynos SoC kernel # @@ -42,6 +42,7 @@ gpiokeys* at fdt? # Timer mct* at fdt? # Exynos Multi Core Timer (MCT) +armgtmr0 at mct? # ARM Generic Timer # Interrupt controller exyointr* at fdt? pass 1