Author: kevans
Date: Fri Apr  6 15:17:09 2018
New Revision: 332105
URL: https://svnweb.freebsd.org/changeset/base/332105

Log:
  aw_sid(4): Use prctl read for all reads when it's required
  
  It was later found that some operation on the OrangePi one will cause
  direct accesses to the eeprom to return wrong data again, so reading it all
  once via prctl at attach time is no longer sufficient.

Modified:
  head/sys/arm/allwinner/aw_sid.c

Modified: head/sys/arm/allwinner/aw_sid.c
==============================================================================
--- head/sys/arm/allwinner/aw_sid.c     Fri Apr  6 15:15:21 2018        
(r332104)
+++ head/sys/arm/allwinner/aw_sid.c     Fri Apr  6 15:17:09 2018        
(r332105)
@@ -61,8 +61,11 @@ __FBSDID("$FreeBSD$");
 #define        SID_RDKEY               0x60
 
 #define        SID_SRAM                0x200
-#define        SID_THERMAL_CALIB0      (SID_SRAM + 0x34)
-#define        SID_THERMAL_CALIB1      (SID_SRAM + 0x38)
+/* Offsets into efuse space, for convenience */
+#define        SID_THERMAL_CALIB0_OFF  (0x34)
+#define        SID_THERMAL_CALIB1_OFF  (0x38)
+#define        SID_THERMAL_CALIB0      (SID_SRAM + SID_THERMAL_CALIB0_OFF)
+#define        SID_THERMAL_CALIB1      (SID_SRAM + SID_THERMAL_CALIB1_OFF)
 
 #define        ROOT_KEY_SIZE           4
 
@@ -116,6 +119,7 @@ static struct ofw_compat_data compat_data[] = {
 };
 
 struct aw_sid_softc {
+       device_t                sid_dev;
        struct resource         *res;
        struct aw_sid_conf      *sid_conf;
        struct mtx              prctl_mtx;
@@ -135,6 +139,8 @@ enum sid_keys {
 #define        RD4(sc, reg)            bus_read_4((sc)->res, (reg))
 #define        WR4(sc, reg, val)       bus_write_4((sc)->res, (reg), (val))
 
+#define        PRCTL_RD4(sc, reg, val) aw_sid_prctl_read((sc)->sid_dev, (reg), 
(val))
+
 static int aw_sid_sysctl(SYSCTL_HANDLER_ARGS);
 static int aw_sid_prctl_read(device_t dev, bus_size_t offset, uint32_t *val);
 
@@ -183,10 +189,9 @@ static int
 aw_sid_attach(device_t dev)
 {
        struct aw_sid_softc *sc;
-       bus_size_t i;
-       uint32_t val;
 
        sc = device_get_softc(dev);
+       sc->sid_dev = dev;
 
        if (bus_alloc_resources(dev, aw_sid_spec, &sc->res) != 0) {
                device_printf(dev, "cannot allocate resources for device\n");
@@ -197,19 +202,6 @@ aw_sid_attach(device_t dev)
        sc->sid_conf = (struct aw_sid_conf *)ofw_bus_search_compatible(dev, 
compat_data)->ocd_data;
        aw_sid_sc = sc;
 
-       /*
-        * This set of reads is solely for working around a silicon bug on some
-        * SoC that require a prctl read in order for direct register access to
-        * return a non-garbled value. Hence, the values we read are simply
-        * ignored.
-        */
-       if (sc->sid_conf->requires_prctl_read)
-               for (i = 0; i < sc->sid_conf->efuse_size; i += 4)
-                       if (aw_sid_prctl_read(dev, i, &val) != 0) {
-                               device_printf(dev, "failed prctl read\n");
-                               goto fail;
-                       }
-
        SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
            SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
            OID_AUTO, "rootkey",
@@ -217,11 +209,6 @@ aw_sid_attach(device_t dev)
            dev, AW_SID_ROOT_KEY, aw_sid_sysctl, "A", "Root Key");
 
        return (0);
-
-fail:
-       bus_release_resources(dev, aw_sid_spec, &sc->res);
-       mtx_destroy(&sc->prctl_mtx);
-       return (ENXIO);
 }
 
 int
@@ -235,8 +222,13 @@ aw_sid_read_tscalib(uint32_t *calib0, uint32_t *calib1
        if (!sc->sid_conf->has_thermal)
                return (ENXIO);
 
-       *calib0 = RD4(sc, SID_THERMAL_CALIB0);
-       *calib1 = RD4(sc, SID_THERMAL_CALIB1);
+       if (sc->sid_conf->requires_prctl_read) {
+               PRCTL_RD4(sc, SID_THERMAL_CALIB0_OFF, calib0);
+               PRCTL_RD4(sc, SID_THERMAL_CALIB1_OFF, calib1);
+       } else {
+               *calib0 = RD4(sc, SID_THERMAL_CALIB0);
+               *calib1 = RD4(sc, SID_THERMAL_CALIB1);
+       }
 
        return (0);
 }
@@ -254,7 +246,10 @@ aw_sid_get_rootkey(u_char *out)
                return (ENXIO);
        root_key_off = aw_sid_sc->sid_conf->rootkey_offset;
        for (i = 0; i < ROOT_KEY_SIZE ; i++) {
-               tmp = RD4(aw_sid_sc, root_key_off + (i * 4));
+               if (sc->sid_conf->requires_prctl_read)
+                       PRCTL_RD4(sc, (i * 4), &tmp);
+               else
+                       tmp = RD4(aw_sid_sc, root_key_off + (i * 4));
                be32enc(&out[i * 4], tmp);
        }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to