Module Name: src Committed By: jmcneill Date: Sun Apr 21 13:51:04 UTC 2019
Modified Files: src/sys/arch/arm/amlogic: files.meson src/sys/arch/evbarm/conf: GENERIC64 Added Files: src/sys/arch/arm/amlogic: mesongx_wdt.c Log Message: Add driver for Meson GX EE-domain watchdog timer. To generate a diff of this commit: cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/amlogic/files.meson cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/amlogic/mesongx_wdt.c cvs rdiff -u -r1.88 -r1.89 src/sys/arch/evbarm/conf/GENERIC64 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/amlogic/files.meson diff -u src/sys/arch/arm/amlogic/files.meson:1.8 src/sys/arch/arm/amlogic/files.meson:1.9 --- src/sys/arch/arm/amlogic/files.meson:1.8 Sun Apr 21 11:02:32 2019 +++ src/sys/arch/arm/amlogic/files.meson Sun Apr 21 13:51:04 2019 @@ -1,4 +1,4 @@ -# $NetBSD: files.meson,v 1.8 2019/04/21 11:02:32 jmcneill Exp $ +# $NetBSD: files.meson,v 1.9 2019/04/21 13:51:04 jmcneill Exp $ # # Configuration info for Amlogic Meson family SoCs # @@ -104,11 +104,16 @@ device gxlphy: mii_phy attach gxlphy at mii file arch/arm/amlogic/gxlphy.c gxlphy -# Watchdog +# Meson8b Watchdog device mesonwdt: sysmon_wdog attach mesonwdt at fdt with meson_wdt file arch/arm/amlogic/meson_wdt.c meson_wdt +# Meson GX Watchdog +device mesongxwdt: sysmon_wdog +attach mesongxwdt at fdt with mesongx_wdt +file arch/arm/amlogic/mesongx_wdt.c mesongx_wdt + # SOC parameters defflag opt_soc.h SOC_MESON defflag opt_soc.h SOC_MESON8B: SOC_MESON Index: src/sys/arch/evbarm/conf/GENERIC64 diff -u src/sys/arch/evbarm/conf/GENERIC64:1.88 src/sys/arch/evbarm/conf/GENERIC64:1.89 --- src/sys/arch/evbarm/conf/GENERIC64:1.88 Sun Apr 21 11:02:33 2019 +++ src/sys/arch/evbarm/conf/GENERIC64 Sun Apr 21 13:51:04 2019 @@ -1,5 +1,5 @@ # -# $NetBSD: GENERIC64,v 1.88 2019/04/21 11:02:33 jmcneill Exp $ +# $NetBSD: GENERIC64,v 1.89 2019/04/21 13:51:04 jmcneill Exp $ # # GENERIC ARM (aarch64) kernel # @@ -179,6 +179,7 @@ armgtmr0 at gtmr? tegratimer* at fdt? # Timers # Watchdog +mesongxwdt* at fdt? # Amlogic Meson GX watchdog sbsawdt* at acpi? # ARM SBSA-compliant watchdog sunxiwdt* at fdt? # Allwinner watchdog watchdog* at fdt? # Broadcom BCM283x watchdog Added files: Index: src/sys/arch/arm/amlogic/mesongx_wdt.c diff -u /dev/null src/sys/arch/arm/amlogic/mesongx_wdt.c:1.1 --- /dev/null Sun Apr 21 13:51:05 2019 +++ src/sys/arch/arm/amlogic/mesongx_wdt.c Sun Apr 21 13:51:04 2019 @@ -0,0 +1,172 @@ +/* $NetBSD: mesongx_wdt.c,v 1.1 2019/04/21 13:51:04 jmcneill Exp $ */ + +/*- + * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: mesongx_wdt.c,v 1.1 2019/04/21 13:51:04 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/cpu.h> +#include <sys/device.h> +#include <sys/wdog.h> + +#include <dev/sysmon/sysmonvar.h> + +#include <dev/fdt/fdtvar.h> + +#define CBUS_REG(x) ((x) << 2) + +#define WATCHDOG_CNTL CBUS_REG(0) +#define CNTL_CLK_DIV_EN __BIT(25) +#define CNTL_CLK_EN __BIT(24) +#define CNTL_SYS_RESET_N_EN __BIT(21) +#define CNTL_WATCHDOG_EN __BIT(18) +#define CNTL_CLK_DIV_TCNT __BITS(17,0) +#define WATCHDOG_CNTL1 CBUS_REG(1) +#define WATCHDOG_TCNT CBUS_REG(2) +#define WATCHDOG_RESET CBUS_REG(3) + +#define WATCHDOG_PERIOD_DEFAULT 8 +#define WATCHDOG_PERIOD_MAX 8 + +static const char * compatible[] = { + "amlogic,meson-gx-wdt", + NULL +}; + +struct mesongx_wdt_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + + struct sysmon_wdog sc_wdog; + u_int sc_rate; +}; + +#define WDT_READ(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) +#define WDT_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) + +static int +mesongx_wdt_setmode(struct sysmon_wdog *smw) +{ + struct mesongx_wdt_softc * const sc = smw->smw_cookie; + + if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) { + WDT_WRITE(sc, WATCHDOG_CNTL, 0); + return 0; + } + + if (smw->smw_period == WDOG_PERIOD_DEFAULT) { + sc->sc_wdog.smw_period = WATCHDOG_PERIOD_DEFAULT; + } else if (smw->smw_period == 0 || + smw->smw_period > WATCHDOG_PERIOD_MAX) { + return EINVAL; + } else { + sc->sc_wdog.smw_period = smw->smw_period; + } + + const u_int tcnt = sc->sc_rate / 1000; + + WDT_WRITE(sc, WATCHDOG_CNTL, 0); + WDT_WRITE(sc, WATCHDOG_RESET, 0); + WDT_WRITE(sc, WATCHDOG_TCNT, sc->sc_wdog.smw_period * 1000); + WDT_WRITE(sc, WATCHDOG_CNTL, + __SHIFTIN(tcnt, CNTL_CLK_DIV_TCNT) | + CNTL_CLK_DIV_EN | CNTL_CLK_EN | + CNTL_SYS_RESET_N_EN | CNTL_WATCHDOG_EN); + + return 0; +} + +static int +mesongx_wdt_tickle(struct sysmon_wdog *smw) +{ + struct mesongx_wdt_softc * const sc = smw->smw_cookie; + + WDT_WRITE(sc, WATCHDOG_RESET, 0); + + return 0; +} + +static int +mesongx_wdt_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +mesongx_wdt_attach(device_t parent, device_t self, void *aux) +{ + struct mesongx_wdt_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + struct clk *clk; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_bst = faa->faa_bst; + if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + + aprint_naive("\n"); + aprint_normal(": EE-watchdog\n"); + + clk = fdtbus_clock_get_index(phandle, 0); + if (clk != NULL) + sc->sc_rate = clk_get_rate(clk); + else { + aprint_error_dev(self, "WARNING: couldn't get xtal clock, assuming 24 MHz\n"); + sc->sc_rate = 24000000; + } + + /* Disable watchdog */ + WDT_WRITE(sc, WATCHDOG_CNTL, 0); + + /* Register watchdog */ + sc->sc_wdog.smw_name = "EE-watchdog"; + sc->sc_wdog.smw_setmode = mesongx_wdt_setmode; + sc->sc_wdog.smw_tickle = mesongx_wdt_tickle; + sc->sc_wdog.smw_period = WATCHDOG_PERIOD_DEFAULT; + sc->sc_wdog.smw_cookie = sc; + sysmon_wdog_register(&sc->sc_wdog); +} + +CFATTACH_DECL_NEW(mesongx_wdt, sizeof(struct mesongx_wdt_softc), + mesongx_wdt_match, mesongx_wdt_attach, NULL, NULL);