1 /* 2 * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. 3 * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #include <assert.h> 9 #include <errno.h> 10 #include <stdbool.h> 11 12 #include <arch_helpers.h> 13 #include <common/debug.h> 14 #include <drivers/delay_timer.h> 15 #include <lib/mmio.h> 16 #include <lib/psci/psci.h> 17 #include <tegra_platform.h> 18 19 #include "se_private.h" 20 21 /******************************************************************************* 22 * Constants and Macros 23 ******************************************************************************/ 24 #define ERR_STATUS_SW_CLEAR U(0xFFFFFFFF) 25 #define INT_STATUS_SW_CLEAR U(0xFFFFFFFF) 26 #define MAX_TIMEOUT_MS U(100) /* Timeout in 100ms */ 27 #define NUM_SE_REGS_TO_SAVE U(4) 28 29 /******************************************************************************* 30 * Data structure and global variables 31 ******************************************************************************/ 32 static uint32_t se_regs[NUM_SE_REGS_TO_SAVE]; 33 34 /* 35 * Check that SE operation has completed after kickoff. 36 * 37 * This function is invoked after an SE operation has been started, 38 * and it checks the following conditions: 39 * 40 * 1. SE_STATUS = IDLE 41 * 2. AHB bus data transfer is complete. 42 * 3. SE_ERR_STATUS is clean. 43 */ 44 static bool tegra_se_is_operation_complete(void) 45 { 46 uint32_t val = 0, timeout = 0, sha_status, aes_status; 47 int32_t ret = 0; 48 bool se_is_busy, txn_has_errors, txn_successful; 49 50 /* 51 * Poll the status register to check if the operation 52 * completed. 53 */ 54 do { 55 val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); 56 se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY); 57 58 /* sleep until SE finishes */ 59 if (se_is_busy) { 60 mdelay(1); 61 timeout++; 62 } 63 64 } while (se_is_busy && (timeout < MAX_TIMEOUT_MS)); 65 66 /* any transaction errors? */ 67 txn_has_errors = (tegra_se_read_32(SHA_ERR_STATUS) != 0U) || 68 (tegra_se_read_32(AES0_ERR_STATUS) != 0U); 69 70 /* transaction successful? */ 71 sha_status = tegra_se_read_32(SHA_INT_STATUS) & SHA_SE_OP_DONE; 72 aes_status = tegra_se_read_32(AES0_INT_STATUS) & AES0_SE_OP_DONE; 73 txn_successful = (sha_status == SHA_SE_OP_DONE) && 74 (aes_status == AES0_SE_OP_DONE); 75 76 if ((timeout == MAX_TIMEOUT_MS) || txn_has_errors || !txn_successful) { 77 ERROR("%s: Atomic context save operation failed!\n", 78 __func__); 79 ret = -ECANCELED; 80 } 81 82 return (ret == 0); 83 } 84 85 /* 86 * Wait for SE engine to be idle and clear any pending interrupts, before 87 * starting the next SE operation. 88 */ 89 static bool tegra_se_is_ready(void) 90 { 91 int32_t ret = 0; 92 uint32_t val = 0, timeout = 0; 93 bool se_is_ready; 94 95 /* Wait for previous operation to finish */ 96 do { 97 val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); 98 se_is_ready = (val == CTX_SAVE_AUTO_SE_READY); 99 100 /* sleep until SE is ready */ 101 if (!se_is_ready) { 102 mdelay(1); 103 timeout++; 104 } 105 106 } while (!se_is_ready && (timeout < MAX_TIMEOUT_MS)); 107 108 if (timeout == MAX_TIMEOUT_MS) { 109 ERROR("%s: SE is not ready!\n", __func__); 110 ret = -ETIMEDOUT; 111 } 112 113 /* Clear any pending interrupts from previous operation */ 114 tegra_se_write_32(AES0_INT_STATUS, INT_STATUS_SW_CLEAR); 115 tegra_se_write_32(AES1_INT_STATUS, INT_STATUS_SW_CLEAR); 116 tegra_se_write_32(RSA_INT_STATUS, INT_STATUS_SW_CLEAR); 117 tegra_se_write_32(SHA_INT_STATUS, INT_STATUS_SW_CLEAR); 118 119 /* Clear error status for each engine seen from current port */ 120 tegra_se_write_32(AES0_ERR_STATUS, ERR_STATUS_SW_CLEAR); 121 tegra_se_write_32(AES1_ERR_STATUS, ERR_STATUS_SW_CLEAR); 122 tegra_se_write_32(RSA_ERR_STATUS, ERR_STATUS_SW_CLEAR); 123 tegra_se_write_32(SHA_ERR_STATUS, ERR_STATUS_SW_CLEAR); 124 125 return (ret == 0); 126 } 127 128 /* 129 * During System Suspend, this handler triggers the hardware context 130 * save operation. 131 */ 132 static int32_t tegra_se_save_context(void) 133 { 134 int32_t ret = -ECANCELED; 135 136 /* 137 * 1. Ensure all SE Driver including RNG1/PKA1 are shut down. 138 * TSEC/R5s are powergated/idle. All tasks on SE1~SE4, RNG1, 139 * PKA1 are wrapped up. SE0 is ready for use. 140 * 2. Clear interrupt/error in SE0 status register. 141 * 3. Scrub SE0 register to avoid false failure for illegal 142 * configuration. Probably not needed, dependent on HW 143 * implementation. 144 * 4. Check SE is ready for HW CTX_SAVE by polling 145 * SE_CTX_SAVE_AUTO_STATUS.SE_READY. 146 * 147 * Steps 1-4 are executed by tegra_se_is_ready(). 148 * 149 * 5. Issue context save command. 150 * 6. Check SE is busy with CTX_SAVE, the command in step5 was not 151 * dropped for ongoing traffic in any of SE port/engine. 152 * 7. Poll SE register or wait for SE APB interrupt for task completion 153 * a. Polling: Read SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE 154 * b. Interrupt: After receiving interrupt from SE APB, read 155 * SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE. 156 * 8. Check AES0 and SHA ERR_STATUS to ensure no error case. 157 * 9. Check AES0 and SHA INT_STATUS to ensure operation has successfully 158 * completed. 159 * 160 * Steps 6-9 are executed by tegra_se_is_operation_complete(). 161 */ 162 if (tegra_se_is_ready()) { 163 164 /* Issue context save command */ 165 tegra_se_write_32(AES0_OPERATION, SE_OP_CTX_SAVE); 166 167 /* Wait for operation to finish */ 168 if (tegra_se_is_operation_complete()) { 169 ret = 0; 170 } 171 } 172 173 return ret; 174 } 175 176 /* 177 * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This 178 * needs to be called only during System Suspend. 179 */ 180 int32_t tegra_se_suspend(void) 181 { 182 int32_t ret = 0; 183 184 /* save SE registers */ 185 se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT); 186 se_regs[1] = mmio_read_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL); 187 se_regs[2] = mmio_read_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT); 188 se_regs[3] = mmio_read_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT); 189 190 /* Save SE context. The BootROM restores it during System Resume */ 191 ret = tegra_se_save_context(); 192 if (ret != 0) { 193 ERROR("%s: context save failed (%d)\n", __func__, ret); 194 } 195 196 return ret; 197 } 198 199 /* 200 * Handler to power up the SE hardware block(s) during System Resume. 201 */ 202 void tegra_se_resume(void) 203 { 204 /* 205 * When TZ takes over after System Resume, TZ should first reconfigure 206 * SE_MUTEX_WATCHDOG_NS_LIMIT, PKA1_MUTEX_WATCHDOG_NS_LIMIT, 207 * RNG1_MUTEX_WATCHDOG_NS_LIMIT and SE_ENTROPY_SRC_AGE_CTRL before 208 * other operations. 209 */ 210 mmio_write_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT, se_regs[0]); 211 mmio_write_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL, se_regs[1]); 212 mmio_write_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[2]); 213 mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]); 214 } 215