blob: 0a6515e1ce1a4f48bb15b053cca8258e9682bcb0 [file] [log] [blame]
/*
* Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch.h>
#include <arch_helpers.h>
#include <assert.h>
#include <common/bl_common.h>
#include <context.h>
#include <lib/el3_runtime/context_mgmt.h>
#include <common/debug.h>
#include <denver.h>
#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
******************************************************************************/
int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
uint64_t arg2)
{
uint64_t ret64 = 0, arg3, arg4, arg5;
int32_t ret = 0;
cpu_context_t *ctx = cm_get_context(NON_SECURE);
gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
assert(ctx);
assert(gp_regs);
switch (cmd) {
case MCE_CMD_ENTER_CSTATE:
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:
/*
* get the parameters required for the update cstate info
* command
*/
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, ((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:
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:
ret64 = nvg_get_cstate_stat_query_value();
/* update context to return cstate stats value */
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:
ret = nvg_set_cstate_stat_query_value(arg0);
break;
case MCE_CMD_IS_SC7_ALLOWED:
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, ((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:
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:
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, ((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_ROC_FLUSH_CACHE_TRBITS:
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:
ret = nvg_roc_flush_cache();
if (ret < 0) {
ERROR("%s: flush cache failed(%d)\n", __func__, ret);
}
break;
case MCE_CMD_ROC_CLEAN_CACHE:
ret = nvg_roc_clean_cache();
if (ret < 0) {
ERROR("%s: clean cache failed(%d)\n", __func__, ret);
}
break;
default:
ERROR("unknown MCE command (%llu)\n", cmd);
ret = EINVAL;
break;
}
return ret;
}
/*******************************************************************************
* Handler to update carveout values for Video Memory Carveout region
******************************************************************************/
int32_t mce_update_gsc_videomem(void)
{
return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_VPR_IDX);
}
/*******************************************************************************
* Handler to update carveout values for TZDRAM aperture
******************************************************************************/
int32_t mce_update_gsc_tzdram(void)
{
return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZ_DRAM_IDX);
}
/*******************************************************************************
* Handler to update carveout values for TZ SysRAM aperture
******************************************************************************/
int32_t mce_update_gsc_tzram(void)
{
return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZRAM);
}
/*******************************************************************************
* Handler to issue the UPDATE_CSTATE_INFO request
******************************************************************************/
void mce_update_cstate_info(const mce_cstate_info_t *cstate)
{
/* issue the UPDATE_CSTATE_INFO request */
nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
cstate->wake_mask, cstate->update_wake_mask);
}
/*******************************************************************************
* Handler to read the MCE firmware version and check if it is compatible
* with interface header the BL3-1 was compiled against
******************************************************************************/
void mce_verify_firmware_version(void)
{
uint64_t version;
uint32_t major, minor;
/*
* MCE firmware is not running on simulation platforms.
*/
if ((tegra_platform_is_linsim() == 1U) ||
(tegra_platform_is_virt_dev_kit() == 1U) ||
(tegra_platform_is_qt() == 1U)) {
return;
}
/*
* Read the MCE firmware version and extract the major and minor
* version fields
*/
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);
/*
* Verify that the MCE firmware version and the interface header
* match
*/
if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
ERROR("MCE major version mismatch\n");
panic();
}
if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
ERROR("MCE minor version mismatch\n");
panic();
}
}