mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-19 19:14:28 +00:00
Tegra194: Enable MCE driver
This patch enable MCE driver for T19x SoC. The MCE driver takes care of the communication with the MCE firmware to achieve: - Cold boot - Warm boot - Core/Cluster/System Power management - Custom MCE requests Change-Id: I75854c0b649a691e9b244d9ed9fc1c19743e3e8d Signed-off-by: Steven Kao <skao@nvidia.com>
This commit is contained in:
parent
5660eebf39
commit
9808032cd9
6 changed files with 688 additions and 409 deletions
|
@ -14,143 +14,61 @@
|
||||||
* Macros to prepare CSTATE info request
|
* Macros to prepare CSTATE info request
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
/* Description of the parameters for UPDATE_CSTATE_INFO request */
|
/* Description of the parameters for UPDATE_CSTATE_INFO request */
|
||||||
#define CLUSTER_CSTATE_MASK 0x7
|
#define CLUSTER_CSTATE_MASK 0x7UL
|
||||||
#define CLUSTER_CSTATE_SHIFT 0
|
#define CLUSTER_CSTATE_SHIFT 0X0UL
|
||||||
#define CLUSTER_CSTATE_UPDATE_BIT (1 << 7)
|
#define CLUSTER_CSTATE_UPDATE_BIT (1UL << 7)
|
||||||
#define CCPLEX_CSTATE_MASK 0x3
|
#define CCPLEX_CSTATE_MASK 0x3UL
|
||||||
#define CCPLEX_CSTATE_SHIFT 8
|
#define CCPLEX_CSTATE_SHIFT 8UL
|
||||||
#define CCPLEX_CSTATE_UPDATE_BIT (1 << 15)
|
#define CCPLEX_CSTATE_UPDATE_BIT (1UL << 15)
|
||||||
#define SYSTEM_CSTATE_MASK 0xF
|
#define SYSTEM_CSTATE_MASK 0xFUL
|
||||||
#define SYSTEM_CSTATE_SHIFT 16
|
#define SYSTEM_CSTATE_SHIFT 16UL
|
||||||
#define SYSTEM_CSTATE_FORCE_UPDATE_SHIFT 22
|
#define SYSTEM_CSTATE_UPDATE_BIT (1UL << 23)
|
||||||
#define SYSTEM_CSTATE_FORCE_UPDATE_BIT (1 << 22)
|
#define CSTATE_WAKE_MASK_UPDATE_BIT (1UL << 31)
|
||||||
#define SYSTEM_CSTATE_UPDATE_BIT (1 << 23)
|
#define CSTATE_WAKE_MASK_SHIFT 32UL
|
||||||
#define CSTATE_WAKE_MASK_UPDATE_BIT (1 << 31)
|
#define CSTATE_WAKE_MASK_CLEAR 0xFFFFFFFFUL
|
||||||
#define CSTATE_WAKE_MASK_SHIFT 32
|
|
||||||
#define CSTATE_WAKE_MASK_CLEAR 0xFFFFFFFF
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Auto-CC3 control macros
|
* Auto-CC3 control macros
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define MCE_AUTO_CC3_FREQ_MASK 0x1FF
|
#define MCE_AUTO_CC3_FREQ_MASK 0xFFUL
|
||||||
#define MCE_AUTO_CC3_FREQ_SHIFT 0
|
#define MCE_AUTO_CC3_FREQ_SHIFT 0UL
|
||||||
#define MCE_AUTO_CC3_VTG_MASK 0x7F
|
#define MCE_AUTO_CC3_ENABLE_BIT (1UL << 31)
|
||||||
#define MCE_AUTO_CC3_VTG_SHIFT 16
|
|
||||||
#define MCE_AUTO_CC3_ENABLE_BIT (1 << 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_CORE_ID_MASK 0xFUL
|
||||||
#define MCE_SC7_WAKE_TIME_SHIFT 32
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Macros for 'read/write ctats' commands
|
* Cache control macros
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define MCE_CSTATE_STATS_TYPE_SHIFT 32
|
#define CACHE_CLEAN_SET (1UL << 0)
|
||||||
#define MCE_CSTATE_WRITE_DATA_LO_MASK 0xF
|
#define CACHE_CLEAN_INVAL_SET (1UL << 1)
|
||||||
|
#define CACHE_CLEAN_INVAL_TR_SET (1UL << 2)
|
||||||
/*******************************************************************************
|
|
||||||
* 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
|
|
||||||
|
|
||||||
/* declarations for NVG handler functions */
|
/* declarations for NVG handler functions */
|
||||||
int nvg_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time);
|
uint64_t nvg_get_version(void);
|
||||||
int nvg_update_cstate_info(uint32_t ari_base, uint32_t cluster, uint32_t ccplex,
|
int32_t nvg_enable_power_perf_mode(void);
|
||||||
uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
|
int32_t nvg_disable_power_perf_mode(void);
|
||||||
uint8_t update_wake_mask);
|
int32_t nvg_enable_power_saver_modes(void);
|
||||||
int nvg_update_crossover_time(uint32_t ari_base, uint32_t type, uint32_t time);
|
int32_t nvg_disable_power_saver_modes(void);
|
||||||
uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state);
|
void nvg_set_wake_time(uint32_t wake_time);
|
||||||
int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t val);
|
void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex,
|
||||||
int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time);
|
uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask);
|
||||||
int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time);
|
int32_t nvg_update_crossover_time(uint32_t type, uint32_t time);
|
||||||
int nvg_online_core(uint32_t ari_base, uint32_t core);
|
int32_t nvg_set_cstate_stat_query_value(uint64_t data);
|
||||||
int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable);
|
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__ */
|
#endif /* __MCE_PRIVATE_H__ */
|
||||||
|
|
275
plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
Normal file
275
plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h
Normal file
|
@ -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
|
|
@ -15,21 +15,21 @@
|
||||||
#include <mce.h>
|
#include <mce.h>
|
||||||
#include <mce_private.h>
|
#include <mce_private.h>
|
||||||
#include <mmio.h>
|
#include <mmio.h>
|
||||||
|
#include <platform_def.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <t194_nvg.h>
|
||||||
#include <tegra_def.h>
|
#include <tegra_def.h>
|
||||||
#include <tegra_platform.h>
|
#include <tegra_platform.h>
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Common handler for all MCE commands
|
* 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 arg2)
|
||||||
{
|
{
|
||||||
uint64_t ret64 = 0, arg3, arg4, arg5;
|
uint64_t ret64 = 0, arg3, arg4, arg5;
|
||||||
int ret = 0;
|
int32_t ret = 0;
|
||||||
mca_cmd_t mca_cmd;
|
|
||||||
uncore_perfmon_req_t req;
|
|
||||||
cpu_context_t *ctx = cm_get_context(NON_SECURE);
|
cpu_context_t *ctx = cm_get_context(NON_SECURE);
|
||||||
gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
|
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) {
|
switch (cmd) {
|
||||||
case MCE_CMD_ENTER_CSTATE:
|
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;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_UPDATE_CSTATE_INFO:
|
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
|
* get the parameters required for the update cstate info
|
||||||
* command
|
* command
|
||||||
*/
|
*/
|
||||||
arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4);
|
arg3 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4));
|
||||||
arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5);
|
arg4 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5));
|
||||||
arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6);
|
arg5 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6));
|
||||||
|
|
||||||
/* NVG */
|
/* 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, ((uint64_t)CTX_GPREG_X4), (arg3));
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, arg4);
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5), (arg4));
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, arg5);
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6), (arg5));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_UPDATE_CROSSOVER_TIME:
|
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;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_READ_CSTATE_STATS:
|
case MCE_CMD_READ_CSTATE_STATS:
|
||||||
/* NVG */
|
ret64 = nvg_get_cstate_stat_query_value();
|
||||||
|
|
||||||
/* update context to return cstate stats value */
|
/* update context to return cstate stats value */
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64);
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64));
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64);
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_WRITE_CSTATE_STATS:
|
case MCE_CMD_WRITE_CSTATE_STATS:
|
||||||
/* NVG */
|
ret = nvg_set_cstate_stat_query_value(arg0);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MCE_CMD_IS_CCX_ALLOWED:
|
|
||||||
/* NVG */
|
|
||||||
|
|
||||||
/* update context to return CCx status value */
|
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X1, ret);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_IS_SC7_ALLOWED:
|
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 */
|
/* update context to return SC7 status value */
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X1, ret);
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), ((uint64_t)ret));
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X3, ret);
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X3), ((uint64_t)ret));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_ONLINE_CORE:
|
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;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_CC3_CTRL:
|
case MCE_CMD_CC3_CTRL:
|
||||||
/* NVG */
|
ret = nvg_cc3_ctrl((uint32_t)arg0, (uint8_t)arg2);
|
||||||
|
if (ret < 0) {
|
||||||
break;
|
ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret);
|
||||||
|
}
|
||||||
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);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_READ_VERSIONS:
|
case MCE_CMD_READ_VERSIONS:
|
||||||
/* get the MCE firmware version */
|
/* get the MCE firmware version */
|
||||||
|
ret64 = nvg_get_version();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* version = minor(63:32) | major(31:0). Update context
|
* version = minor(63:32) | major(31:0). Update context
|
||||||
* to return major and minor version number.
|
* to return major and minor version number.
|
||||||
*/
|
*/
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint32_t)ret64);
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64 & (uint64_t)0xFFFF));
|
||||||
write_ctx_reg(gp_regs, CTX_GPREG_X2, (uint32_t)(ret64 >> 32));
|
write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64 >> 32));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_ENUM_FEATURES:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MCE_CMD_ROC_FLUSH_CACHE_TRBITS:
|
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;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_ROC_FLUSH_CACHE:
|
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;
|
break;
|
||||||
|
|
||||||
case MCE_CMD_ROC_CLEAN_CACHE:
|
case MCE_CMD_ROC_CLEAN_CACHE:
|
||||||
/* NVG */
|
ret = nvg_roc_clean_cache();
|
||||||
|
if (ret < 0) {
|
||||||
break;
|
ERROR("%s: clean cache failed(%d)\n", __func__, ret);
|
||||||
|
}
|
||||||
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 */
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ERROR("unknown MCE command (%lld)\n", cmd);
|
ERROR("unknown MCE command (%lld)\n", cmd);
|
||||||
return EINVAL;
|
ret = EINVAL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
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
|
* 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
|
* 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
|
* 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();
|
return nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_GSC_TZRAM);
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -262,7 +199,8 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx)
|
||||||
void mce_update_cstate_info(mce_cstate_info_t *cstate)
|
void mce_update_cstate_info(mce_cstate_info_t *cstate)
|
||||||
{
|
{
|
||||||
/* issue the UPDATE_CSTATE_INFO request */
|
/* 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.
|
* 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;
|
return;
|
||||||
|
}
|
||||||
/* get a pointer to the CPU's arch_mce_ops_t struct */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the MCE firmware version and extract the major and minor
|
* Read the MCE firmware version and extract the major and minor
|
||||||
* version fields
|
* version fields
|
||||||
*/
|
*/
|
||||||
version = 0;
|
version = nvg_get_version();
|
||||||
major = (uint32_t)version;
|
minor = (uint32_t)version;
|
||||||
minor = (uint32_t)(version >> 32);
|
major = (uint32_t)(version >> 32);
|
||||||
|
|
||||||
INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
|
INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
|
||||||
0, 0);
|
0, 0);
|
||||||
|
@ -297,12 +235,12 @@ void mce_verify_firmware_version(void)
|
||||||
* Verify that the MCE firmware version and the interface header
|
* Verify that the MCE firmware version and the interface header
|
||||||
* match
|
* match
|
||||||
*/
|
*/
|
||||||
if (major != 0) {
|
if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
|
||||||
ERROR("MCE major version mismatch\n");
|
ERROR("MCE major version mismatch\n");
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minor < 0) {
|
if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
|
||||||
ERROR("MCE minor version mismatch\n");
|
ERROR("MCE minor version mismatch\n");
|
||||||
panic();
|
panic();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,207 +8,356 @@
|
||||||
#include <arch_helpers.h>
|
#include <arch_helpers.h>
|
||||||
#include <common/debug.h>
|
#include <common/debug.h>
|
||||||
#include <denver.h>
|
#include <denver.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <lib/mmio.h>
|
#include <lib/mmio.h>
|
||||||
#include <mce_private.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_data(uint64_t req, uint64_t data);
|
||||||
extern void nvg_set_request(uint64_t req);
|
extern void nvg_set_request(uint64_t req);
|
||||||
extern uint64_t nvg_get_result(void);
|
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 */
|
nvg_set_request(TEGRA_NVG_CHANNEL_VERSION);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* time (TSC ticks) until the core is expected to get a wake event */
|
return (uint64_t)nvg_get_result();
|
||||||
nvg_set_request_data(TEGRA_NVG_CHANNEL_WAKE_TIME, wake_time);
|
}
|
||||||
|
|
||||||
/* 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;
|
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
|
* This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and
|
||||||
* SYSTEM_CSTATE values.
|
* 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,
|
void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex,
|
||||||
uint32_t system, uint8_t sys_state_force, uint32_t wake_mask,
|
uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask)
|
||||||
uint8_t update_wake_mask)
|
|
||||||
{
|
{
|
||||||
uint64_t val = 0;
|
uint64_t val = 0;
|
||||||
|
|
||||||
/* update CLUSTER_CSTATE? */
|
/* update CLUSTER_CSTATE? */
|
||||||
if (cluster)
|
if (cluster != 0U) {
|
||||||
val |= (cluster & CLUSTER_CSTATE_MASK) |
|
val |= ((uint64_t)cluster & CLUSTER_CSTATE_MASK) |
|
||||||
CLUSTER_CSTATE_UPDATE_BIT;
|
CLUSTER_CSTATE_UPDATE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
/* update CCPLEX_CSTATE? */
|
/* update CCPLEX_CSTATE? */
|
||||||
if (ccplex)
|
if (ccplex != 0U) {
|
||||||
val |= (ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT |
|
val |= (((uint64_t)ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) |
|
||||||
CCPLEX_CSTATE_UPDATE_BIT;
|
CCPLEX_CSTATE_UPDATE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
/* update SYSTEM_CSTATE? */
|
/* update SYSTEM_CSTATE? */
|
||||||
if (system)
|
if (system != 0U) {
|
||||||
val |= ((system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
|
val |= (((uint64_t)system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) |
|
||||||
((sys_state_force << SYSTEM_CSTATE_FORCE_UPDATE_SHIFT) |
|
SYSTEM_CSTATE_UPDATE_BIT;
|
||||||
SYSTEM_CSTATE_UPDATE_BIT);
|
}
|
||||||
|
|
||||||
/* update wake mask value? */
|
/* update wake mask value? */
|
||||||
if (update_wake_mask)
|
if (update_wake_mask != 0U) {
|
||||||
val |= CSTATE_WAKE_MASK_UPDATE_BIT;
|
val |= CSTATE_WAKE_MASK_UPDATE_BIT;
|
||||||
|
}
|
||||||
|
|
||||||
/* set the wake mask */
|
/* set the wake mask */
|
||||||
val &= CSTATE_WAKE_MASK_CLEAR;
|
val |= ((uint64_t)wake_mask & CSTATE_WAKE_MASK_CLEAR) << CSTATE_WAKE_MASK_SHIFT;
|
||||||
val |= ((uint64_t)wake_mask << CSTATE_WAKE_MASK_SHIFT);
|
|
||||||
|
|
||||||
/* set the updated cstate info */
|
/* set the updated cstate info */
|
||||||
nvg_set_request_data(TEGRA_NVG_CHANNEL_CSTATE_INFO, val);
|
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 */
|
int32_t ret = 0;
|
||||||
if (type > TEGRA_ARI_CROSSOVER_CCP3_SC1)
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
/*
|
switch (type) {
|
||||||
* The crossover threshold limit types start from
|
case TEGRA_NVG_CROSSOVER_C6:
|
||||||
* TEGRA_CROSSOVER_TYPE_C1_C6 to TEGRA_CROSSOVER_TYPE_CCP3_SC7. The
|
nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND,
|
||||||
* command indices for updating the threshold can be generated
|
(uint64_t)time);
|
||||||
* by adding the type to the NVG_SET_THRESHOLD_CROSSOVER_C1_C6
|
break;
|
||||||
* command index.
|
|
||||||
*/
|
|
||||||
nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_C1_C6 + type,
|
|
||||||
(uint64_t)time);
|
|
||||||
|
|
||||||
return 0;
|
case TEGRA_NVG_CROSSOVER_CC6:
|
||||||
}
|
nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND,
|
||||||
|
(uint64_t)time);
|
||||||
|
break;
|
||||||
|
|
||||||
uint64_t nvg_read_cstate_stats(uint32_t ari_base, uint32_t state)
|
case TEGRA_NVG_CROSSOVER_CG7:
|
||||||
{
|
nvg_set_request_data(TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND,
|
||||||
/* sanity check state */
|
(uint64_t)time);
|
||||||
if (state == 0)
|
break;
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
/*
|
default:
|
||||||
* The cstate types start from NVG_READ_CSTATE_STATS_SC7_ENTRIES
|
ERROR("%s: unknown crossover type (%d)\n", __func__, type);
|
||||||
* to NVG_GET_LAST_CSTATE_ENTRY_A57_3. The command indices for
|
ret = EINVAL;
|
||||||
* reading the threshold can be generated by adding the type to
|
break;
|
||||||
* the NVG_CLEAR_CSTATE_STATS command index.
|
|
||||||
*/
|
|
||||||
nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STATS_CLEAR + state);
|
|
||||||
|
|
||||||
return (int64_t)nvg_get_result();
|
|
||||||
}
|
|
||||||
|
|
||||||
int nvg_write_cstate_stats(uint32_t ari_base, uint32_t state, uint32_t stats)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nvg_is_ccx_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
|
|
||||||
{
|
|
||||||
/* This does not apply to the Denver cluster */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int nvg_is_sc7_allowed(uint32_t ari_base, uint32_t state, uint32_t wake_time)
|
|
||||||
{
|
|
||||||
uint64_t val;
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
return ret;
|
||||||
* Request format -
|
}
|
||||||
* 63:32 = wake time
|
|
||||||
* 31:0 = C-state for this core
|
|
||||||
*/
|
|
||||||
val = ((uint64_t)wake_time << MCE_SC7_WAKE_TIME_SHIFT) |
|
|
||||||
(state & MCE_SC7_ALLOWED_MASK);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
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 ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
nvg_set_request(TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE);
|
||||||
|
|
||||||
|
return (uint64_t)nvg_get_result();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
/* issue command to check if SC7 is allowed */
|
/* issue command to check if SC7 is allowed */
|
||||||
nvg_set_request_data(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED, val);
|
nvg_set_request(TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED);
|
||||||
|
|
||||||
/* 1 = SC7 allowed, 0 = SC7 not allowed */
|
/* 1 = SC7 allowed, 0 = SC7 not allowed */
|
||||||
return !!nvg_get_result();
|
return (int32_t)nvg_get_result();
|
||||||
}
|
}
|
||||||
|
|
||||||
int nvg_online_core(uint32_t ari_base, uint32_t core)
|
/*
|
||||||
|
* 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)
|
||||||
{
|
{
|
||||||
int cpu = read_mpidr() & MPIDR_CPU_MASK;
|
int32_t ret = 0;
|
||||||
int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
|
|
||||||
|
|
||||||
/* sanity check code id */
|
/* sanity check the core ID value */
|
||||||
if ((core >= MCE_CORE_ID_MAX) || (cpu == core)) {
|
if (core > (uint32_t)PLATFORM_CORE_COUNT) {
|
||||||
ERROR("%s: unsupported core id (%d)\n", __func__, core);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
ERROR("%s: unknown core id (%d)\n", __func__, core);
|
||||||
return EINVAL;
|
ret = EINVAL;
|
||||||
|
} else {
|
||||||
|
/* get a core online */
|
||||||
|
nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE,
|
||||||
|
(uint64_t)core & MCE_CORE_ID_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get a core online */
|
return ret;
|
||||||
nvg_set_request_data(TEGRA_NVG_CHANNEL_ONLINE_CORE, core & MCE_CORE_ID_MASK);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int nvg_cc3_ctrl(uint32_t ari_base, uint32_t freq, uint32_t volt, uint8_t enable)
|
/*
|
||||||
|
* 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)
|
||||||
{
|
{
|
||||||
int val;
|
uint64_t val = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the enable bit is cleared, Auto-CC3 will be disabled by setting
|
* If the enable bit is cleared, Auto-CC3 will be disabled by setting
|
||||||
* the SW visible voltage/frequency request registers for all non
|
* the SW visible frequency request registers for all non
|
||||||
* floorswept cores valid independent of StandbyWFI and disabling
|
* floorswept cores valid independent of StandbyWFI and disabling
|
||||||
* the IDLE voltage/frequency request register. If set, Auto-CC3
|
* the IDLE frequency request register. If set, Auto-CC3
|
||||||
* will be enabled by setting the ARM SW visible voltage/frequency
|
* will be enabled by setting the ARM SW visible frequency
|
||||||
* request registers for all non floorswept cores to be enabled by
|
* request registers for all non floorswept cores to be enabled by
|
||||||
* StandbyWFI or the equivalent signal, and always keeping the IDLE
|
* StandbyWFI or the equivalent signal, and always keeping the IDLE
|
||||||
* voltage/frequency request register enabled.
|
* frequency request register enabled.
|
||||||
*/
|
*/
|
||||||
val = (((freq & MCE_AUTO_CC3_FREQ_MASK) << MCE_AUTO_CC3_FREQ_SHIFT) |\
|
if (enable != 0U) {
|
||||||
((volt & MCE_AUTO_CC3_VTG_MASK) << MCE_AUTO_CC3_VTG_SHIFT) |\
|
val = ((uint64_t)freq & MCE_AUTO_CC3_FREQ_MASK) | MCE_AUTO_CC3_ENABLE_BIT;
|
||||||
(enable ? MCE_AUTO_CC3_ENABLE_BIT : 0));
|
}
|
||||||
|
|
||||||
nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val);
|
nvg_set_request_data(TEGRA_NVG_CHANNEL_CC3_CTRL, val);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cache clean and invalidate operation for all CCPLEX caches.
|
||||||
|
*
|
||||||
|
* NVGDATA[1] cache_clean_inval
|
||||||
|
*/
|
||||||
|
int32_t nvg_roc_flush_cache(void)
|
||||||
|
{
|
||||||
|
nvg_set_request_data(TEGRA_NVG_CHANNEL_CCPLEX_CACHE_INVAL,
|
||||||
|
(uint64_t)CACHE_CLEAN_INVAL_SET);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
|
@ -59,7 +59,4 @@ void plat_secondary_setup(void)
|
||||||
addr_low);
|
addr_low);
|
||||||
mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV1_HI,
|
mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV1_HI,
|
||||||
addr_high);
|
addr_high);
|
||||||
|
|
||||||
/* update reset vector address to the CCPLEX */
|
|
||||||
mce_update_reset_vector();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,8 @@ BL31_SOURCES += lib/cpus/aarch64/denver.S \
|
||||||
${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
|
${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
|
||||||
${COMMON_DIR}/drivers/smmu/smmu.c \
|
${COMMON_DIR}/drivers/smmu/smmu.c \
|
||||||
${SOC_DIR}/drivers/mce/mce.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_psci_handlers.c \
|
||||||
${SOC_DIR}/plat_setup.c \
|
${SOC_DIR}/plat_setup.c \
|
||||||
${SOC_DIR}/plat_secondary.c \
|
${SOC_DIR}/plat_secondary.c \
|
||||||
|
|
Loading…
Add table
Reference in a new issue