Module Name:    src
Committed By:   ryo
Date:           Mon Oct  6 10:15:40 UTC 2014

Modified Files:
        src/sys/arch/arm/imx: files.imx6 imx6_reg.h
Added Files:
        src/sys/arch/arm/imx: imx6_snvs.c imx6_snvsreg.h

Log Message:
add support imx6 Secure Non-Volatile Storage (SNVS) real-time clock


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/imx/files.imx6 \
    src/sys/arch/arm/imx/imx6_reg.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/imx6_snvs.c \
    src/sys/arch/arm/imx/imx6_snvsreg.h

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/imx/files.imx6
diff -u src/sys/arch/arm/imx/files.imx6:1.2 src/sys/arch/arm/imx/files.imx6:1.3
--- src/sys/arch/arm/imx/files.imx6:1.2	Thu Sep 25 05:05:28 2014
+++ src/sys/arch/arm/imx/files.imx6	Mon Oct  6 10:15:40 2014
@@ -1,4 +1,4 @@
-#	$NetBSD: files.imx6,v 1.2 2014/09/25 05:05:28 ryo Exp $
+#	$NetBSD: files.imx6,v 1.3 2014/10/06 10:15:40 ryo Exp $
 #
 # Configuration info for the Freescale i.MX6
 #
@@ -88,3 +88,9 @@ file	arch/arm/imx/imx6_usdhc.c		sdhc_axi
 # iMX6 SATA Controllers (AHCI)
 attach	ahcisata at axi with imx6_ahcisata
 file	arch/arm/imx/imx6_ahcisata.c		imx6_ahcisata
+
+# iMX6 Secure Non-Volatile Storage (SNVS)
+device	imxsnvs
+attach	imxsnvs at axi
+file	arch/arm/imx/imx6_snvs.c		imxsnvs
+
Index: src/sys/arch/arm/imx/imx6_reg.h
diff -u src/sys/arch/arm/imx/imx6_reg.h:1.2 src/sys/arch/arm/imx/imx6_reg.h:1.3
--- src/sys/arch/arm/imx/imx6_reg.h:1.2	Thu Sep 25 05:05:28 2014
+++ src/sys/arch/arm/imx/imx6_reg.h	Mon Oct  6 10:15:40 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx6_reg.h,v 1.2 2014/09/25 05:05:28 ryo Exp $	*/
+/*	$NetBSD: imx6_reg.h,v 1.3 2014/10/06 10:15:40 ryo Exp $	*/
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -139,7 +139,8 @@
 #define	AIPS1_EPIT2_BASE	0x000d4000
 #define	AIPS1_EPIT1_BASE	0x000d0000
 #define	AIPS1_EPIT_SIZE		0x00000020
-#define	AIPS1_SNVS_HP_BASE	0x000cc000
+#define	AIPS1_SNVS_BASE		0x000cc000
+#define	AIPS1_SNVS_SIZE		0x00000c00
 #define	AIPS1_USBPHY2_BASE	0x000ca000
 #define	AIPS1_USBPHY1_BASE	0x000c9000
 #define	AIPS1_ANATOP_DIG_BASE	0x000c8000

Added files:

Index: src/sys/arch/arm/imx/imx6_snvs.c
diff -u /dev/null src/sys/arch/arm/imx/imx6_snvs.c:1.1
--- /dev/null	Mon Oct  6 10:15:40 2014
+++ src/sys/arch/arm/imx/imx6_snvs.c	Mon Oct  6 10:15:40 2014
@@ -0,0 +1,217 @@
+/*	$NetBSD: imx6_snvs.c,v 1.1 2014/10/06 10:15:40 ryo Exp $	*/
+
+/*
+ * Copyright (c) 2014 Ryo Shimizu <[email protected]>
+ * 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.
+ */
+
+/*
+ * i.MX6 Secure Non-Volatile Storage
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx6_snvs.c,v 1.1 2014/10/06 10:15:40 ryo Exp $");
+
+#include "locators.h"
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/param.h>
+#include <dev/clock_subr.h>
+
+#include <arm/imx/imx6var.h>
+#include <arm/imx/imx6_reg.h>
+#include <arm/imx/imx6_snvsreg.h>
+
+struct imxsnvs_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_ioh;
+	struct todr_chip_handle sc_todr;
+};
+
+#define SNVS_READ(sc, reg)					\
+	bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, reg)
+
+#define SNVS_WRITE(sc, reg, val)				\
+	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, reg, val)
+
+static int imxsnvs_match(device_t, struct cfdata *, void *);
+static void imxsnvs_attach(device_t, device_t, void *);
+static int imxsnvs_rtc_enable(struct imxsnvs_softc *);
+static int imxsnvs_rtc_disable(struct imxsnvs_softc *);
+static int imxsnvs_gettime(todr_chip_handle_t, struct timeval *);
+static int imxsnvs_settime(todr_chip_handle_t, struct timeval *);
+
+
+CFATTACH_DECL_NEW(imxsnvs, sizeof(struct imxsnvs_softc),
+    imxsnvs_match, imxsnvs_attach, NULL, NULL);
+
+/* ARGSUSED */
+static int
+imxsnvs_match(device_t parent __unused, struct cfdata *match __unused, void *aux)
+{
+	struct axi_attach_args *aa;
+
+	aa = aux;
+
+	switch (aa->aa_addr) {
+	case (IMX6_AIPS1_BASE + AIPS1_SNVS_BASE):
+		return 1;
+	}
+
+	return 0;
+}
+
+/* ARGSUSED */
+static void
+imxsnvs_attach(device_t parent __unused, device_t self, void *aux)
+{
+	struct imxsnvs_softc *sc;
+	struct axi_attach_args *aa;
+	uint32_t v1, v2;
+
+	aa = aux;
+	sc = device_private(self);
+	sc->sc_dev = self;
+	sc->sc_iot = aa->aa_iot;
+
+	if (aa->aa_size == AXICF_SIZE_DEFAULT)
+		aa->aa_size = AIPS1_SNVS_SIZE;
+
+	aprint_naive("\n");
+	aprint_normal(": Secure Non-Volatile Storage\n");
+	if (bus_space_map(sc->sc_iot, aa->aa_addr, aa->aa_size, 0,
+	    &sc->sc_ioh)) {
+		aprint_error_dev(self, "Cannot map registers\n");
+		return;
+	}
+
+	v1 = SNVS_READ(sc, SNVS_HPVIDR1);
+	v2 = SNVS_READ(sc, SNVS_HPVIDR2);
+	aprint_verbose_dev(self, "id=0x%llx, ver=%lld.%lld, ip_era=0x%llx, "
+	    "intg_opt=0x%llx, eco_rev=0x%llx, config_opt=0x%llx\n",
+	    __SHIFTOUT(v1, SNVS_HPVIDR1_IP_ID),
+	    __SHIFTOUT(v1, SNVS_HPVIDR1_MAJOR_REV),
+	    __SHIFTOUT(v1, SNVS_HPVIDR1_MINOR_REV),
+	    __SHIFTOUT(v2, SNVS_HPVIDR2_IP_ERA),
+	    __SHIFTOUT(v2, SNVS_HPVIDR2_INTG_OPT),
+	    __SHIFTOUT(v2, SNVS_HPVIDR2_ECO_REV),
+	    __SHIFTOUT(v2, SNVS_HPVIDR2_CONFIG_OPT));
+
+	if (imxsnvs_rtc_enable(sc) != 0) {
+		aprint_error_dev(self, "cannot enable RTC\n");
+		return;
+	}
+
+	sc->sc_todr.todr_gettime = imxsnvs_gettime;
+	sc->sc_todr.todr_settime = imxsnvs_settime;
+	sc->sc_todr.cookie = sc;
+	todr_attach(&sc->sc_todr);
+
+	return;
+}
+
+static int
+imxsnvs_rtc_enable(struct imxsnvs_softc *sc)
+{
+	uint32_t v;
+	int timeout;
+
+	/* enable SRTC */
+	v = SNVS_READ(sc, SNVS_LPCR);
+	SNVS_WRITE(sc, SNVS_LPCR, v | SNVS_LPCR_SRTC_ENV);
+	for (timeout = 10000; timeout > 0; timeout--) {
+		if (SNVS_READ(sc, SNVS_LPCR) & SNVS_LPCR_SRTC_ENV)
+			break;
+	}
+	if (timeout == 0)
+		return ETIMEDOUT;
+
+	return 0;
+}
+
+static int
+imxsnvs_rtc_disable(struct imxsnvs_softc *sc)
+{
+	uint32_t v;
+	int timeout;
+
+	/* disable SRTC */
+	v = SNVS_READ(sc, SNVS_LPCR);
+	SNVS_WRITE(sc, SNVS_LPCR, v & ~SNVS_LPCR_SRTC_ENV);
+	for (timeout = 10000; timeout > 0; timeout--) {
+		if (!(SNVS_READ(sc, SNVS_LPCR) & SNVS_LPCR_SRTC_ENV))
+			break;
+	}
+	if (timeout == 0)
+		return ETIMEDOUT;
+
+	return 0;
+}
+
+static int
+imxsnvs_gettime(todr_chip_handle_t tch, struct timeval *tvp)
+{
+	struct imxsnvs_softc *sc;
+	uint64_t c1, c2;
+
+	sc = tch->cookie;
+
+	c2 = ((uint64_t)SNVS_READ(sc, SNVS_LPSRTCMR) << 32) +
+	    SNVS_READ(sc, SNVS_LPSRTCLR);
+	do {
+		c1 = c2;
+		c2 = ((uint64_t)SNVS_READ(sc, SNVS_LPSRTCMR) << 32) +
+		    SNVS_READ(sc, SNVS_LPSRTCLR);
+	} while (c1 != c2);
+
+	tvp->tv_sec = c1 >> SVNS_COUNTER_SHIFT;
+	tvp->tv_usec = (c1 % SVNS_COUNTER_HZ) * 1000000 / SVNS_COUNTER_HZ;
+
+	return 0;
+}
+
+static int
+imxsnvs_settime(todr_chip_handle_t tch, struct timeval *tvp)
+{
+	struct imxsnvs_softc *sc;
+	uint64_t c, h, l;
+	int rv;
+
+	c = (uint64_t)tvp->tv_sec * SVNS_COUNTER_HZ +
+	    (uint64_t)tvp->tv_usec * SVNS_COUNTER_HZ / 1000000;
+	h = __SHIFTIN((c >> 32) & SNVS_LPSRTCMR_SRTC, SNVS_LPSRTCMR_SRTC);
+	l = c & 0xffffffff;
+
+	sc = tch->cookie;
+	if ((rv = imxsnvs_rtc_disable(sc)) != 0)
+		return rv;
+
+	SNVS_WRITE(sc, SNVS_LPSRTCMR, h);
+	SNVS_WRITE(sc, SNVS_LPSRTCLR, l);
+
+	if ((rv = imxsnvs_rtc_enable(sc)) != 0)
+		return rv;
+
+	return 0;
+}
Index: src/sys/arch/arm/imx/imx6_snvsreg.h
diff -u /dev/null src/sys/arch/arm/imx/imx6_snvsreg.h:1.1
--- /dev/null	Mon Oct  6 10:15:40 2014
+++ src/sys/arch/arm/imx/imx6_snvsreg.h	Mon Oct  6 10:15:40 2014
@@ -0,0 +1,88 @@
+/*	$NetBSD: imx6_snvsreg.h,v 1.1 2014/10/06 10:15:40 ryo Exp $	*/
+
+/*
+ * Copyright (c) 2014 Ryo Shimizu <[email protected]>
+ * 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.
+ */
+#ifndef _IMX6_SNVSREG_H_
+#define _IMX6_SNVSREG_H_
+
+#define SVNS_COUNTER_HZ			(32 * 1024)	/* 32kHz */
+#define SVNS_COUNTER_SHIFT		15
+
+#define SNVS_HPLR			0x00000000
+#define SNVS_HPCOMR			0x00000004
+#define SNVS_HPCR			0x00000008
+#define SNVS_HPSR			0x00000014
+#define SNVS_HPRTCMR			0x00000024
+#define SNVS_HPRTCLR			0x00000028
+#define SNVS_HPTAMR			0x0000002c
+#define SNVS_HPTALR			0x00000030
+#define SNVS_LPLR			0x00000034
+#define  SNVS_LPLR_GPR_HL		__BIT(5)
+#define  SNVS_LPLR_MC_HL		__BIT(4)
+#define  SNVS_LPLR_LPCALB_HL		__BIT(3)
+#define  SNVS_LPLR_SRTC_HL		__BIT(2)
+#define SNVS_LPCR			0x00000038
+#define  SNVS_LPCR_PK_OVERRIDE		__BIT(23)
+#define  SNVS_LPCR_PK_EN		__BIT(22)
+#define  SNVS_LPCR_ON_TIME		__BITS(21, 20)
+#define  SNVS_LPCR_DEBOUNCE		__BITS(19, 18)
+#define  SNVS_LPCR_BTN_PRESS_TIME	__BITS(17, 16)
+#define  SNVS_LPCR_LPCALB_VAL		__BITS(14, 10)
+#define  SNVS_LPCR_LPCALB_EN		__BIT(8)
+#define  SNVS_LPCR_PWR_GLITCH_EN	__BIT(7)
+#define  SNVS_LPCR_TOP			__BIT(6)
+#define  SNVS_LPCR_DP_EN		__BIT(5)
+#define  SNVS_LPCR_SRTC_INV_EN		__BIT(4)
+#define  SNVS_LPCR_LPWUI_EN		__BIT(3)
+#define  SNVS_LPCR_MC_ENV		__BIT(2)
+#define  SNVS_LPCR_LPTA_EN		__BIT(1)
+#define  SNVS_LPCR_SRTC_ENV		__BIT(0)
+#define SNVS_LPSR			0x0000004c
+#define  SNVS_LPSR_SPO			__BIT(18)
+#define  SNVS_LPSR_EO			__BIT(17)
+#define  SNVS_LPSR_MCR			__BIT(2)
+#define  SNVS_LPSR_SRTCR		__BIT(1)
+#define  SNVS_LPSR_LPTA			__BIT(0)
+#define SNVS_LPSRTCMR			0x00000050
+#define  SNVS_LPSRTCMR_SRTC		__BITS(14, 0)
+#define SNVS_LPSRTCLR			0x00000054
+#define SNVS_LPTAR			0x00000058
+#define SNVS_LPSMCMR			0x0000005c
+#define  SNVS_LPSMCMR_MC_ERA_BIT	__BITS(31, 16)
+#define  SNVS_LPSMCMR_MON_COUNTER	__BITS(15, 0)
+#define SNVS_LPSMCLR			0x00000060
+#define SNVS_LPGPR			0x00000068
+#define SNVS_HPVIDR1			0x00000bf8
+#define  SNVS_HPVIDR1_IP_ID		__BITS(31, 16)
+#define  SNVS_HPVIDR1_MAJOR_REV		__BITS(15, 8)
+#define  SNVS_HPVIDR1_MINOR_REV		__BITS(7, 0)
+#define SNVS_HPVIDR2			0x00000bfc
+#define  SNVS_HPVIDR2_IP_ERA		__BITS(31, 24)
+#define  SNVS_HPVIDR2_INTG_OPT		__BITS(23, 16)
+#define  SNVS_HPVIDR2_ECO_REV		__BITS(15, 8)
+#define  SNVS_HPVIDR2_CONFIG_OPT	__BITS(7, 0)
+
+#endif /* _IMX6_SNVSREG_H_ */

Reply via email to