From: kettenis Date: Sun, 17 Dec 2017 15:29:29 +0000 (+0000) Subject: Add 32K output klock support. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=cfe273a3b9f39882a683cd45e784c82326eeced7;p=openbsd Add 32K output klock support. --- diff --git a/sys/dev/fdt/acrtc.c b/sys/dev/fdt/acrtc.c index a150a433a27..460bae916c1 100644 --- a/sys/dev/fdt/acrtc.c +++ b/sys/dev/fdt/acrtc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acrtc.c,v 1.1 2017/12/16 10:22:13 kettenis Exp $ */ +/* $OpenBSD: acrtc.c,v 1.2 2017/12/17 15:29:29 kettenis Exp $ */ /* * Copyright (c) 2017 Mark Kettenis * @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -31,25 +32,34 @@ extern todr_chip_handle_t todr_handle; -#define RTC_CTRL 0xc7 -#define RTC_CTRL_12H_24H_MODE (1 << 0) -#define RTC_SEC 0xc8 -#define RTC_MIN 0xc9 -#define RTC_HOU 0xca -#define RTC_WEE 0xcb -#define RTC_DAY 0xcc -#define RTC_MON 0xcd -#define RTC_YEA 0xce -#define RTC_YEA_LEAP_YEAR (1 << 15) -#define RTC_UPD_TRIG 0xcf -#define RTC_UPD_TRIG_UPDATE (1 << 15) +#define CK32K_OUT_CTRL1 0xc1 +#define CK32K_OUT_CTRL_PRE_DIV_MASK (0x7 << 5) +#define CK32K_OUT_CTRL_PRE_DIV_32K (0x7 << 5) +#define CK32K_OUT_CTRL_MUX_SEL_MASK (1 << 4) +#define CK32K_OUT_CTRL_MUX_SEL_32K (0 << 4) +#define CK32K_OUT_CTRL_POST_DIV_MASK (0x7 << 1) +#define CK32K_OUT_CTRL_POST_DIV_32K (0x0 << 1) +#define CK32K_OUT_CTRL_ENA (1 << 0) +#define RTC_CTRL 0xc7 +#define RTC_CTRL_12H_24H_MODE (1 << 0) +#define RTC_SEC 0xc8 +#define RTC_MIN 0xc9 +#define RTC_HOU 0xca +#define RTC_WEE 0xcb +#define RTC_DAY 0xcc +#define RTC_MON 0xcd +#define RTC_YEA 0xce +#define RTC_YEA_LEAP_YEAR (1 << 15) +#define RTC_UPD_TRIG 0xcf +#define RTC_UPD_TRIG_UPDATE (1 << 15) struct acrtc_softc { - struct device sc_dev; - void *sc_cookie; - uint16_t sc_rta; + struct device sc_dev; + void *sc_cookie; + uint16_t sc_rta; - struct todr_chip_handle sc_todr; + struct todr_chip_handle sc_todr; + struct clock_device sc_cd; }; int acrtc_match(struct device *, void *, void *); @@ -68,6 +78,8 @@ int acrtc_clock_write(struct acrtc_softc *, struct clock_ymdhms *); int acrtc_gettime(struct todr_chip_handle *, struct timeval *); int acrtc_settime(struct todr_chip_handle *, struct timeval *); +void acrtc_ck32k_enable(void *, uint32_t *, int); + int acrtc_match(struct device *parent, void *match, void *aux) { @@ -83,6 +95,7 @@ acrtc_attach(struct device *parent, struct device *self, void *aux) { struct acrtc_softc *sc = (struct acrtc_softc *)self; struct rsb_attach_args *ra = aux; + int node; sc->sc_cookie = ra->ra_cookie; sc->sc_rta = ra->ra_rta; @@ -93,6 +106,15 @@ acrtc_attach(struct device *parent, struct device *self, void *aux) sc->sc_todr.todr_gettime = acrtc_gettime; sc->sc_todr.todr_settime = acrtc_settime; todr_handle = &sc->sc_todr; + + node = OF_getnodebyname(ra->ra_node, "rtc"); + if (node == 0) + return; + + sc->sc_cd.cd_node = node; + sc->sc_cd.cd_cookie = sc; + sc->sc_cd.cd_enable = acrtc_ck32k_enable; + clock_register(&sc->sc_cd); } inline uint16_t @@ -184,3 +206,24 @@ acrtc_clock_write(struct acrtc_softc *sc, struct clock_ymdhms *dt) return 0; } + +void +acrtc_ck32k_enable(void *cookie, uint32_t *cells, int on) +{ + struct acrtc_softc *sc = cookie; + uint32_t idx = cells[0]; + uint16_t reg; + + reg = acrtc_read_reg(sc, CK32K_OUT_CTRL1 + idx); + reg &= ~CK32K_OUT_CTRL_PRE_DIV_MASK; + reg &= ~CK32K_OUT_CTRL_MUX_SEL_MASK; + reg &= ~CK32K_OUT_CTRL_POST_DIV_MASK; + reg |= CK32K_OUT_CTRL_PRE_DIV_32K; + reg |= CK32K_OUT_CTRL_MUX_SEL_32K; + reg |= CK32K_OUT_CTRL_POST_DIV_32K; + if (on) + reg |= CK32K_OUT_CTRL_ENA; + else + reg &= ~CK32K_OUT_CTRL_ENA; + acrtc_write_reg(sc, CK32K_OUT_CTRL1 + idx, reg); +}