1 /* 2 * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <arch_helpers.h> 9 #include <common/debug.h> 10 #include <denver.h> 11 #include <lib/mmio.h> 12 #include <mce_private.h> 13 #include <errno.h> 14 15 extern void nvg_set_request_data(uint64_t req, uint64_t data); 16 extern void nvg_set_request(uint64_t req); 17 extern uint64_t nvg_get_result(void); 18 19 int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time) 20 { 21 /* check for allowed power state */ 22 if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && 23 state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { 24 ERROR("%s: unknown cstate (%d)\n", __func__, state); 25 return EINVAL; 26 } 27 28 /* time (TSC ticks) until the core is expected to get a wake event */ 29 nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time); 30 31 /* set the core cstate */ 32 write_actlr_el1(state); 33 34 return 0; 35 } 36 37 /* 38 * This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and 39 * SYSTEM_CSTATE values. 40 */ 41 int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, 42 uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, 43 uint8_t update_wake_mask) 44 { 45 uint64_t val = 0; 46 47 /* update CLUSTER_CSTATE? */ 48 if (cluster) 49 val |= (cluster & CLUSTER_CSTATE_MASK) | 50 CLUSTER_CSTATE_UPDATE_BIT; 51 52 /* update CCPLEX_CSTATE? */ 53 if (ccplex) 54 val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT | 55 CCPLEX_CSTATE_UPDATE_BIT; 56 57 /* update SYSTEM_CSTATE? */ 58 if (system) 59 val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) | 60 ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) | 61 SYSTEM_CSTATE_UPDATE_BIT); 62 63 /* update wake mask value? */ 64 if (update_wake_mask) 65 val |= CSTATE_WAKE_MASK_UPDATE_BIT; 66 67 /* set the wake mask */ 68 val &= CSTATE_WAKE_MASK_CLEAR; 69 val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT); 70 71 /* set the updated cstate info */ 72 nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val); 73 74 return 0; 75 } 76 77 int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time) 78 { 79 /* sanity check crossover type */ 80 if (type > TEGRA_ARI_CROSSOVER_CCP3_SC1) 81 return EINVAL; 82 83 /* 84 * The crossover threshold limit types start from 85 * TEGRA_CROSSOVER_TYPE_C1_C6 to TEGRA_CROSSOVER_TYPE_CCP3_SC7. The 86 * command indices for updating the threshold can be generated 87 * by adding the type to the NVG_SET_THRESHOLD_CROSSOVER_C1_C6 88 * command index. 89 */ 90 nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C1_C6 + type, 91 (uint64_t)time); 92 93 return 0; 94 } 95 96 uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state) 97 { 98 /* sanity check state */ 99 if (state == 0) 100 return EINVAL; 101 102 /* 103 * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES 104 * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for 105 * reading the threshold can be generated by adding the type to 106 * the NVG_CLEAR_CSTATE_STATS command index. 107 */ 108 nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state); 109 110 return (int64_t)nvg_get_result(); 111 } 112 113 int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats) 114 { 115 uint64_t val; 116 117 /* 118 * The only difference between a CSTATE_STATS_WRITE and 119 * CSTATE_STATS_READ is the usage of the 63:32 in the request. 120 * 63:32 are set to '0' for a read, while a write contains the 121 * actual stats value to be written. 122 */ 123 val = ((uint64_t)stats << MCE_CSTATE_STATS_TYPE_SHIFT) | state; 124 125 /* 126 * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES 127 * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for 128 * reading the threshold can be generated by adding the type to 129 * the NVG_CLEAR_CSTATE_STATS command index. 130 */ 131 nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state, val); 132 133 return 0; 134 } 135 136 int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) 137 { 138 /* This does not apply to the Denver cluster */ 139 return 0; 140 } 141 142 int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) 143 { 144 uint64_t val; 145 146 /* check for allowed power state */ 147 if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && 148 state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { 149 ERROR("%s: unknown cstate (%d)\n", __func__, state); 150 return EINVAL; 151 } 152 153 /* 154 * Request format - 155 * 63:32 = wake time 156 * 31:0 = C-state for this core 157 */ 158 val = ((uint64_t)wake_time << MCE_SC7_WAKE_TIME_SHIFT) | 159 (state & MCE_SC7_ALLOWED_MASK); 160 161 /* issue command to check if SC7 is allowed */ 162 nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val); 163 164 /* 1 = SC7 allowed, 0 = SC7 not allowed */ 165 return !!nvg_get_result(); 166 } 167 168 int nvg_online_core(uint32_t ari_base, uint32_t core) 169 { 170 int cpu = read_mpidr() & MPIDR_CPU_MASK; 171 int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; 172 173 /* sanity check code id */ 174 if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) { 175 ERROR("%s: unsupported core id (%d)\n", __func__, core); 176 return EINVAL; 177 } 178 179 /* 180 * The Denver cluster has 2 CPUs only - 0, 1. 181 */ 182 if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) { 183 ERROR("%s: unknown core id (%d)\n", __func__, core); 184 return EINVAL; 185 } 186 187 /* get a core online */ 188 nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE, core & MCE_CORE_ID_MASK); 189 190 return 0; 191 } 192 193 int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable) 194 { 195 int val; 196 197 /* 198 * If the enable bit is cleared, Auto-CC3 will be disabled by setting 199 * the SW visible voltage/frequency request registers for all non 200 * floorswept cores valid independent of StandbyWFI and disabling 201 * the IDLE voltage/frequency request register. If set, Auto-CC3 202 * will be enabled by setting the ARM SW visible voltage/frequency 203 * request registers for all non floorswept cores to be enabled by 204 * StandbyWFI or the equivalent signal, and always keeping the IDLE 205 * voltage/frequency request register enabled. 206 */ 207 val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\ 208 ((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\ 209 (enable ? MCE_AUTO_CC3_ENABLE_BIT : 0)); 210 211 nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val); 212 213 return 0; 214 } 215