diff options
-rw-r--r-- | arch/arm/mach-tegra/board.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/common.c | 27 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvddk/nvddk_aes.c | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvddk/nvddk_aes_core_ap20.h | 8 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvddk/nvddk_aes_intf_ap20.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvddk/nvddk_aes_priv.h | 10 |
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 |