[FOSS_TLK]platform: tegra: cleanup fuse handling
[3rdparty/ote_partner/tlk.git] / platform / tegra / common / fuse.c
index a0ab508..17f0c65 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2014, NVIDIA CORPORATION. All rights reserved
+ * 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
 #include <debug.h>
 #include <string.h>
 #include <platform.h>
-#include <reg.h>
 
 #include <platform/platform_fuse.h>
-#include <platform/memmap.h>
-
-/*
- * Fuse location information.
- */
-#if defined(TARGET_T124) || defined(TARGET_T132)
-
-#define ODM_PROD_ADDR                  (0x0)
-#define ODM_PROD_START_BIT             (11)
-
-#define ODM_RESERVED0_ADDR             (0x2E)
-#define ODM_RESERVED0_START_BIT                (5)
-
-#elif defined(TARGET_T210) || defined(TARGET_T186)
-
-#define ODM_PROD_ADDR                  (0x0)
-#define ODM_PROD_START_BIT             (11)
-
-#define ODM_RESERVED0_ADDR             (0x2E)
-#define ODM_RESERVED0_START_BIT                (17)
-
-#else
-
-#error unknown architecture
-
-#endif
-
-/*
- * The rollback protection fuses are in the ODM reserved fuse range.
- * ODM reserved fuses are 256bits wide.  To calculate the location of
- * a given fuse we need to determine its offset from ODM_RESERVED0's
- * address/start bit.
- *
- * Note that ODM reserved addresses increment by 2 (so if ODM_RESERVED0
- * is 0x2e then ODM_RESERVED1 is 0x30, etc).
- */
-
-/* calculate ODM_RESERVED1[13:12] bit offset from start of reserved block */
-#define RB_ENABLE_BIT                  (ODM_RESERVED0_START_BIT + 32 + 12)
-#define RB_KEY_PROGRAMMED_BIT          (ODM_RESERVED0_START_BIT + 32 + 13)
-
-/* given bit offset from start of reserved block get address */
-#define GET_ADDR(b)                    (ODM_RESERVED0_ADDR + (((b) / 32) * 2))
-
-/* given bit offset from start of reserved block get addr-relative start bit */
-#define GET_START_BIT(b)               ((b) % 32)
-
-/* get fuse-specific address/start bit */
-#define RB_ENABLE_ADDR                 GET_ADDR(RB_ENABLE_BIT)
-#define RB_ENABLE_START_BIT            GET_START_BIT(RB_ENABLE_BIT)
-
-#define RB_KEY_PROGRAMMED_ADDR         GET_ADDR(RB_KEY_PROGRAMMED_BIT)
-#define RB_KEY_PROGRAMMED_START_BIT    GET_START_BIT(RB_KEY_PROGRAMMED_BIT)
 
 /* fuse values table */
 static uint32_t fuse_values[FUSE_ID_MAX];
-
-/* 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 FUSE_WRITE32(o,v)              writel((v), TEGRA_FUSE_BASE + (o))
-#define FUSE_READ32(o)                         readl(TEGRA_FUSE_BASE + (o))
-
-/* car register information */
-#define CLK_MASK_ARM_0                 (0x48)
-#define CLK_MASK_ARM_CFG_ALL_VISIBLE   (0x10000000)
-
-#define RST_DEVICES_H_0                        (0x8)
-#define RST_DEVICES_H_SWR_FUSE_RST     (0x80)
-
-#define CLK_OUT_ENB_H_0                        (0x14)
-#define CLK_OUT_ENB_H_CLK_ENB_FUSE     (0x80)
-
-#define CAR_WRITE32(o,v)               writel((v), TEGRA_CLK_RESET_BASE + (o))
-#define CAR_READ32(o)                  readl(TEGRA_CLK_RESET_BASE + (o))
-
-static void fuse_wait_for_idle(void)
-{
-       uint32_t data;
-
-       do {
-               spin(1);
-               data = FUSE_READ32(FUSECTRL_0);
-       } 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();
-}
-
-static uint32_t fuse_read(uint32_t addr)
-{
-       uint32_t data;
-
-       fuse_cmd_sense();
-
-       fuse_wait_for_idle();
-
-       FUSE_WRITE32(FUSEADDR_0, addr);
-       data = FUSE_READ32(FUSECTRL_0);
-       data &= ~FUSECTRL_CMD_MASK;
-       data |= FUSECTRL_CMD_READ;
-       FUSE_WRITE32(FUSECTRL_0, data);
-
-       fuse_wait_for_idle();
-
-       data = FUSE_READ32(FUSERDATA_0);
-
-       return data;
-}
+static bool fuse_init_done;
 
 void platform_fuse_init(void)
 {
-       uint32_t fuse_data, clk_mask_arm_data = 0;
-       bool made_visible = false;
+       uint32_t fuse_data;
+       bool made_visible;
 
-       /* for now assume fuse block is out of reset with clock enabled */
-       ASSERT(!(CAR_READ32(RST_DEVICES_H_0) & RST_DEVICES_H_SWR_FUSE_RST));
-       ASSERT(CAR_READ32(CLK_OUT_ENB_H_0) & CLK_OUT_ENB_H_CLK_ENB_FUSE);
+       /* expose fuse registers for access */
+       made_visible = fuse_make_visible();
 
        /* clear fuse values */
        memset(fuse_values, 0, sizeof(fuse_values));
 
-       /* make all fuse registers visible */
-       clk_mask_arm_data = CAR_READ32(CLK_MASK_ARM_0);
-       if ((clk_mask_arm_data & CLK_MASK_ARM_CFG_ALL_VISIBLE) == 0) {
-               CAR_WRITE32(CLK_MASK_ARM_0,
-                       clk_mask_arm_data | CLK_MASK_ARM_CFG_ALL_VISIBLE);
-               made_visible = true;
-       }
-
        /* save odm production fuse value */
        fuse_data = fuse_read(ODM_PROD_ADDR);
        if (fuse_data & (1 << ODM_PROD_START_BIT))
@@ -194,22 +57,25 @@ void platform_fuse_init(void)
        if (fuse_data & (1 << RB_KEY_PROGRAMMED_START_BIT))
                fuse_values[FUSE_ID_RB_KEY_PROGRAMMED] = true;
 
-       dprintf(SPEW, "%s: odm_prod %d rpb_en %d rpb_key_prgrm %d\n",
+       dprintf(INFO, "%s: odm_prod %d rpb_en %d rpb_key_prgrm %d\n",
                __func__,
                fuse_values[FUSE_ID_ODM_PROD],
                fuse_values[FUSE_ID_RB_ENABLE],
                fuse_values[FUSE_ID_RB_KEY_PROGRAMMED]);
 
        /* move fuses back to invisible if necessary */
-       if (made_visible) {
-               CAR_WRITE32(CLK_MASK_ARM_0, clk_mask_arm_data);
-       }
+       if (made_visible)
+               fuse_make_invisible();
+
+       fuse_init_done = true;
 
        return;
 }
 
-uint32_t platform_fuse_show(enum fuse_ids fuse_id)
+uint32_t platform_fuse_get(enum fuse_ids fuse_id)
 {
+       ASSERT(fuse_init_done);
+
        if (fuse_id >= FUSE_ID_MAX)
                return false;