Module Name: src Committed By: jmcneill Date: Sun Sep 7 17:49:39 UTC 2014
Modified Files: src/sys/arch/arm/allwinner: awin_io.c awin_reg.h files.awin Added Files: src/sys/arch/arm/allwinner: awin_rtc.c Log Message: a10/a20 rtc driver To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/allwinner/awin_io.c \ src/sys/arch/arm/allwinner/files.awin cvs rdiff -u -r1.19 -r1.20 src/sys/arch/arm/allwinner/awin_reg.h cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/allwinner/awin_rtc.c 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/allwinner/awin_io.c diff -u src/sys/arch/arm/allwinner/awin_io.c:1.10 src/sys/arch/arm/allwinner/awin_io.c:1.11 --- src/sys/arch/arm/allwinner/awin_io.c:1.10 Sat Sep 6 00:15:34 2014 +++ src/sys/arch/arm/allwinner/awin_io.c Sun Sep 7 17:49:39 2014 @@ -31,7 +31,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.10 2014/09/06 00:15:34 jmcneill Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.11 2014/09/07 17:49:39 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -104,6 +104,7 @@ static const struct awin_locators awin_l { "com", OFFANDSIZE(UART6), 6, AWIN_IRQ_UART6, AANY }, { "com", OFFANDSIZE(UART7), 7, AWIN_IRQ_UART7, AANY }, { "awinwdt", OFFANDSIZE(TMR), NOPORT, NOINTR, AANY }, + { "awinrtc", OFFANDSIZE(TMR), NOPORT, NOINTR, AANY }, { "awinusb", OFFANDSIZE(USB1), 0, NOINTR, AANY }, { "awinusb", OFFANDSIZE(USB2), 1, NOINTR, AANY }, { "awinmmc", OFFANDSIZE(SDMMC0), 0, AWIN_IRQ_SDMMC0, AANY }, Index: src/sys/arch/arm/allwinner/files.awin diff -u src/sys/arch/arm/allwinner/files.awin:1.10 src/sys/arch/arm/allwinner/files.awin:1.11 --- src/sys/arch/arm/allwinner/files.awin:1.10 Sat Sep 6 00:15:34 2014 +++ src/sys/arch/arm/allwinner/files.awin Sun Sep 7 17:49:39 2014 @@ -1,4 +1,4 @@ -# $NetBSD: files.awin,v 1.10 2014/09/06 00:15:34 jmcneill Exp $ +# $NetBSD: files.awin,v 1.11 2014/09/07 17:49:39 jmcneill Exp $ # # Configuration info for Allwinner ARM Peripherals # @@ -42,6 +42,11 @@ device awinwdt : sysmon_wdog attach awinwdt at awinio with awin_wdt file arch/arm/allwinner/awin_wdt.c awin_wdt | awin_io needs-flag +# A10/A20 RTC +device awinrtc +attach awinrtc at awinio with awin_rtc +file arch/arm/allwinner/awin_rtc.c awin_rtc + # A10 Timers device awintmr attach awintmr at awinio with awin_tmr Index: src/sys/arch/arm/allwinner/awin_reg.h diff -u src/sys/arch/arm/allwinner/awin_reg.h:1.19 src/sys/arch/arm/allwinner/awin_reg.h:1.20 --- src/sys/arch/arm/allwinner/awin_reg.h:1.19 Sun Sep 7 15:38:06 2014 +++ src/sys/arch/arm/allwinner/awin_reg.h Sun Sep 7 17:49:39 2014 @@ -1326,6 +1326,29 @@ #define AWIN_WDOG_MODE_RST_EN __BIT(1) #define AWIN_WDOG_MODE_EN __BIT(0) +#define AWIN_LOSC_CTRL_KEY_FIELD __BITS(31,16) +#define AWIN_LOSC_CTRL_CLK32K_AUTO_SWT_PEND __BIT(15) +#define AWIN_LOSC_CTRL_CLK32K_AUTO_SWT_EN __BIT(14) +#define AWIN_LOSC_CTRL_ALM_DDHHMMSS_ACCE __BIT(9) +#define AWIN_LOSC_CTRL_RTC_HHMMSS_ACCE __BIT(8) +#define AWIN_LOSC_CTRL_RTC_YYMMDD_ACCE __BIT(7) +#define AWIN_LOSC_CTRL_EXT_LOSC_GSM __BITS(3,2) +#define AWIN_LOSC_CTRL_OSC32K_SRC_SEL __BIT(0) +#define AWIN_LOSC_CTRL_BUSY \ + (AWIN_LOSC_CTRL_ALM_DDHHMMSS_ACCE | \ + AWIN_LOSC_CTRL_RTC_HHMMSS_ACCE | \ + AWIN_LOSC_CTRL_RTC_YYMMDD_ACCE) + +#define AWIN_RTC_YY_MM_DD_RTC_SIM_CTRL __BIT(30) +#define AWIN_RTC_YY_MM_DD_LEAP __BIT(24) +#define AWIN_RTC_YY_MM_DD_YEAR __BITS(23,16) +#define AWIN_RTC_YY_MM_DD_MONTH __BITS(11,8) +#define AWIN_RTC_YY_MM_DD_DAY __BITS(4,0) +#define AWIN_RTC_HH_MM_SS_WK_NO __BITS(31,29) +#define AWIN_RTC_HH_MM_SS_HOUR __BITS(20,16) +#define AWIN_RTC_HH_MM_SS_MINUTE __BITS(13,8) +#define AWIN_RTC_HH_MM_SS_SECOND __BITS(5,0) + #define AWIN_TWI_ADDR_REG 0x0000 #define AWIN_TWI_XADDR_REG 0x0004 #define AWIN_TWI_DATA_REG 0x0008 Added files: Index: src/sys/arch/arm/allwinner/awin_rtc.c diff -u /dev/null src/sys/arch/arm/allwinner/awin_rtc.c:1.1 --- /dev/null Sun Sep 7 17:49:39 2014 +++ src/sys/arch/arm/allwinner/awin_rtc.c Sun Sep 7 17:49:39 2014 @@ -0,0 +1,143 @@ +/* $NetBSD: awin_rtc.c,v 1.1 2014/09/07 17:49:39 jmcneill Exp $ */ + +/*- + * Copyright (c) 2014 Jared D. 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: awin_rtc.c,v 1.1 2014/09/07 17:49:39 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/mutex.h> + +#include <arm/allwinner/awin_reg.h> +#include <arm/allwinner/awin_var.h> + +#include <dev/clock_subr.h> + +struct awin_rtc_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + struct todr_chip_handle sc_todr; +}; + +static int awin_rtc_match(device_t, cfdata_t, void *); +static void awin_rtc_attach(device_t, device_t, void *); + +static int awin_rtc_gettime(todr_chip_handle_t, struct clock_ymdhms *); +static int awin_rtc_settime(todr_chip_handle_t, struct clock_ymdhms *); + +CFATTACH_DECL_NEW(awin_rtc, sizeof(struct awin_rtc_softc), + awin_rtc_match, awin_rtc_attach, NULL, NULL); + +static int +awin_rtc_match(device_t parent, cfdata_t cf, void *aux) +{ + struct awinio_attach_args * const aio = aux; + const struct awin_locators * const loc = &aio->aio_loc; + + if (strcmp(cf->cf_name, loc->loc_name)) + return 0; + + return 1; +} + +static void +awin_rtc_attach(device_t parent, device_t self, void *aux) +{ + struct awin_rtc_softc *sc = device_private(self); + struct awinio_attach_args * const aio = aux; + const struct awin_locators * const loc = &aio->aio_loc; + + sc->sc_dev = self; + sc->sc_bst = aio->aio_core_bst; + bus_space_subregion(sc->sc_bst, aio->aio_core_bsh, + loc->loc_offset, loc->loc_size, &sc->sc_bsh); + + aprint_naive("\n"); + aprint_normal(": RTC\n"); + + sc->sc_todr.todr_gettime_ymdhms = awin_rtc_gettime; + sc->sc_todr.todr_settime_ymdhms = awin_rtc_settime; + sc->sc_todr.cookie = sc; + todr_attach(&sc->sc_todr); +} + +static int +awin_rtc_gettime(todr_chip_handle_t tch, struct clock_ymdhms *dt) +{ + struct awin_rtc_softc *sc = tch->cookie; + uint32_t yymmdd, hhmmss; + + yymmdd = bus_space_read_4(sc->sc_bst, sc->sc_bsh, + AWIN_RTC_YY_MM_DD_REG); + hhmmss = bus_space_read_4(sc->sc_bst, sc->sc_bsh, + AWIN_RTC_HH_MM_SS_REG); + + dt->dt_year = __SHIFTOUT(yymmdd, AWIN_RTC_YY_MM_DD_YEAR) + + POSIX_BASE_YEAR; + dt->dt_mon = __SHIFTOUT(yymmdd, AWIN_RTC_YY_MM_DD_MONTH); + dt->dt_day = __SHIFTOUT(yymmdd, AWIN_RTC_YY_MM_DD_DAY); + dt->dt_wday = __SHIFTOUT(hhmmss, AWIN_RTC_HH_MM_SS_WK_NO); + dt->dt_hour = __SHIFTOUT(hhmmss, AWIN_RTC_HH_MM_SS_HOUR); + dt->dt_min = __SHIFTOUT(hhmmss, AWIN_RTC_HH_MM_SS_MINUTE); + dt->dt_sec = __SHIFTOUT(hhmmss, AWIN_RTC_HH_MM_SS_SECOND); + + return 0; +} + +static int +awin_rtc_settime(todr_chip_handle_t tch, struct clock_ymdhms *dt) +{ + struct awin_rtc_softc *sc = tch->cookie; + uint32_t yymmdd, hhmmss, losc; + + losc = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_LOSC_CTRL_REG); + if (losc & AWIN_LOSC_CTRL_BUSY) + return EBUSY; + + yymmdd = 0; + yymmdd |= __SHIFTIN(dt->dt_year - POSIX_BASE_YEAR, + AWIN_RTC_YY_MM_DD_YEAR); + yymmdd |= __SHIFTIN(dt->dt_mon, AWIN_RTC_YY_MM_DD_MONTH); + yymmdd |= __SHIFTIN(dt->dt_day, AWIN_RTC_YY_MM_DD_DAY); + hhmmss = 0; + hhmmss |= __SHIFTIN(dt->dt_wday, AWIN_RTC_HH_MM_SS_WK_NO); + hhmmss |= __SHIFTIN(dt->dt_hour, AWIN_RTC_HH_MM_SS_HOUR); + hhmmss |= __SHIFTIN(dt->dt_min, AWIN_RTC_HH_MM_SS_MINUTE); + hhmmss |= __SHIFTIN(dt->dt_sec, AWIN_RTC_HH_MM_SS_SECOND); + + bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_RTC_YY_MM_DD_REG, + yymmdd); + bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_RTC_HH_MM_SS_REG, + hhmmss); + + return 0; +}