[FOSS_TLK]platform: tegra: use arfuse registers
Scott Long [Fri, 12 Dec 2014 19:22:48 +0000 (11:22 -0800)]
Switch fuse init to use arfuse registers (e.g. FUSE_SECURITY_MODE_0)
to extract fuse values.

This avoids losing bypassed fuse values during init because the fuse
sense is left alone.

Change-Id: I2425d9b206a7d2c20ea6d28f3b9990d28724bf79
Signed-off-by: Scott Long <scottl@nvidia.com>
Reviewed-on: http://git-master/r/715766
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
Tested-by: Varun Wadekar <vwadekar@nvidia.com>

platform/tegra/common/fuse.c
platform/tegra/include/platform/platform_fuse.h
platform/tegra/include/platform/platform_p.h
platform/tegra/include/platform/tegra4/fuse_ext.h [deleted file]
platform/tegra/tegra4/fuse.c

index 35c413a..07e4fb6 100644 (file)
 #include <string.h>
 #include <platform.h>
 
+#include <platform/platform_p.h>
 #include <platform/platform_fuse.h>
 
 /* fuse values table */
-static uint32_t fuse_values[FUSE_ID_MAX];
+static uint32_t fuse_table[FUSE_ID_MAX];
 static bool fuse_init_done;
 
 void platform_fuse_init(void)
 {
-       uint32_t fuse_data;
-       bool made_visible;
-
-       /* expose fuse registers for access */
-       made_visible = fuse_make_visible();
-
-       /* clear fuse values */
-       memset(fuse_values, 0, sizeof(fuse_values));
-
-       /* save odm production fuse value */
-       fuse_data = fuse_read(ODM_PROD_ADDR);
-       if (fuse_data & (1 << ODM_PROD_START_BIT))
-               fuse_values[FUSE_ID_ODM_PROD] = true;
-
-       dprintf(INFO, "%s: odm_prod %d\n",
-               __func__, fuse_values[FUSE_ID_ODM_PROD]);
-
-       /* move fuses back to invisible if necessary */
-       if (made_visible)
-               fuse_make_invisible();
+       fuse_load_table(FUSE_ID_MAX, fuse_table);
 
        fuse_init_done = true;
 
-       return;
+       return ;
 }
 
 uint32_t platform_fuse_get(enum fuse_ids fuse_id)
@@ -66,5 +48,5 @@ uint32_t platform_fuse_get(enum fuse_ids fuse_id)
        if (fuse_id >= FUSE_ID_MAX)
                return false;
 
-       return fuse_values[fuse_id];
+       return fuse_table[fuse_id];
 }
index e2c30ef..6bd9858 100644 (file)
@@ -23,8 +23,6 @@
 #ifndef __PLATFORM_FUSE_H
 #define __PLATFORM_FUSE_H
 
-#include <fuse_ext.h>
-
 /*
  * ODM_PROD          -> ODM production fuse set
  */
@@ -34,6 +32,6 @@ enum fuse_ids {
 };
 
 void platform_fuse_init(void);
-uint32_t platform_fuse_get(enum fuse_ids fuse);
+uint32_t platform_fuse_get(enum fuse_ids fuse_id);
 
 #endif
index 2ba5741..53bc5f6 100644 (file)
@@ -74,4 +74,6 @@ void cpu_gic_setup(void);
 
 status_t set_log_phy_addr(nsaddr_t _ns_cb_struct_addr);
 
+void fuse_load_table(uint32_t fuse_id_max, uint32_t *fuse_table);
+
 #endif
diff --git a/platform/tegra/include/platform/tegra4/fuse_ext.h b/platform/tegra/include/platform/tegra4/fuse_ext.h
deleted file mode 100644 (file)
index 3f8b469..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files
- * (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge,
- * publish, distribute, sublicense, and/or sell copies of the Software,
- * and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-#ifndef __FUSE_EXT_H
-#define __FUSE_EXT_H
-
-/*
- * Fuse location information.
- */
-#if defined(TARGET_T124) || defined(TARGET_T132)
-
-#define ODM_PROD_ADDR                  (0x0)
-#define ODM_PROD_START_BIT             (11)
-
-#elif defined(TARGET_T210) || defined(TARGET_T186)
-
-#define ODM_PROD_ADDR                  (0x0)
-#define ODM_PROD_START_BIT             (11)
-
-#else
-
-#error unknown architecture
-
-#endif
-
-/* platform-dependent routines */
-bool fuse_make_visible(void);
-void fuse_make_invisible(void);
-uint32_t fuse_read(uint32_t addr);
-
-#endif
index ce80bd2..8470d06 100644 (file)
 #include <platform.h>
 #include <reg.h>
 
+#include <platform/platform_fuse.h>
+#include <platform/platform_p.h>
 #include <platform/memmap.h>
 
 /* fuse register information */
 #define FUSECTRL_0                     (0x0)
-#define FUSEADDR_0                     (0x4)
-#define FUSERDATA_0                    (0x8)
-#define FUSEWDATA_0                    (0xC)
-
 #define FUSECTRL_STATE_MASK            (0x1F << 16)
 #define FUSECTRL_STATE_IDLE            (0x4 << 16)
 
-#define FUSECTRL_CMD_MASK              (0x3 << 0)
-#define FUSECTRL_CMD_READ              (0x1)
-#define FUSECTRL_CMD_WRITE             (0x2)
-#define FUSECTRL_CMD_SENSE             (0x3)
+#define SECURITY_MODE_0                        (0x1a0)
+#define SECURITY_MODE_MASK             (0x1 << 0x0)
 
-#define FUSE_WRITE32(o,v)              writel((v), TEGRA_FUSE_BASE + (o))
 #define FUSE_READ32(o)                         readl(TEGRA_FUSE_BASE + (o))
 
 /* car register information */
@@ -67,21 +62,7 @@ static void fuse_wait_for_idle(void)
        } while ((data & FUSECTRL_STATE_MASK) != FUSECTRL_STATE_IDLE);
 }
 
-static void fuse_cmd_sense(void)
-{
-       uint32_t data;
-
-       fuse_wait_for_idle();
-
-       data = FUSE_READ32(FUSECTRL_0);
-       data &= ~FUSECTRL_CMD_MASK;
-       data |= FUSECTRL_CMD_SENSE;
-       FUSE_WRITE32(FUSECTRL_0, data);
-
-       fuse_wait_for_idle();
-}
-
-bool fuse_make_visible(void)
+static bool fuse_make_visible(void)
 {
        uint32_t clk_mask_arm_data = 0;
 
@@ -100,7 +81,7 @@ bool fuse_make_visible(void)
        return false;
 }
 
-void fuse_make_invisible(void)
+static void fuse_make_invisible(void)
 {
        uint32_t clk_mask_arm_data = 0;
 
@@ -112,24 +93,55 @@ void fuse_make_invisible(void)
        return;
 }
 
-uint32_t fuse_read(uint32_t addr)
+static te_error_t fuse_read(enum fuse_ids fuse_id, uint32_t *fuse_val)
 {
-       uint32_t data;
-
-       fuse_cmd_sense();
+       uint32_t val = 0;
+       te_error_t result = OTE_SUCCESS;
+
+       switch (fuse_id) {
+               case FUSE_ID_ODM_PROD:
+                       fuse_wait_for_idle();
+                       val = FUSE_READ32(SECURITY_MODE_0);
+                       val &= SECURITY_MODE_MASK;
+                       break;
+               default:
+                       dprintf(CRITICAL, "%s: unknown fuse id 0x%x\n",
+                               __func__, fuse_id);
+                       result = OTE_ERROR_BAD_PARAMETERS;
+                       break;
+       }
 
-       fuse_wait_for_idle();
+       *fuse_val = val;
 
-       FUSE_WRITE32(FUSEADDR_0, addr);
-       data = FUSE_READ32(FUSECTRL_0);
-       data &= ~FUSECTRL_CMD_MASK;
-       data |= FUSECTRL_CMD_READ;
-       FUSE_WRITE32(FUSECTRL_0, data);
+       return result;
+}
 
-       fuse_wait_for_idle();
+void fuse_load_table(uint32_t fuse_id_max, uint32_t *fuse_table)
+{
+       uint32_t fuse_id, fuse_data;
+       bool made_visible;
+
+       /* expose fuse registers for access */
+       made_visible = fuse_make_visible();
+
+       /* init fuses */
+       for (fuse_id = 0; fuse_id < FUSE_ID_MAX; fuse_id++) {
+               if (fuse_read(fuse_id, &fuse_data) != OTE_SUCCESS) {
+                       dprintf(CRITICAL, "%s: cannot read fuse_id %d\n",
+                               __func__, fuse_id);
+                       goto done;
+               }
+               fuse_table[fuse_id] = fuse_data;
+
+               dprintf(SPEW, "%s: id %d value 0x%x\n",
+                       __func__, fuse_id, fuse_table[fuse_id]);
+       }
 
-       data = FUSE_READ32(FUSERDATA_0);
+done:
+       /* move fuses back to invisible if necessary */
+       if (made_visible)
+               fuse_make_invisible();
 
-       return data;
+       return ;
 }