Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/imx add support imx6 Secure Non-Volatile Storag...



details:   https://anonhg.NetBSD.org/src/rev/fc56364da48c
branches:  trunk
changeset: 332727:fc56364da48c
user:      ryo <ryo%NetBSD.org@localhost>
date:      Mon Oct 06 10:15:40 2014 +0000

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

diffstat:

 sys/arch/arm/imx/files.imx6     |    8 +-
 sys/arch/arm/imx/imx6_reg.h     |    5 +-
 sys/arch/arm/imx/imx6_snvs.c    |  217 ++++++++++++++++++++++++++++++++++++++++
 sys/arch/arm/imx/imx6_snvsreg.h |   88 ++++++++++++++++
 4 files changed, 315 insertions(+), 3 deletions(-)

diffs (truncated from 351 to 300 lines):

diff -r 3aae062c9a94 -r fc56364da48c sys/arch/arm/imx/files.imx6
--- a/sys/arch/arm/imx/files.imx6       Mon Oct 06 09:05:55 2014 +0000
+++ b/sys/arch/arm/imx/files.imx6       Mon Oct 06 10:15:40 2014 +0000
@@ -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 @@
 # 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
+
diff -r 3aae062c9a94 -r fc56364da48c sys/arch/arm/imx/imx6_reg.h
--- a/sys/arch/arm/imx/imx6_reg.h       Mon Oct 06 09:05:55 2014 +0000
+++ b/sys/arch/arm/imx/imx6_reg.h       Mon Oct 06 10:15:40 2014 +0000
@@ -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
diff -r 3aae062c9a94 -r fc56364da48c sys/arch/arm/imx/imx6_snvs.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/imx/imx6_snvs.c      Mon Oct 06 10:15:40 2014 +0000
@@ -0,0 +1,217 @@
+/*     $NetBSD: imx6_snvs.c,v 1.1 2014/10/06 10:15:40 ryo Exp $        */
+
+/*
+ * Copyright (c) 2014 Ryo Shimizu <ryo%nerv.org@localhost>
+ * 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;
+}
diff -r 3aae062c9a94 -r fc56364da48c sys/arch/arm/imx/imx6_snvsreg.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/arm/imx/imx6_snvsreg.h   Mon Oct 06 10:15:40 2014 +0000
@@ -0,0 +1,88 @@
+/*     $NetBSD: imx6_snvsreg.h,v 1.1 2014/10/06 10:15:40 ryo Exp $     */
+
+/*
+ * Copyright (c) 2014 Ryo Shimizu <ryo%nerv.org@localhost>
+ * 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



Home | Main Index | Thread Index | Old Index