diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h index 473540473be583b9c66970e69af4de541fc09558..cc32ec41611ac02075aa0a624728821897aa69f0 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h @@ -14,143 +14,61 @@ * Macros to prepare CSTATE info request ******************************************************************************/ /* Description of the parameters for UPDATE_CSTATE_INFO request */ -#define CLUSTER_CSTATE_MASK 0x7 -#define CLUSTER_CSTATE_SHIFT 0 -#define CLUSTER_CSTATE_UPDATE_BIT (1 << 7) -#define CCPLEX_CSTATE_MASK 0x3 -#define CCPLEX_CSTATE_SHIFT 8 -#define CCPLEX_CSTATE_UPDATE_BIT (1 << 15) -#define SYSTEM_CSTATE_MASK 0xF -#define SYSTEM_CSTATE_SHIFT 16 -#define SYSTEM_CSTATE_FORCE_UPDATE_SHIFT 22 -#define SYSTEM_CSTATE_FORCE_UPDATE_BIT (1 << 22) -#define SYSTEM_CSTATE_UPDATE_BIT (1 << 23) -#define CSTATE_WAKE_MASK_UPDATE_BIT (1 << 31) -#define CSTATE_WAKE_MASK_SHIFT 32 -#define CSTATE_WAKE_MASK_CLEAR 0xFFFFFFFF +#define CLUSTER_CSTATE_MASK 0x7UL +#define CLUSTER_CSTATE_SHIFT 0X0UL +#define CLUSTER_CSTATE_UPDATE_BIT (1UL << 7) +#define CCPLEX_CSTATE_MASK 0x3UL +#define CCPLEX_CSTATE_SHIFT 8UL +#define CCPLEX_CSTATE_UPDATE_BIT (1UL << 15) +#define SYSTEM_CSTATE_MASK 0xFUL +#define SYSTEM_CSTATE_SHIFT 16UL +#define SYSTEM_CSTATE_UPDATE_BIT (1UL << 23) +#define CSTATE_WAKE_MASK_UPDATE_BIT (1UL << 31) +#define CSTATE_WAKE_MASK_SHIFT 32UL +#define CSTATE_WAKE_MASK_CLEAR 0xFFFFFFFFUL /******************************************************************************* * Auto-CC3 control macros ******************************************************************************/ -#define MCE_AUTO_CC3_FREQ_MASK 0x1FF -#define MCE_AUTO_CC3_FREQ_SHIFT 0 -#define MCE_AUTO_CC3_VTG_MASK 0x7F -#define MCE_AUTO_CC3_VTG_SHIFT 16 -#define MCE_AUTO_CC3_ENABLE_BIT (1 << 31) +#define MCE_AUTO_CC3_FREQ_MASK 0xFFUL +#define MCE_AUTO_CC3_FREQ_SHIFT 0UL +#define MCE_AUTO_CC3_ENABLE_BIT (1UL << 31) /******************************************************************************* - * Macros for the 'IS_SC7_ALLOWED' command + * Core ID mask (bits 3:0 in the online request) ******************************************************************************/ -#define MCE_SC7_ALLOWED_MASK 0x7 -#define MCE_SC7_WAKE_TIME_SHIFT 32 +#define MCE_CORE_ID_MASK 0xFUL /******************************************************************************* - * Macros for 'read/write ctats' commands + * Cache control macros ******************************************************************************/ -#define MCE_CSTATE_STATS_TYPE_SHIFT 32 -#define MCE_CSTATE_WRITE_DATA_LO_MASK 0xF - -/******************************************************************************* - * Macros for 'update crossover threshold' command - ******************************************************************************/ -#define MCE_CROSSOVER_THRESHOLD_TIME_SHIFT 32 - -/******************************************************************************* - * Timeout value used to powerdown a core - ******************************************************************************/ -#define MCE_CORE_SLEEP_TIME_INFINITE 0xFFFFFFFF - -/******************************************************************************* - * MCA command struct - ******************************************************************************/ -typedef union mca_cmd { - struct command { - uint8_t cmd; - uint8_t idx; - uint8_t subidx; - } command; - struct input { - uint32_t low; - uint32_t high; - } input; - uint64_t data; -} mca_cmd_t; - -/******************************************************************************* - * MCA argument struct - ******************************************************************************/ -typedef union mca_arg { - struct err { - uint64_t error:8; - uint64_t unused:48; - uint64_t finish:8; - } err; - struct arg { - uint32_t low; - uint32_t high; - } arg; - uint64_t data; -} mca_arg_t; - -/******************************************************************************* - * Uncore PERFMON ARI struct - ******************************************************************************/ -typedef union uncore_perfmon_req { - struct perfmon_command { - /* - * Commands: 0 = READ, 1 = WRITE - */ - uint64_t cmd:8; - /* - * The unit group: L2=0, L3=1, ROC=2, MC=3, IOB=4 - */ - uint64_t grp:4; - /* - * Unit selector: Selects the unit instance, with 0 = Unit - * = (number of units in group) - 1. - */ - uint64_t unit:4; - /* - * Selects the uncore perfmon register to access - */ - uint64_t reg:8; - /* - * Counter number. Selects which counter to use for - * registers NV_PMEVCNTR and NV_PMEVTYPER. - */ - uint64_t counter:8; - } perfmon_command; - struct perfmon_status { - /* - * Resulting command status - */ - uint64_t val:8; - uint64_t unused:24; - } perfmon_status; - uint64_t data; -} uncore_perfmon_req_t; - -#define UNCORE_PERFMON_CMD_READ 0 -#define UNCORE_PERFMON_CMD_WRITE 1 - -#define UNCORE_PERFMON_CMD_MASK 0xFF -#define UNCORE_PERFMON_UNIT_GRP_MASK 0xF -#define UNCORE_PERFMON_SELECTOR_MASK 0xF -#define UNCORE_PERFMON_REG_MASK 0xFF -#define UNCORE_PERFMON_CTR_MASK 0xFF -#define UNCORE_PERFMON_RESP_STATUS_MASK 0xFF +#define CACHE_CLEAN_SET (1UL << 0) +#define CACHE_CLEAN_INVAL_SET (1UL << 1) +#define CACHE_CLEAN_INVAL_TR_SET (1UL << 2) /* declarations for NVG handler functions */ -int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time); -int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, - uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, - uint8_t update_wake_mask); -int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time); -uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state); -int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t val); -int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time); -int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time); -int nvg_online_core(uint32_t ari_base, uint32_t core); -int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable); +uint64_t nvg_get_version(void); +int32_t nvg_enable_power_perf_mode(void); +int32_t nvg_disable_power_perf_mode(void); +int32_t nvg_enable_power_saver_modes(void); +int32_t nvg_disable_power_saver_modes(void); +void nvg_set_wake_time(uint32_t wake_time); +void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex, + uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask); +int32_t nvg_update_crossover_time(uint32_t type, uint32_t time); +int32_t nvg_set_cstate_stat_query_value(uint64_t data); +uint64_t nvg_get_cstate_stat_query_value(void); +int32_t nvg_is_sc7_allowed(void); +int32_t nvg_online_core(uint32_t core); +int32_t nvg_cc3_ctrl(uint32_t freq, uint8_t enable); +int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx); +int32_t nvg_roc_flush_cache(void); +int32_t nvg_roc_clean_cache(void); +int32_t nvg_roc_clean_cache_trbits(void); +int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time); + +void nvg_set_request_data(uint64_t req, uint64_t data); +void nvg_set_request(uint64_t req); +uint64_t nvg_get_result(void); #endif /* __MCE_PRIVATE_H__ */ diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h new file mode 100644 index 0000000000000000000000000000000000000000..1fe462032d70b89fd5377e55fc01b707c0435d47 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef T194_NVG_H +#define T194_NVG_H + +/** + * t194_nvg.h - Header for the NVIDIA Generic interface (NVG). + * Official documentation for this interface is included as part + * of the T194 TRM. + */ + +/** + * Current version - Major version increments may break backwards + * compatiblity and binary compatibility. Minor version increments + * occur when there is only new functionality. + */ +enum { + TEGRA_NVG_VERSION_MAJOR = 6, + TEGRA_NVG_VERSION_MINOR = 0, +}; + +typedef enum { + TEGRA_NVG_CHANNEL_VERSION = 0, + TEGRA_NVG_CHANNEL_POWER_PERF = 1, + TEGRA_NVG_CHANNEL_POWER_MODES = 2, + TEGRA_NVG_CHANNEL_WAKE_TIME = 3, + TEGRA_NVG_CHANNEL_CSTATE_INFO = 4, + TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = 5, + TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = 6, + // Value 7 reserved + TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = 8, + // Value 9 reserved + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = 10, + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = 11, + // Values 12-42 reserved + TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43, + TEGRA_NVG_CHANNEL_ONLINE_CORE = 44, + TEGRA_NVG_CHANNEL_CC3_CTRL = 45, + TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = 50, + TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL = 51, + // 52 FREQ FEEDBACK + TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = 53, + TEGRA_NVG_CHANNEL_SECURITY_CONFIG = 54, + TEGRA_NVG_CHANNEL_LAST_INDEX, +} tegra_nvg_channel_id_t; + + +typedef enum { + // Value 0 reserved + NVG_STAT_QUERY_SC7_ENTRIES = 1, + // Values 2-5 reserved + NVG_STAT_QUERY_CC6_ENTRIES = 6, + NVG_STAT_QUERY_CG7_ENTRIES = 7, + // Values 8-9 reserved + NVG_STAT_QUERY_C6_ENTRIES = 10, + // Values 11-13 reserved + NVG_STAT_QUERY_C7_ENTRIES = 14, + // Values 15-31 reserved + NVG_STAT_QUERY_SC7_RESIDENCY_SUM = 32, + NVG_STAT_QUERY_CC6_RESIDENCY_SUM = 41, + NVG_STAT_QUERY_CG7_RESIDENCY_SUM = 46, + NVG_STAT_QUERY_C6_RESIDENCY_SUM = 51, + NVG_STAT_QUERY_C7_RESIDENCY_SUM = 56, +} tegra_nvg_stat_query_t; + + +typedef enum { + TEGRA_NVG_CORE_C0 = 0, + TEGRA_NVG_CORE_C1 = 1, + TEGRA_NVG_CORE_C6 = 6, + TEGRA_NVG_CORE_C7 = 7, + TEGRA_NVG_CORE_WARMRSTREQ = 8, +} tegra_nvg_core_sleep_state_t; + +typedef enum { + TEGRA_NVG_CLUSTER_CC0 = 0, + TEGRA_NVG_CLUSTER_CC6 = 6, +} tegra_nvg_cluster_sleep_state_t; + +typedef enum { + TEGRA_NVG_CCPLEX_CG0 = 0, + TEGRA_NVG_CCPLEX_CG7 = 1, + +} tegra_nvg_cluster_group_sleep_state_t; + +typedef enum { + TEGRA_NVG_SYSTEM_SC0 = 0, + TEGRA_NVG_SYSTEM_SC7 = 7, + TEGRA_NVG_SYSTEM_SC8 = 8, +} tegra_nvg_system_sleep_state_t; + +// --------------------------------------------------------------------------- +// NVG Data subformats +// --------------------------------------------------------------------------- + +typedef union +{ + uint64_t flat; + struct nvg_version_channel_t { + uint64_t minor_version : 32; + uint64_t major_version : 32; + } bits; +} nvg_version_data_t; + +typedef union nvg_channel_1_data_u +{ + uint64_t flat; + struct nvg_channel_1_data_s + { + uint64_t perf_per_watt_mode : 1; + uint64_t reserved_63_1 : 63; + } bits; +} nvg_channel_1_data_t; + +typedef union nvg_channel_2_data_u +{ + uint64_t flat; + struct nvg_channel_2_data_s + { + uint64_t reserved_1_0 : 2; + uint64_t battery_saver_mode : 1; + uint64_t reserved_63_3 : 61; + } bits; +} nvg_channel_2_data_t; + +typedef union +{ + uint64_t flat; + struct nvg_wake_time_channel_t { + uint64_t wake_time : 32; + uint64_t reserved_63_32 : 32; + } bits; +} nvg_wake_time_channel_t; + +typedef union +{ + uint64_t flat; + struct nvg_cstate_info_channel_t { + uint64_t cluster_state : 3; + uint64_t reserved_6_3 : 4; + uint64_t update_cluster : 1; + uint64_t cg_cstate : 3; + uint64_t reserved_14_11 : 4; + uint64_t update_cg : 1; + uint64_t system_cstate : 4; + uint64_t reserved_22_20 : 3; + uint64_t update_system : 1; + uint64_t reserved_30_24 : 7; + uint64_t update_wake_mask : 1; + uint64_t wake_mask : 32; + } bits; +} nvg_cstate_info_channel_t; + +typedef union +{ + uint64_t flat; + struct nvg_lower_bound_channel_t { + uint64_t crossover_value : 32; + uint64_t reserved_63_32 : 32; + } bits; +} nvg_lower_bound_channel_t; + + +typedef union +{ + uint64_t flat; + struct nvg_cstate_stat_query_channel_t { + uint64_t unit_id : 4; + uint64_t reserved_15_4 : 12; + uint64_t stat_id : 16; + uint64_t reserved_63_32 : 32; + } bits; +} nvg_cstate_stat_query_channel_t; + +typedef union +{ + uint64_t flat; + struct nvg_is_sc7_allowed_channel_t { + uint64_t is_sc7_allowed : 1; + uint64_t reserved_63_32 : 63; + } bits; +} nvg_is_sc7_allowed_channel_t; + + +typedef union +{ + uint64_t flat; + struct nvg_core_online_channel_t { + uint64_t core_id : 4; + uint64_t reserved_63_4 : 60; + } bits; +} nvg_core_online_channel_t; + + +typedef union +{ + uint64_t flat; + struct nvg_cc3_control_channel_t { + uint64_t freq_req : 8; + uint64_t reserved_30_8 : 23; + uint64_t enable : 1; + uint64_t reserved_63_32 : 32; + } bits; +} nvg_cc3_control_channel_t; + + +typedef union +{ + uint64_t flat; + struct nvg_update_gsc_channel_t { + uint64_t gsc_enum : 16; + uint64_t reserved_63_16 : 48; + } bits; +} nvg_update_gsc_channel_t; + + +typedef union +{ + uint64_t flat; + struct nvg_cache_inval_channel_t { + uint64_t cache_clean : 1; + uint64_t cache_clean_inval : 1; + uint64_t cache_clean_inval_tr : 1; + uint64_t reserved_63_3 : 61; + } bits; +} nvg_cache_inval_channel_t; + + +/* GSC type define */ +typedef enum { + TEGRA_NVG_GSC_ALL=0, + TEGRA_NVG_GSC_NVDEC=1, + TEGRA_NVG_GSC_WPR1=2, + TEGRA_NVG_GSC_WPR2=3, + TEGRA_NVG_GSC_TSECA=4, + TEGRA_NVG_GSC_TSECB=5, + + TEGRA_NVG_GSC_BPMP=6, + TEGRA_NVG_GSC_APE=7, + TEGRA_NVG_GSC_SPE=8, + TEGRA_NVG_GSC_SCE=9, + TEGRA_NVG_GSC_APR=10, + TEGRA_NVG_GSC_TZRAM=11, + TEGRA_NVG_GSC_SE=12, + + TEGRA_NVG_GSC_DMCE=13, + TEGRA_NVG_GSC_BPMP_TO_DMCE=14, + TEGRA_NVG_GSC_BPMP_TO_SPE=16, + TEGRA_NVG_GSC_CPU_TZ_TO_BPMP=18, + TEGRA_NVG_GSC_CPU_NS_TO_BPMP=20, + TEGRA_NVG_GSC_IPC_SE_SPE_SCE_BPMP=22, + TEGRA_NVG_GSC_SC7_RESUME_FW=23, + + TEGRA_NVG_GSC_VPR_RESIZE=24, + TEGRA_NVG_GSC_RCE=25, + TEGRA_NVG_GSC_CV=26, + + TEGRA_NVG_GSC_BO_MTS_PACKAGE=28, + TEGRA_NVG_GSC_BO_MCE_PREBOOT=29, + + TEGRA_NVG_GSC_TZ_DRAM_IDX=34, + TEGRA_NVG_GSC_VPR_IDX=35, +} tegra_nvg_gsc_index_t; + +typedef enum { + TEGRA_NVG_CROSSOVER_C6 = 0, + TEGRA_NVG_CROSSOVER_CC6 = 1, + TEGRA_NVG_CROSSOVER_CG7 = 2, +} tegra_nvg_crossover_index_t; + +#endif // T194_NVG_H diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c index 3a2e262f605ca864361296515c35dda0cb4627d0..4754b77c5124c76934bb3dcb6926f783fb246306 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c @@ -15,21 +15,21 @@ #include <mce.h> #include <mce_private.h> #include <mmio.h> +#include <platform_def.h> #include <string.h> #include <errno.h> +#include <t194_nvg.h> #include <tegra_def.h> #include <tegra_platform.h> /******************************************************************************* * Common handler for all MCE commands ******************************************************************************/ -int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, +int32_t mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2) { uint64_t ret64 = 0, arg3, arg4, arg5; - int ret = 0; - mca_cmd_t mca_cmd; - uncore_perfmon_req_t req; + int32_t ret = 0; cpu_context_t *ctx = cm_get_context(NON_SECURE); gp_regs_t *gp_regs = get_gpregs_ctx(ctx); @@ -38,7 +38,11 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, switch (cmd) { case MCE_CMD_ENTER_CSTATE: - /* NVG */ + ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1); + if (ret < 0) { + ERROR("%s: enter_cstate failed(%d)\n", __func__, ret); + } + break; case MCE_CMD_UPDATE_CSTATE_INFO: @@ -46,214 +50,147 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, * get the parameters required for the update cstate info * command */ - arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4); - arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5); - arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6); - - /* NVG */ + arg3 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4)); + arg4 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5)); + arg5 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6)); + + /* arg0 cluster + * arg1 ccplex + * arg2 system + * arg3 sys_state_force => T19x not support + * arg4 wake_mask + * arg5 update_wake_mask + */ + nvg_update_cstate_info((uint32_t)arg0, (uint32_t)arg1, + (uint32_t)arg2, (uint32_t)arg4, (uint8_t)arg5); - write_ctx_reg(gp_regs, CTX_GPREG_X4, arg3); - write_ctx_reg(gp_regs, CTX_GPREG_X5, arg4); - write_ctx_reg(gp_regs, CTX_GPREG_X6, arg5); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4), (arg3)); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5), (arg4)); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6), (arg5)); break; case MCE_CMD_UPDATE_CROSSOVER_TIME: - /* NVG */ + ret = nvg_update_crossover_time((uint32_t)arg0, (uint32_t)arg1); + if (ret < 0) { + ERROR("%s: update_crossover_time failed(%d)\n", + __func__, ret); + } break; case MCE_CMD_READ_CSTATE_STATS: - /* NVG */ + ret64 = nvg_get_cstate_stat_query_value(); /* update context to return cstate stats value */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); - write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64)); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64)); break; case MCE_CMD_WRITE_CSTATE_STATS: - /* NVG */ - - break; - - case MCE_CMD_IS_CCX_ALLOWED: - /* NVG */ - - /* update context to return CCx status value */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); + ret = nvg_set_cstate_stat_query_value(arg0); break; case MCE_CMD_IS_SC7_ALLOWED: - /* NVG */ + ret = nvg_is_sc7_allowed(); + if (ret < 0) { + ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret); + break; + } /* update context to return SC7 status value */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); - write_ctx_reg(gp_regs, CTX_GPREG_X3, ret); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), ((uint64_t)ret)); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X3), ((uint64_t)ret)); break; case MCE_CMD_ONLINE_CORE: - /* NVG */ + ret = nvg_online_core((uint32_t)arg0); + if (ret < 0) { + ERROR("%s: online_core failed(%d)\n", __func__, ret); + } break; case MCE_CMD_CC3_CTRL: - /* NVG */ - - break; - - case MCE_CMD_ECHO_DATA: - /* issue NVG to echo data */ - - /* update context to return if echo'd data matched source */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64 == arg0); - write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64 == arg0); + ret = nvg_cc3_ctrl((uint32_t)arg0, (uint8_t)arg2); + if (ret < 0) { + ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret); + } break; case MCE_CMD_READ_VERSIONS: /* get the MCE firmware version */ + ret64 = nvg_get_version(); /* * version = minor(63:32) | major(31:0). Update context * to return major and minor version number. */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint32_t)ret64); - write_ctx_reg(gp_regs, CTX_GPREG_X2, (uint32_t)(ret64 >> 32)); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64 & (uint64_t)0xFFFF)); + write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64 >> 32)); break; - case MCE_CMD_ENUM_FEATURES: - break; - case MCE_CMD_ROC_FLUSH_CACHE_TRBITS: - /* NVG */ + ret = nvg_roc_clean_cache_trbits(); + if (ret < 0) { + ERROR("%s: flush cache_trbits failed(%d)\n", __func__, + ret); + } break; case MCE_CMD_ROC_FLUSH_CACHE: - /* NVG */ + ret = nvg_roc_flush_cache(); + if (ret < 0) { + ERROR("%s: flush cache failed(%d)\n", __func__, ret); + } break; case MCE_CMD_ROC_CLEAN_CACHE: - /* NVG */ - - break; - - case MCE_CMD_ENUM_READ_MCA: - memcpy(&mca_cmd, &arg0, sizeof(arg0)); - - /* NVG */ - - /* update context to return MCA data/error */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); - write_ctx_reg(gp_regs, CTX_GPREG_X2, arg1); - write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); - - break; - - case MCE_CMD_ENUM_WRITE_MCA: - memcpy(&mca_cmd, &arg0, sizeof(arg0)); - - /* NVG */ - - /* update context to return MCA error */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); - write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); - - break; - - case MCE_CMD_ENABLE_LATIC: - /* - * This call is not for production use. The constant value, - * 0xFFFF0000, is specific to allowing for enabling LATIC on - * pre-production parts for the chip verification harness. - * - * Enabling LATIC allows S/W to read the MINI ISPs in the - * CCPLEX. The ISMs are used for various measurements relevant - * to particular locations in the Silicon. They are small - * counters which can be polled to determine how fast a - * particular location in the Silicon is. - */ - /* NVG */ - - break; - - case MCE_CMD_UNCORE_PERFMON_REQ: - memcpy(&req, &arg0, sizeof(arg0)); - /* NVG */ - - /* update context to return data */ - write_ctx_reg(gp_regs, CTX_GPREG_X1, arg1); - break; - - case MCE_CMD_MISC_CCPLEX: - /* NVG */ + ret = nvg_roc_clean_cache(); + if (ret < 0) { + ERROR("%s: clean cache failed(%d)\n", __func__, ret); + } break; default: ERROR("unknown MCE command (%lld)\n", cmd); - return EINVAL; + ret = EINVAL; + break; } return ret; } -/******************************************************************************* - * Handler to update the reset vector for CPUs - ******************************************************************************/ -int mce_update_reset_vector(void) -{ - return 0; -} - -static int mce_update_ccplex_gsc(/* GSC ID */) -{ - return 0; -} - /******************************************************************************* * Handler to update carveout values for Video Memory Carveout region ******************************************************************************/ -int mce_update_gsc_videomem(void) +int32_t mce_update_gsc_videomem(void) { - return mce_update_ccplex_gsc(); + return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_VPR_IDX); } /******************************************************************************* * Handler to update carveout values for TZDRAM aperture ******************************************************************************/ -int mce_update_gsc_tzdram(void) +int32_t mce_update_gsc_tzdram(void) { - return mce_update_ccplex_gsc(); + return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZ_DRAM_IDX); } /******************************************************************************* * Handler to update carveout values for TZ SysRAM aperture ******************************************************************************/ -int mce_update_gsc_tzram(void) +int32_t mce_update_gsc_tzram(void) { - return mce_update_ccplex_gsc(); -} - -/******************************************************************************* - * Handler to shutdown/reset the entire system - ******************************************************************************/ -__dead2 void mce_enter_ccplex_state(uint32_t state_idx) -{ - /* sanity check state value */ - - /* enter ccplex power state */ - - /* wait till the CCPLEX powers down */ - for (;;) - ; - - panic(); + return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZRAM); } /******************************************************************************* @@ -262,7 +199,8 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx) void mce_update_cstate_info(mce_cstate_info_t *cstate) { /* issue the UPDATE_CSTATE_INFO request */ - /* NVG */ + nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system, + cstate->wake_mask, cstate->update_wake_mask); } /******************************************************************************* @@ -277,18 +215,18 @@ void mce_verify_firmware_version(void) /* * MCE firmware is not running on simulation platforms. */ - if (tegra_platform_is_linsim() || tegra_platform_is_virt_dev_kit()) + if ((tegra_platform_is_linsim() == 1U) || + (tegra_platform_is_virt_dev_kit() == 1U)) { return; - - /* get a pointer to the CPU's arch_mce_ops_t struct */ + } /* * Read the MCE firmware version and extract the major and minor * version fields */ - version = 0; - major = (uint32_t)version; - minor = (uint32_t)(version >> 32); + version = nvg_get_version(); + minor = (uint32_t)version; + major = (uint32_t)(version >> 32); INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor, 0, 0); @@ -297,12 +235,12 @@ void mce_verify_firmware_version(void) * Verify that the MCE firmware version and the interface header * match */ - if (major != 0) { + if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) { ERROR("MCE major version mismatch\n"); panic(); } - if (minor < 0) { + if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) { ERROR("MCE minor version mismatch\n"); panic(); } diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c index 36b3aabbb353fcb9c1d7f4f3d0d3046c003188c4..12dd6cb09fe31cf2a70c846c025768b3f467a01b 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c @@ -8,207 +8,356 @@ #include <arch_helpers.h> #include <common/debug.h> #include <denver.h> +#include <errno.h> #include <lib/mmio.h> #include <mce_private.h> -#include <errno.h> +#include <platform_def.h> +#include <t194_nvg.h> extern void nvg_set_request_data(uint64_t req, uint64_t data); extern void nvg_set_request(uint64_t req); extern uint64_t nvg_get_result(void); -int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time) +/* + * Reports the major and minor version of this interface. + * + * NVGDATA[0:31]: SW(R) Minor Version + * NVGDATA[32:63]: SW(R) Major Version + */ +uint64_t nvg_get_version(void) { - /* check for allowed power state */ - if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && - state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { - ERROR("%s: unknown cstate (%d)\n", __func__, state); - return EINVAL; - } + nvg_set_request(TEGRA_NVG_CHANNEL_VERSION); - /* time (TSC ticks) until the core is expected to get a wake event */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time); + return (uint64_t)nvg_get_result(); +} - /* set the core cstate */ - write_actlr_el1(state); +/* + * Enable the perf per watt mode. + * + * NVGDATA[0]: SW(RW), 1 = enable perf per watt mode + */ +int32_t nvg_enable_power_perf_mode(void) +{ + nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_PERF, 1U); + + return 0; +} + +/* + * Disable the perf per watt mode. + * + * NVGDATA[0]: SW(RW), 0 = disable perf per watt mode + */ +int32_t nvg_disable_power_perf_mode(void) +{ + nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_PERF, 0U); + + return 0; +} + +/* + * Enable the battery saver mode. + * + * NVGDATA[2]: SW(RW), 1 = enable battery saver mode + */ +int32_t nvg_enable_power_saver_modes(void) +{ + nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_MODES, 1U); + + return 0; +} + +/* + * Disable the battery saver mode. + * + * NVGDATA[2]: SW(RW), 0 = disable battery saver mode + */ +int32_t nvg_disable_power_saver_modes(void) +{ + nvg_set_request_data(TEGRA_NVG_CHANNEL_POWER_MODES, 0U); return 0; } +/* + * Set the expected wake time in TSC ticks for the next low-power state the + * core enters. + * + * NVGDATA[0:31]: SW(RW), WAKE_TIME + */ +void nvg_set_wake_time(uint32_t wake_time) +{ + /* time (TSC ticks) until the core is expected to get a wake event */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, (uint64_t)wake_time); +} + /* * This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and * SYSTEM_CSTATE values. + * + * NVGDATA[0:2]: SW(RW), CLUSTER_CSTATE + * NVGDATA[7]: SW(W), update cluster flag + * NVGDATA[8:9]: SW(RW), CG_CSTATE + * NVGDATA[15]: SW(W), update ccplex flag + * NVGDATA[16:19]: SW(RW), SYSTEM_CSTATE + * NVGDATA[23]: SW(W), update system flag + * NVGDATA[31]: SW(W), update wake mask flag + * NVGDATA[32:63]: SW(RW), WAKE_MASK */ -int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex, - uint32_t system, uint8_t sys_state_force, uint32_t wake_mask, - uint8_t update_wake_mask) +void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex, + uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask) { uint64_t val = 0; /* update CLUSTER_CSTATE? */ - if (cluster) - val |= (cluster & CLUSTER_CSTATE_MASK) | - CLUSTER_CSTATE_UPDATE_BIT; + if (cluster != 0U) { + val |= ((uint64_t)cluster & CLUSTER_CSTATE_MASK) | + CLUSTER_CSTATE_UPDATE_BIT; + } /* update CCPLEX_CSTATE? */ - if (ccplex) - val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT | - CCPLEX_CSTATE_UPDATE_BIT; + if (ccplex != 0U) { + val |= (((uint64_t)ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) | + CCPLEX_CSTATE_UPDATE_BIT; + } /* update SYSTEM_CSTATE? */ - if (system) - val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) | - ((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) | - SYSTEM_CSTATE_UPDATE_BIT); + if (system != 0U) { + val |= (((uint64_t)system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) | + SYSTEM_CSTATE_UPDATE_BIT; + } /* update wake mask value? */ - if (update_wake_mask) + if (update_wake_mask != 0U) { val |= CSTATE_WAKE_MASK_UPDATE_BIT; + } /* set the wake mask */ - val &= CSTATE_WAKE_MASK_CLEAR; - val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT); + val |= ((uint64_t)wake_mask & CSTATE_WAKE_MASK_CLEAR) << CSTATE_WAKE_MASK_SHIFT; /* set the updated cstate info */ nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val); - - return 0; } -int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time) +/* + * Indices gives MTS the crossover point in TSC ticks for when it becomes + * no longer viable to enter the named state + * + * Type 0 : NVGDATA[0:31]: C6 Lower bound + * Type 1 : NVGDATA[0:31]: CC6 Lower bound + * Type 2 : NVGDATA[0:31]: CG7 Lower bound + */ +int32_t nvg_update_crossover_time(uint32_t type, uint32_t time) { - /* sanity check crossover type */ - if (type > TEGRA_ARI_CROSSOVER_CCP3_SC1) - return EINVAL; - - /* - * The crossover threshold limit types start from - * TEGRA_CROSSOVER_TYPE_C1_C6 to TEGRA_CROSSOVER_TYPE_CCP3_SC7. The - * command indices for updating the threshold can be generated - * by adding the type to the NVG_SET_THRESHOLD_CROSSOVER_C1_C6 - * command index. - */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C1_C6 + type, - (uint64_t)time); + int32_t ret = 0; + + switch (type) { + case TEGRA_NVG_CROSSOVER_C6: + nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND, + (uint64_t)time); + break; + + case TEGRA_NVG_CROSSOVER_CC6: + nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND, + (uint64_t)time); + break; + + case TEGRA_NVG_CROSSOVER_CG7: + nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND, + (uint64_t)time); + break; + + default: + ERROR("%s: unknown crossover type (%d)\n", __func__, type); + ret = EINVAL; + break; + } - return 0; + return ret; } -uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state) +/* + * These NVG calls allow ARM SW to access CSTATE statistical information + * + * NVGDATA[0:3]: SW(RW) Core/cluster/cg id + * NVGDATA[16:31]: SW(RW) Stat id + */ +int32_t nvg_set_cstate_stat_query_value(uint64_t data) { - /* sanity check state */ - if (state == 0) - return EINVAL; - - /* - * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES - * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for - * reading the threshold can be generated by adding the type to - * the NVG_CLEAR_CSTATE_STATS command index. - */ - nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state); + int32_t ret = 0; + + /* sanity check stat id */ + if (data > (uint64_t)NVG_STAT_QUERY_C7_RESIDENCY_SUM) { + ERROR("%s: unknown stat id (%d)\n", __func__, (uint32_t)data); + ret = EINVAL; + } else { + nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST, data); + } - return (int64_t)nvg_get_result(); + return ret; } -int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats) +/* + * The read-only value associated with the CSTATE_STAT_QUERY_REQUEST + * + * NVGDATA[0:63]: SW(R) Stat count + */ +uint64_t nvg_get_cstate_stat_query_value(void) { - uint64_t val; - - /* - * The only difference between a CSTATE_STATS_WRITE and - * CSTATE_STATS_READ is the usage of the 63:32 in the request. - * 63:32 are set to '0' for a read, while a write contains the - * actual stats value to be written. - */ - val = ((uint64_t)stats << MCE_CSTATE_STATS_TYPE_SHIFT) | state; - - /* - * The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES - * to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for - * reading the threshold can be generated by adding the type to - * the NVG_CLEAR_CSTATE_STATS command index. - */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state, val); + nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE); - return 0; + return (uint64_t)nvg_get_result(); } -int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) +/* + * Return a non-zero value if the CCPLEX is able to enter SC7 + * + * NVGDATA[0]: SW(R), Is allowed result + */ +int32_t nvg_is_sc7_allowed(void) { - /* This does not apply to the Denver cluster */ - return 0; + /* issue command to check if SC7 is allowed */ + nvg_set_request(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED); + + /* 1 = SC7 allowed, 0 = SC7 not allowed */ + return (int32_t)nvg_get_result(); } -int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time) +/* + * Wake an offlined logical core. Note that a core is offlined by entering + * a C-state where the WAKE_MASK is all 0. + * + * NVGDATA[0:3]: SW(W) logical core to online + */ +int32_t nvg_online_core(uint32_t core) { - uint64_t val; + int32_t ret = 0; - /* check for allowed power state */ - if (state != TEGRA_ARI_CORE_C0 && state != TEGRA_ARI_CORE_C1 && - state != TEGRA_ARI_CORE_C6 && state != TEGRA_ARI_CORE_C7) { - ERROR("%s: unknown cstate (%d)\n", __func__, state); - return EINVAL; + /* sanity check the core ID value */ + if (core > (uint32_t)PLATFORM_CORE_COUNT) { + ERROR("%s: unknown core id (%d)\n", __func__, core); + ret = EINVAL; + } else { + /* get a core online */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE, + (uint64_t)core & MCE_CORE_ID_MASK); } + return ret; +} + +/* + * Enables and controls the voltage/frequency hint for CC3. CC3 is disabled + * by default. + * + * NVGDATA[7:0] SW(RW) frequency request + * NVGDATA[31:31] SW(RW) enable bit + */ +int32_t nvg_cc3_ctrl(uint32_t freq, uint8_t enable) +{ + uint64_t val = 0; + /* - * Request format - - * 63:32 = wake time - * 31:0 = C-state for this core + * If the enable bit is cleared, Auto-CC3 will be disabled by setting + * the SW visible frequency request registers for all non + * floorswept cores valid independent of StandbyWFI and disabling + * the IDLE frequency request register. If set, Auto-CC3 + * will be enabled by setting the ARM SW visible frequency + * request registers for all non floorswept cores to be enabled by + * StandbyWFI or the equivalent signal, and always keeping the IDLE + * frequency request register enabled. */ - val = ((uint64_t)wake_time << MCE_SC7_WAKE_TIME_SHIFT) | - (state & MCE_SC7_ALLOWED_MASK); - - /* issue command to check if SC7 is allowed */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val); + if (enable != 0U) { + val = ((uint64_t)freq & MCE_AUTO_CC3_FREQ_MASK) | MCE_AUTO_CC3_ENABLE_BIT; + } + nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val); - /* 1 = SC7 allowed, 0 = SC7 not allowed */ - return !!nvg_get_result(); + return 0; } -int nvg_online_core(uint32_t ari_base, uint32_t core) +/* + * MC GSC (General Security Carveout) register values are expected to be + * changed by TrustZone ARM code after boot. + * + * NVGDATA[0:15] SW(R) GSC enun + */ +int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx) { - int cpu = read_mpidr() & MPIDR_CPU_MASK; - int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; - - /* sanity check code id */ - if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) { - ERROR("%s: unsupported core id (%d)\n", __func__, core); - return EINVAL; + int32_t ret = 0; + + /* sanity check GSC ID */ + if (gsc_idx > (uint32_t)TEGRA_NVG_GSC_VPR_IDX) { + ERROR("%s: unknown gsc_idx (%d)\n", __func__, gsc_idx); + ret = EINVAL; + } else { + nvg_set_request_data(TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC, + (uint64_t)gsc_idx); } - /* - * The Denver cluster has 2 CPUs only - 0, 1. - */ - if (impl == DENVER_IMPL && ((core == 2) || (core == 3))) { - ERROR("%s: unknown core id (%d)\n", __func__, core); - return EINVAL; - } + return ret; +} - /* get a core online */ - nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE, core & MCE_CORE_ID_MASK); +/* + * Cache clean operation for all CCPLEX caches. + * + * NVGDATA[0] cache_clean + */ +int32_t nvg_roc_clean_cache(void) +{ + nvg_set_request_data(TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL, + (uint64_t)CACHE_CLEAN_SET); return 0; } -int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable) +/* + * Cache clean and invalidate operation for all CCPLEX caches. + * + * NVGDATA[1] cache_clean_inval + */ +int32_t nvg_roc_flush_cache(void) { - int val; + nvg_set_request_data(TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL, + (uint64_t)CACHE_CLEAN_INVAL_SET); - /* - * If the enable bit is cleared, Auto-CC3 will be disabled by setting - * the SW visible voltage/frequency request registers for all non - * floorswept cores valid independent of StandbyWFI and disabling - * the IDLE voltage/frequency request register. If set, Auto-CC3 - * will be enabled by setting the ARM SW visible voltage/frequency - * request registers for all non floorswept cores to be enabled by - * StandbyWFI or the equivalent signal, and always keeping the IDLE - * voltage/frequency request register enabled. - */ - val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\ - ((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\ - (enable ? MCE_AUTO_CC3_ENABLE_BIT : 0)); + return 0; +} - nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val); +/* + * Cache clean and invalidate, clear TR-bit operation for all CCPLEX caches. + * + * NVGDATA[2] cache_clean_inval_tr + */ +int32_t nvg_roc_clean_cache_trbits(void) +{ + nvg_set_request_data(TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL, + (uint64_t)CACHE_CLEAN_INVAL_TR_SET); return 0; } + +/* + * Set the power state for a core + */ +int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time) +{ + int32_t ret = 0; + + /* check for allowed power state */ + if ((state != (uint32_t)TEGRA_NVG_CORE_C0) && + (state != (uint32_t)TEGRA_NVG_CORE_C1) && + (state != (uint32_t)TEGRA_NVG_CORE_C6) && + (state != (uint32_t)TEGRA_NVG_CORE_C7)) + { + ERROR("%s: unknown cstate (%d)\n", __func__, state); + ret = EINVAL; + } else { + /* time (TSC ticks) until the core is expected to get a wake event */ + nvg_set_wake_time(wake_time); + + /* set the core cstate */ + write_actlr_el1(state); + } + + return ret; +} diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c index 33c8e1b64a0da0a6bbcd5a856f07623416d341a6..f5e56b9b07f0ed17a5ac33c4a703f7fae04a1602 100644 --- a/plat/nvidia/tegra/soc/t194/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c @@ -59,7 +59,4 @@ void plat_secondary_setup(void) addr_low); mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV1_HI, addr_high); - - /* update reset vector address to the CCPLEX */ - mce_update_reset_vector(); } diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk index 8a61759b307d36289095a015f3d13a254d37edd7..b6bc442144861524007e29d31312cdc9f61445f4 100644 --- a/plat/nvidia/tegra/soc/t194/platform_t194.mk +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -55,6 +55,8 @@ BL31_SOURCES += lib/cpus/aarch64/denver.S \ ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \ ${COMMON_DIR}/drivers/smmu/smmu.c \ ${SOC_DIR}/drivers/mce/mce.c \ + ${SOC_DIR}/drivers/mce/nvg.c \ + ${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \ ${SOC_DIR}/plat_psci_handlers.c \ ${SOC_DIR}/plat_setup.c \ ${SOC_DIR}/plat_secondary.c \