summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/board.h2
-rw-r--r--arch/arm/mach-tegra/common.c27
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_aes.c10
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.c16
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.h8
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_aes_intf_ap20.c13
-rw-r--r--arch/arm/mach-tegra/nvddk/nvddk_aes_priv.h10
7 files changed, 86 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
index e6801c4b5c24..574cf83c96fa 100644
--- a/arch/arm/mach-tegra/board.h
+++ b/arch/arm/mach-tegra/board.h
@@ -49,5 +49,7 @@ bool tegra_chip_compare(u32 chip, u32 major_rev, u32 minor_rev);
#define tegra_is_ap20_a03() tegra_chip_compare(0x20, 0x1, 0x3)
+bool tegra_is_ap20_a03p(void);
+
extern struct sys_timer tegra_timer;
#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index a1bc52ddce0d..85b61f337e3e 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -32,6 +32,11 @@
#include "board.h"
#define APB_MISC_HIDREV 0x804
+#define FUSE_VISIBILITY_REG_OFFSET 0x48
+#define FUSE_VISIBILITY_BIT_POS 28
+#define FUSE_SPARE_BIT_18_REG_OFFSET 0x248
+#define FUSE_SPARE_BIT_19_REG_OFFSET 0x24c
+
bool tegra_chip_compare(u32 chip, u32 major_rev, u32 minor_rev)
{
@@ -46,6 +51,28 @@ bool tegra_chip_compare(u32 chip, u32 major_rev, u32 minor_rev)
(major_rev==major || major_rev==TEGRA_ALL_REVS);
}
+bool tegra_is_ap20_a03p(void)
+{
+ if (tegra_is_ap20_a03()) {
+ void __iomem *clk = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+ void __iomem *fuse = IO_ADDRESS(TEGRA_FUSE_BASE);
+ u32 clk_val = readl(clk + FUSE_VISIBILITY_REG_OFFSET);
+ u32 fuse_18_val = 0;
+ u32 fuse_19_val = 0;
+
+ clk_val |= (1 << FUSE_VISIBILITY_BIT_POS);
+ writel(clk_val, (clk + FUSE_VISIBILITY_REG_OFFSET));
+ fuse_18_val = readl(fuse + FUSE_SPARE_BIT_18_REG_OFFSET);
+ fuse_19_val = readl(fuse + FUSE_SPARE_BIT_19_REG_OFFSET);
+ clk_val &= ~(1 << FUSE_VISIBILITY_BIT_POS);
+ writel(clk_val, (clk + FUSE_VISIBILITY_REG_OFFSET));
+ return (((fuse_18_val|fuse_19_val)&1)? true:false);
+ }
+ else {
+ return false;
+ }
+}
+
#ifdef CONFIG_DMABOUNCE
int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size)
{
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_aes.c b/arch/arm/mach-tegra/nvddk/nvddk_aes.c
index 9e7008c0e464..530363f1d743 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_aes.c
+++ b/arch/arm/mach-tegra/nvddk/nvddk_aes.c
@@ -603,6 +603,14 @@ NvDdkAesSetAndLockSecureStorageKey(
AesHwIv Iv;
AesHwEngine Engine;
+ NvOsMutexLock(gs_hAesCoreEngineMutex);
+ if (!gs_pAesCoreEngine->SskUpdateAllowed)
+ {
+ NvOsMutexUnlock(gs_hAesCoreEngineMutex);
+ return NvError_NotSupported;
+ }
+ NvOsMutexUnlock(gs_hAesCoreEngineMutex);
+
NVDDK_AES_CHECK_INPUT_PARAMS(pSecureStorageKey);
NVDDK_AES_CHECK_USER_IDENTITY;
@@ -1892,6 +1900,8 @@ NvError AesCoreInitEngine(const NvRmDeviceHandle hRmDevice)
0,
NULL));
}
+ gs_pAesCoreEngine->SskUpdateAllowed =
+ pAesHwCtxt->ppEngineCaps[AesHwEngine_A]->pAesInterf->AesHwIsSskUpdateAllowed();
return e;
}
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.c b/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.c
index ad94855b149e..71ffd5bf70c6 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.c
+++ b/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.c
@@ -41,6 +41,8 @@
#include "nvddk_aes_priv.h"
#include "nvddk_aes_hw.h"
#include "nvddk_aes_core_ap20.h"
+#include <linux/interrupt.h>
+#include "../board.h"
#define SECURE_HW_REGR(engine, viraddr, reg, value) \
{ \
@@ -545,3 +547,17 @@ void NvAesCoreAp20KeyReadDisable(
RegValue = NV_FLD_SET_DRF_NUM(ARVDE_BSEV, SECURE_SEC_SEL0, KEYREAD_ENB0, 0, RegValue);
SECURE_INDEXED_REGW(Engine, pEngineVirAddr, Slot, RegValue);
}
+
+NvBool NvAesCoreAp20IsSskUpdateAllowed(void)
+{
+ if (tegra_is_ap20_a03())
+ {
+ // It is AO3 chip
+ // Check whether it is AO3P or not
+ // SSK update is not supported on AO3 board
+ if (!tegra_is_ap20_a03p())
+ return NV_FALSE;
+ }
+ // Except AO3, all other chips support SSK update
+ return NV_TRUE;
+}
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.h b/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.h
index 728a3e276165..a9f06a8231ff 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.h
+++ b/arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.h
@@ -221,6 +221,14 @@ NvAesCoreAp20KeyReadDisable(
const AesHwKeySlot Slot,
const NvU32 *const pEngineVirAddr);
+/**
+ * Queries whether SSK update is allowed or not
+ *
+ * @retval NV_TRUE if SSK update is allowed
+ * @retval NV_FALSE if SSK update is not allowed
+ */
+NvBool NvAesCoreAp20IsSskUpdateAllowed(void);
+
#ifdef __cplusplus
};
#endif
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_aes_intf_ap20.c b/arch/arm/mach-tegra/nvddk/nvddk_aes_intf_ap20.c
index 0eeab861f3ad..474f5dc2bed4 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_aes_intf_ap20.c
+++ b/arch/arm/mach-tegra/nvddk/nvddk_aes_intf_ap20.c
@@ -122,6 +122,7 @@ Ap20AesHwDisableAllKeyRead(
const AesHwContext *const pAesHwCtxt,
const AesHwEngine Engine,
const AesHwKeySlot NumSlotsSupported);
+static NvBool Ap20AesIsSskUpdateAllowed(void);
/**
* Set the Setup Table command required for the AES engine.
@@ -663,6 +664,17 @@ Ap20AesHwDisableAllKeyRead(
NvOsMutexUnlock(pAesHwCtxt->Mutex[Engine]);
}
+/**
+ * Queries whether SSK update is allowed or not
+ *
+ * @retval NV_TRUE if SSK update is allowed
+ * @retval NV_FALSE if SSK update is not allowed
+ */
+NvBool Ap20AesIsSskUpdateAllowed(void)
+{
+ return NvAesCoreAp20IsSskUpdateAllowed();
+}
+
void NvAesIntfAp20GetHwInterface(AesHwInterface *const pAp20AesHw)
{
NV_ASSERT(pAp20AesHw);
@@ -680,4 +692,5 @@ void NvAesIntfAp20GetHwInterface(AesHwInterface *const pAp20AesHw)
pAp20AesHw->AesHwGetUsedSlots = Ap20AesHwGetUsedSlots;
pAp20AesHw->AesHwIsEngineDisabled = Ap20AesHwIsEngineDisabled;
pAp20AesHw->AesHwDisableAllKeyRead = Ap20AesHwDisableAllKeyRead;
+ pAp20AesHw->AesHwIsSskUpdateAllowed = Ap20AesIsSskUpdateAllowed;
}
diff --git a/arch/arm/mach-tegra/nvddk/nvddk_aes_priv.h b/arch/arm/mach-tegra/nvddk/nvddk_aes_priv.h
index a1fc9a540481..1bd78c9beab4 100644
--- a/arch/arm/mach-tegra/nvddk/nvddk_aes_priv.h
+++ b/arch/arm/mach-tegra/nvddk/nvddk_aes_priv.h
@@ -184,6 +184,8 @@ typedef struct AesCoreEngineRec
AesHwContext AesHwCtxt;
// Indicates whether engine is disabled or not
NvBool IsEngineDisabled;
+ // Indicates whether ssk update is allowed or not
+ NvBool SskUpdateAllowed;
} AesCoreEngine;
// Set of function pointers to be used to access the hardware interface for
@@ -399,6 +401,14 @@ struct AesHwInterfaceRec
const AesHwContext *const pAesHwCtxt,
const AesHwEngine Engine,
const AesHwKeySlot NumSlotsSupported);
+
+ /**
+ * Queries whether SSK update is allowed or not
+ *
+ * @retval NV_TRUE if SSK update is allowed
+ * @retval NV_FALSE if SSK update is not allowed
+ */
+ NvBool (*AesHwIsSskUpdateAllowed)(void);
};
// AES client state: this structure is common to all clients