Merge pull request #884 from vwadekar/tegra186-platform-support-v3
Tegra186 platform support v3
This commit is contained in:
commit
82720675b9
|
@ -38,6 +38,7 @@
|
|||
#include <smmu.h>
|
||||
#include <string.h>
|
||||
#include <tegra_def.h>
|
||||
#include <tegra_platform.h>
|
||||
#include <xlat_tables.h>
|
||||
|
||||
#define TEGRA_GPU_RESET_REG_OFFSET 0x30
|
||||
|
@ -495,7 +496,6 @@ void tegra_memctrl_setup(void)
|
|||
uint32_t num_overrides = sizeof(streamid_overrides) / sizeof(uint32_t);
|
||||
uint32_t num_sec_cfgs = sizeof(sec_cfgs) / sizeof(mc_streamid_security_cfg_t);
|
||||
uint32_t num_txn_overrides = sizeof(mc_override_cfgs) / sizeof(mc_txn_override_cfg_t);
|
||||
uint32_t chip_minor, chip_major;
|
||||
int i;
|
||||
|
||||
INFO("Tegra Memory Controller (v2)\n");
|
||||
|
@ -543,12 +543,8 @@ void tegra_memctrl_setup(void)
|
|||
/*
|
||||
* Set the MC_TXN_OVERRIDE registers for write clients.
|
||||
*/
|
||||
chip_major = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >>
|
||||
MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK;
|
||||
chip_minor = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >>
|
||||
MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK;
|
||||
|
||||
if ((chip_major == 0) || (chip_major > 0 && chip_minor == 1)) {
|
||||
if (!tegra_platform_is_silicon() ||
|
||||
(tegra_platform_is_silicon() && tegra_get_chipid_minor() == 1)) {
|
||||
|
||||
/* GPU and NVENC settings for rev. A01 */
|
||||
val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
|
||||
|
@ -641,33 +637,55 @@ void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
|
|||
*/
|
||||
void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
|
||||
{
|
||||
uint64_t tzram_end = phys_base + size_in_bytes - 1;
|
||||
uint32_t index;
|
||||
uint32_t total_128kb_blocks = size_in_bytes >> 17;
|
||||
uint32_t residual_4kb_blocks = (size_in_bytes & 0x1FFFF) >> 12;
|
||||
uint32_t val;
|
||||
|
||||
/*
|
||||
* Check if the TZRAM is locked already.
|
||||
* Reset the access configuration registers to restrict access
|
||||
* to the TZRAM aperture
|
||||
*/
|
||||
if (tegra_mc_read_32(MC_TZRAM_REG_CTRL) == DISABLE_TZRAM_ACCESS)
|
||||
return;
|
||||
for (index = MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0;
|
||||
index <= MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5;
|
||||
index += 4)
|
||||
tegra_mc_write_32(index, 0);
|
||||
|
||||
/*
|
||||
* Setup the Memory controller to allow only secure accesses to
|
||||
* the TZRAM carveout
|
||||
* Allow CPU read/write access to the aperture
|
||||
*/
|
||||
INFO("Configuring TrustZone RAM (SysRAM) Memory Carveout\n");
|
||||
tegra_mc_write_32(MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1,
|
||||
TZRAM_CARVEOUT_CPU_WRITE_ACCESS_BIT |
|
||||
TZRAM_CARVEOUT_CPU_READ_ACCESS_BIT);
|
||||
|
||||
/* Program the base and end values */
|
||||
tegra_mc_write_32(MC_TZRAM_BASE, (uint32_t)phys_base);
|
||||
tegra_mc_write_32(MC_TZRAM_END, (uint32_t)tzram_end);
|
||||
/*
|
||||
* Set the TZRAM base. TZRAM base must be 4k aligned, at least.
|
||||
*/
|
||||
assert(!(phys_base & 0xFFF));
|
||||
tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base);
|
||||
tegra_mc_write_32(MC_TZRAM_BASE_HI,
|
||||
(uint32_t)(phys_base >> 32) & TZRAM_BASE_HI_MASK);
|
||||
|
||||
/* Extract the high address bits from the base/end values */
|
||||
val = (uint32_t)(phys_base >> 32) & TZRAM_ADDR_HI_BITS_MASK;
|
||||
val |= (((uint32_t)(tzram_end >> 32) & TZRAM_ADDR_HI_BITS_MASK) <<
|
||||
TZRAM_END_HI_BITS_SHIFT);
|
||||
tegra_mc_write_32(MC_TZRAM_HI_ADDR_BITS, val);
|
||||
/*
|
||||
* Set the TZRAM size
|
||||
*
|
||||
* total size = (number of 128KB blocks) + (number of remaining 4KB
|
||||
* blocks)
|
||||
*
|
||||
*/
|
||||
val = (residual_4kb_blocks << TZRAM_SIZE_RANGE_4KB_SHIFT) |
|
||||
total_128kb_blocks;
|
||||
tegra_mc_write_32(MC_TZRAM_SIZE, val);
|
||||
|
||||
/* Disable further writes to the TZRAM setup registers */
|
||||
tegra_mc_write_32(MC_TZRAM_REG_CTRL, DISABLE_TZRAM_ACCESS);
|
||||
/*
|
||||
* Lock the configuration settings by disabling TZ-only lock
|
||||
* and locking the configuration against any future changes
|
||||
* at all.
|
||||
*/
|
||||
val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
|
||||
val &= ~TZRAM_ENABLE_TZ_LOCK_BIT;
|
||||
val |= TZRAM_LOCK_CFG_SETTINGS_BIT;
|
||||
tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
|
||||
|
||||
/*
|
||||
* MCE propogates the security configuration values across the
|
||||
|
|
|
@ -350,7 +350,7 @@ typedef struct mc_streamid_security_cfg {
|
|||
.override_enable = OVERRIDE_ ## access \
|
||||
}
|
||||
|
||||
#endif /* __ASSMEBLY__ */
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
/*******************************************************************************
|
||||
* TZDRAM carveout configuration registers
|
||||
|
@ -367,15 +367,35 @@ typedef struct mc_streamid_security_cfg {
|
|||
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
|
||||
|
||||
/*******************************************************************************
|
||||
* TZRAM carveout configuration registers
|
||||
* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers
|
||||
******************************************************************************/
|
||||
#define MC_TZRAM_BASE 0x1850
|
||||
#define MC_TZRAM_END 0x1854
|
||||
#define MC_TZRAM_HI_ADDR_BITS 0x1588
|
||||
#define TZRAM_ADDR_HI_BITS_MASK 0x3
|
||||
#define TZRAM_END_HI_BITS_SHIFT 8
|
||||
#define MC_TZRAM_REG_CTRL 0x185c
|
||||
#define DISABLE_TZRAM_ACCESS 1
|
||||
#define MC_TZRAM_BASE_LO 0x2194
|
||||
#define TZRAM_BASE_LO_SHIFT 12
|
||||
#define TZRAM_BASE_LO_MASK 0xFFFFF
|
||||
#define MC_TZRAM_BASE_HI 0x2198
|
||||
#define TZRAM_BASE_HI_SHIFT 0
|
||||
#define TZRAM_BASE_HI_MASK 3
|
||||
#define MC_TZRAM_SIZE 0x219C
|
||||
#define TZRAM_SIZE_RANGE_4KB_SHIFT 27
|
||||
|
||||
#define MC_TZRAM_CARVEOUT_CFG 0x2190
|
||||
#define TZRAM_LOCK_CFG_SETTINGS_BIT (1 << 1)
|
||||
#define TZRAM_ENABLE_TZ_LOCK_BIT (1 << 0)
|
||||
#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0 0x21A0
|
||||
#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1 0x21A4
|
||||
#define TZRAM_CARVEOUT_CPU_WRITE_ACCESS_BIT (1 << 25)
|
||||
#define TZRAM_CARVEOUT_CPU_READ_ACCESS_BIT (1 << 7)
|
||||
#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG2 0x21A8
|
||||
#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG3 0x21AC
|
||||
#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG4 0x21B0
|
||||
#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG5 0x21B4
|
||||
|
||||
#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS0 0x21B8
|
||||
#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS1 0x21BC
|
||||
#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS2 0x21C0
|
||||
#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS3 0x21C4
|
||||
#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS4 0x21C8
|
||||
#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5 0x21CC
|
||||
|
||||
/*******************************************************************************
|
||||
* Memory Controller Reset Control registers
|
||||
|
|
|
@ -599,9 +599,16 @@
|
|||
* SMMU Global Secure Aux. Configuration Register
|
||||
******************************************************************************/
|
||||
#define SMMU_GSR0_SECURE_ACR 0x10
|
||||
#define SMMU_GNSR_ACR (SMMU_GSR0_SECURE_ACR + 0x400)
|
||||
#define SMMU_GSR0_PGSIZE_SHIFT 16
|
||||
#define SMMU_GSR0_PGSIZE_4K (0 << SMMU_GSR0_PGSIZE_SHIFT)
|
||||
#define SMMU_GSR0_PGSIZE_64K (1 << SMMU_GSR0_PGSIZE_SHIFT)
|
||||
#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1 << 26)
|
||||
|
||||
/*******************************************************************************
|
||||
* SMMU Global Aux. Control Register
|
||||
******************************************************************************/
|
||||
#define SMMU_CBn_ACTLR_CPRE_BIT (1 << 1)
|
||||
|
||||
/*******************************************************************************
|
||||
* SMMU configuration constants
|
||||
|
|
|
@ -76,10 +76,6 @@
|
|||
******************************************************************************/
|
||||
#define TEGRA_MISC_BASE 0x00100000
|
||||
#define HARDWARE_REVISION_OFFSET 0x4
|
||||
#define MAJOR_VERSION_SHIFT 0x4
|
||||
#define MAJOR_VERSION_MASK 0xF
|
||||
#define MINOR_VERSION_SHIFT 0x10
|
||||
#define MINOR_VERSION_MASK 0xF
|
||||
|
||||
#define MISCREG_PFCFG 0x200C
|
||||
|
||||
|
@ -105,6 +101,13 @@
|
|||
#define TEGRA_UARTF_BASE 0x03150000
|
||||
#define TEGRA_UARTG_BASE 0x0C290000
|
||||
|
||||
/*******************************************************************************
|
||||
* Tegra Fuse Controller related constants
|
||||
******************************************************************************/
|
||||
#define TEGRA_FUSE_BASE 0x03820000
|
||||
#define OPT_SUBREVISION 0x248
|
||||
#define SUBREVISION_MASK 0xFF
|
||||
|
||||
/*******************************************************************************
|
||||
* GICv2 & interrupt handling related constants
|
||||
******************************************************************************/
|
||||
|
@ -143,6 +146,8 @@
|
|||
#define SECURE_SCRATCH_RSV6 0x680
|
||||
#define SECURE_SCRATCH_RSV11_LO 0x6A8
|
||||
#define SECURE_SCRATCH_RSV11_HI 0x6AC
|
||||
#define SECURE_SCRATCH_RSV53_LO 0x7F8
|
||||
#define SECURE_SCRATCH_RSV53_HI 0x7FC
|
||||
|
||||
/*******************************************************************************
|
||||
* Tegra Memory Mapped Control Register Access Bus constants
|
||||
|
@ -158,6 +163,6 @@
|
|||
* Tegra TZRAM constants
|
||||
******************************************************************************/
|
||||
#define TEGRA_TZRAM_BASE 0x30000000
|
||||
#define TEGRA_TZRAM_SIZE 0x50000
|
||||
#define TEGRA_TZRAM_SIZE 0x40000
|
||||
|
||||
#endif /* __TEGRA_DEF_H__ */
|
||||
|
|
|
@ -95,12 +95,31 @@ typedef enum mce_cmd {
|
|||
MCE_CMD_ROC_FLUSH_CACHE,
|
||||
MCE_CMD_ROC_CLEAN_CACHE,
|
||||
MCE_CMD_ENABLE_LATIC,
|
||||
MCE_CMD_UNCORE_PERFMON_REQ,
|
||||
MCE_CMD_IS_CCX_ALLOWED = 0xFE,
|
||||
MCE_CMD_MAX = 0xFF,
|
||||
} mce_cmd_t;
|
||||
|
||||
#define MCE_CMD_MASK 0xFF
|
||||
|
||||
/*******************************************************************************
|
||||
* Struct to prepare UPDATE_CSTATE_INFO request
|
||||
******************************************************************************/
|
||||
typedef struct mce_cstate_info {
|
||||
/* cluster cstate value */
|
||||
uint32_t cluster;
|
||||
/* ccplex cstate value */
|
||||
uint32_t ccplex;
|
||||
/* system cstate value */
|
||||
uint32_t system;
|
||||
/* force system state? */
|
||||
uint8_t system_state_force;
|
||||
/* wake mask value */
|
||||
uint32_t wake_mask;
|
||||
/* update the wake mask? */
|
||||
uint8_t update_wake_mask;
|
||||
} mce_cstate_info_t;
|
||||
|
||||
/*******************************************************************************
|
||||
* Macros to prepare CSTATE info request
|
||||
******************************************************************************/
|
||||
|
@ -183,6 +202,54 @@ typedef union mca_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
|
||||
|
||||
/*******************************************************************************
|
||||
* Structure populated by arch specific code to export routines which perform
|
||||
* common low level MCE functions
|
||||
|
@ -313,6 +380,12 @@ typedef struct arch_mce_ops {
|
|||
* reset the entire system
|
||||
*/
|
||||
void (*enter_ccplex_state)(uint32_t ari_base, uint32_t state_idx);
|
||||
/*
|
||||
* This ARI request reads/writes data from/to Uncore PERFMON
|
||||
* registers
|
||||
*/
|
||||
int (*read_write_uncore_perfmon)(uint32_t ari_base,
|
||||
uncore_perfmon_req_t req, uint64_t *data);
|
||||
} arch_mce_ops_t;
|
||||
|
||||
int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
|
||||
|
@ -322,6 +395,7 @@ int mce_update_gsc_videomem(void);
|
|||
int mce_update_gsc_tzdram(void);
|
||||
int mce_update_gsc_tzram(void);
|
||||
__dead2 void mce_enter_ccplex_state(uint32_t state_idx);
|
||||
void mce_update_cstate_info(mce_cstate_info_t *cstate);
|
||||
void mce_verify_firmware_version(void);
|
||||
|
||||
/* declarations for ARI/NVG handler functions */
|
||||
|
@ -344,6 +418,8 @@ int ari_roc_clean_cache(uint32_t ari_base);
|
|||
uint64_t ari_read_write_mca(uint32_t ari_base, mca_cmd_t cmd, uint64_t *data);
|
||||
int ari_update_ccplex_gsc(uint32_t ari_base, uint32_t gsc_idx);
|
||||
void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx);
|
||||
int ari_read_write_uncore_perfmon(uint32_t ari_base,
|
||||
uncore_perfmon_req_t req, uint64_t *data);
|
||||
|
||||
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,
|
||||
|
|
|
@ -389,3 +389,41 @@ void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx)
|
|||
*/
|
||||
(void)ari_request_wait(ari_base, 0, TEGRA_ARI_MISC_CCPLEX, state_idx, 0);
|
||||
}
|
||||
|
||||
int ari_read_write_uncore_perfmon(uint32_t ari_base,
|
||||
uncore_perfmon_req_t req, uint64_t *data)
|
||||
{
|
||||
int ret;
|
||||
uint32_t val;
|
||||
|
||||
/* sanity check input parameters */
|
||||
if (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_READ && !data) {
|
||||
ERROR("invalid parameters\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* For "write" commands get the value that has to be written
|
||||
* to the uncore perfmon registers
|
||||
*/
|
||||
val = (req.perfmon_command.cmd == UNCORE_PERFMON_CMD_WRITE) ?
|
||||
*data : 0;
|
||||
|
||||
ret = ari_request_wait(ari_base, 0, TEGRA_ARI_PERFMON, val, req.data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* read the command status value */
|
||||
req.perfmon_status.val = ari_get_response_high(ari_base) &
|
||||
UNCORE_PERFMON_RESP_STATUS_MASK;
|
||||
|
||||
/*
|
||||
* For "read" commands get the data from the uncore
|
||||
* perfmon registers
|
||||
*/
|
||||
if ((req.perfmon_status.val == 0) && (req.perfmon_command.cmd ==
|
||||
UNCORE_PERFMON_CMD_READ))
|
||||
*data = ari_get_response_low(ari_base);
|
||||
|
||||
return (int)req.perfmon_status.val;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <sys/errno.h>
|
||||
#include <t18x_ari.h>
|
||||
#include <tegra_def.h>
|
||||
#include <tegra_platform.h>
|
||||
|
||||
/* NVG functions handlers */
|
||||
static arch_mce_ops_t nvg_mce_ops = {
|
||||
|
@ -61,7 +62,8 @@ static arch_mce_ops_t nvg_mce_ops = {
|
|||
.roc_clean_cache = ari_roc_clean_cache,
|
||||
.read_write_mca = ari_read_write_mca,
|
||||
.update_ccplex_gsc = ari_update_ccplex_gsc,
|
||||
.enter_ccplex_state = ari_enter_ccplex_state
|
||||
.enter_ccplex_state = ari_enter_ccplex_state,
|
||||
.read_write_uncore_perfmon = ari_read_write_uncore_perfmon
|
||||
};
|
||||
|
||||
/* ARI functions handlers */
|
||||
|
@ -82,7 +84,8 @@ static arch_mce_ops_t ari_mce_ops = {
|
|||
.roc_clean_cache = ari_roc_clean_cache,
|
||||
.read_write_mca = ari_read_write_mca,
|
||||
.update_ccplex_gsc = ari_update_ccplex_gsc,
|
||||
.enter_ccplex_state = ari_enter_ccplex_state
|
||||
.enter_ccplex_state = ari_enter_ccplex_state,
|
||||
.read_write_uncore_perfmon = ari_read_write_uncore_perfmon
|
||||
};
|
||||
|
||||
typedef struct mce_config {
|
||||
|
@ -173,6 +176,7 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
|
|||
uint64_t ret64 = 0, arg3, arg4, arg5;
|
||||
int ret = 0;
|
||||
mca_cmd_t mca_cmd;
|
||||
uncore_perfmon_req_t req;
|
||||
cpu_context_t *ctx = cm_get_context(NON_SECURE);
|
||||
gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
|
||||
|
||||
|
@ -374,6 +378,15 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
|
|||
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MCE_CMD_UNCORE_PERFMON_REQ:
|
||||
memcpy(&req, &arg0, sizeof(arg0));
|
||||
ret = ops->read_write_uncore_perfmon(cpu_ari_base, req, &arg1);
|
||||
|
||||
/* update context to return data */
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X1, arg1);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR("unknown MCE command (%d)\n", cmd);
|
||||
return EINVAL;
|
||||
|
@ -448,6 +461,19 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx)
|
|||
panic();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Handler to issue the UPDATE_CSTATE_INFO request
|
||||
******************************************************************************/
|
||||
void mce_update_cstate_info(mce_cstate_info_t *cstate)
|
||||
{
|
||||
arch_mce_ops_t *ops = mce_get_curr_cpu_ops();
|
||||
|
||||
/* issue the UPDATE_CSTATE_INFO request */
|
||||
ops->update_cstate_info(mce_get_curr_cpu_ari_base(), cstate->cluster,
|
||||
cstate->ccplex, cstate->system, cstate->system_state_force,
|
||||
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
|
||||
|
@ -457,7 +483,13 @@ void mce_verify_firmware_version(void)
|
|||
arch_mce_ops_t *ops;
|
||||
uint32_t cpu_ari_base;
|
||||
uint64_t version;
|
||||
uint32_t major, minor, chip_minor, chip_major;
|
||||
uint32_t major, minor;
|
||||
|
||||
/*
|
||||
* MCE firmware is not running on simulation platforms.
|
||||
*/
|
||||
if (tegra_platform_is_emulation())
|
||||
return;
|
||||
|
||||
/* get a pointer to the CPU's arch_mce_ops_t struct */
|
||||
ops = mce_get_curr_cpu_ops();
|
||||
|
@ -476,17 +508,6 @@ void mce_verify_firmware_version(void)
|
|||
INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor,
|
||||
TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR);
|
||||
|
||||
/*
|
||||
* MCE firmware is not running on simulation platforms. Simulation
|
||||
* platforms are identified by v0.3 from the Tegra Chip ID value.
|
||||
*/
|
||||
chip_major = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >>
|
||||
MAJOR_VERSION_SHIFT) & MAJOR_VERSION_MASK;
|
||||
chip_minor = (mmio_read_32(TEGRA_MISC_BASE + HARDWARE_REVISION_OFFSET) >>
|
||||
MINOR_VERSION_SHIFT) & MINOR_VERSION_MASK;
|
||||
if ((chip_major == 0) && (chip_minor == 3))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Verify that the MCE firmware version and the interface header
|
||||
* match
|
||||
|
|
|
@ -465,15 +465,42 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
|
|||
(uint32_t)(smmu_ctx_addr >> 32));
|
||||
}
|
||||
|
||||
#define SMMU_NUM_CONTEXTS 64
|
||||
#define SMMU_CONTEXT_BANK_MAX_IDX 64
|
||||
|
||||
/*
|
||||
* Init SMMU during boot or "System Suspend" exit
|
||||
*/
|
||||
void tegra_smmu_init(void)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t val, i, ctx_base;
|
||||
|
||||
/* Program the SMMU pagesize */
|
||||
/* Program the SMMU pagesize and reset CACHE_LOCK bit */
|
||||
val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR);
|
||||
val |= SMMU_GSR0_PGSIZE_64K;
|
||||
val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
|
||||
tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val);
|
||||
|
||||
/* reset CACHE LOCK bit for NS Aux. Config. Register */
|
||||
val = tegra_smmu_read_32(SMMU_GNSR_ACR);
|
||||
val &= ~SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
|
||||
tegra_smmu_write_32(SMMU_GNSR_ACR, val);
|
||||
|
||||
/* disable TCU prefetch for all contexts */
|
||||
ctx_base = (SMMU_GSR0_PGSIZE_64K * SMMU_NUM_CONTEXTS) + SMMU_CBn_ACTLR;
|
||||
for (i = 0; i < SMMU_CONTEXT_BANK_MAX_IDX; i++) {
|
||||
val = tegra_smmu_read_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i));
|
||||
val &= ~SMMU_CBn_ACTLR_CPRE_BIT;
|
||||
tegra_smmu_write_32(ctx_base + (SMMU_GSR0_PGSIZE_64K * i), val);
|
||||
}
|
||||
|
||||
/* set CACHE LOCK bit for NS Aux. Config. Register */
|
||||
val = tegra_smmu_read_32(SMMU_GNSR_ACR);
|
||||
val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
|
||||
tegra_smmu_write_32(SMMU_GNSR_ACR, val);
|
||||
|
||||
/* set CACHE LOCK bit for S Aux. Config. Register */
|
||||
val = tegra_smmu_read_32(SMMU_GSR0_SECURE_ACR);
|
||||
val |= SMMU_ACR_CACHE_LOCK_ENABLE_BIT;
|
||||
tegra_smmu_write_32(SMMU_GSR0_SECURE_ACR, val);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <debug.h>
|
||||
#include <denver.h>
|
||||
#include <mce.h>
|
||||
#include <platform.h>
|
||||
#include <psci.h>
|
||||
#include <smmu.h>
|
||||
#include <string.h>
|
||||
|
@ -71,12 +72,9 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
|
|||
psci_power_state_t *req_state)
|
||||
{
|
||||
int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK;
|
||||
int cpu = read_mpidr() & MPIDR_CPU_MASK;
|
||||
int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
|
||||
|
||||
if (impl == DENVER_IMPL)
|
||||
cpu |= 0x4;
|
||||
int cpu = plat_my_core_pos();
|
||||
|
||||
/* save the core wake time (us) */
|
||||
wake_time[cpu] = (power_state >> TEGRA186_WAKE_TIME_SHIFT) &
|
||||
TEGRA186_WAKE_TIME_MASK;
|
||||
|
||||
|
@ -84,10 +82,10 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
|
|||
switch (state_id) {
|
||||
case PSTATE_ID_CORE_IDLE:
|
||||
case PSTATE_ID_CORE_POWERDN:
|
||||
/*
|
||||
* Core powerdown request only for afflvl 0
|
||||
*/
|
||||
|
||||
/* Core powerdown request */
|
||||
req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id;
|
||||
req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id;
|
||||
|
||||
break;
|
||||
|
||||
|
@ -103,20 +101,12 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
{
|
||||
const plat_local_state_t *pwr_domain_state;
|
||||
unsigned int stateid_afflvl0, stateid_afflvl2;
|
||||
int cpu = read_mpidr() & MPIDR_CPU_MASK;
|
||||
int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
|
||||
cpu_context_t *ctx = cm_get_context(NON_SECURE);
|
||||
gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
|
||||
int cpu = plat_my_core_pos();
|
||||
plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
|
||||
mce_cstate_info_t cstate_info = { 0 };
|
||||
uint64_t smmu_ctx_base;
|
||||
uint32_t val;
|
||||
|
||||
assert(ctx);
|
||||
assert(gp_regs);
|
||||
|
||||
if (impl == DENVER_IMPL)
|
||||
cpu |= 0x4;
|
||||
|
||||
/* get the state ID */
|
||||
pwr_domain_state = target_state->pwr_domain_state;
|
||||
stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] &
|
||||
|
@ -124,29 +114,14 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] &
|
||||
TEGRA186_STATE_ID_MASK;
|
||||
|
||||
if (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) {
|
||||
if ((stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ||
|
||||
(stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) {
|
||||
|
||||
/* Program default wake mask */
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, TEGRA186_CORE_WAKE_MASK);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
|
||||
(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, 0, 0, 0);
|
||||
|
||||
/* Prepare for cpu idle */
|
||||
(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
|
||||
TEGRA_ARI_CORE_C6, wake_time[cpu], 0);
|
||||
|
||||
} else if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) {
|
||||
|
||||
/* Program default wake mask */
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, TEGRA186_CORE_WAKE_MASK);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
|
||||
(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, 0, 0, 0);
|
||||
|
||||
/* Prepare for cpu powerdn */
|
||||
(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
|
||||
TEGRA_ARI_CORE_C7, wake_time[cpu], 0);
|
||||
/* Enter CPU idle/powerdown */
|
||||
val = (stateid_afflvl0 == PSTATE_ID_CORE_IDLE) ?
|
||||
TEGRA_ARI_CORE_C6 : TEGRA_ARI_CORE_C7;
|
||||
(void)mce_command_handler(MCE_CMD_ENTER_CSTATE, val,
|
||||
wake_time[cpu], 0);
|
||||
|
||||
} else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) {
|
||||
|
||||
|
@ -170,11 +145,11 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
|
||||
|
||||
/* Prepare for system suspend */
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X4, 1);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
|
||||
(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
|
||||
TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC7);
|
||||
cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
|
||||
cstate_info.system = TEGRA_ARI_SYSTEM_SC7;
|
||||
cstate_info.system_state_force = 1;
|
||||
cstate_info.update_wake_mask = 1;
|
||||
mce_update_cstate_info(&cstate_info);
|
||||
|
||||
/* Loop until system suspend is allowed */
|
||||
do {
|
||||
|
@ -187,15 +162,84 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
/* Instruct the MCE to enter system suspend state */
|
||||
(void)mce_command_handler(MCE_CMD_ENTER_CSTATE,
|
||||
TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0);
|
||||
|
||||
} else {
|
||||
ERROR("%s: Unknown state id\n", __func__);
|
||||
return PSCI_E_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Platform handler to calculate the proper target power level at the
|
||||
* specified affinity level
|
||||
******************************************************************************/
|
||||
plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
|
||||
const plat_local_state_t *states,
|
||||
unsigned int ncpu)
|
||||
{
|
||||
plat_local_state_t target = *states;
|
||||
int cpu = plat_my_core_pos(), ret, cluster_powerdn = 1;
|
||||
int core_pos = read_mpidr() & MPIDR_CPU_MASK;
|
||||
mce_cstate_info_t cstate_info = { 0 };
|
||||
|
||||
/* get the current core's power state */
|
||||
target = *(states + core_pos);
|
||||
|
||||
/* CPU suspend */
|
||||
if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
|
||||
|
||||
/* Program default wake mask */
|
||||
cstate_info.wake_mask = TEGRA186_CORE_WAKE_MASK;
|
||||
cstate_info.update_wake_mask = 1;
|
||||
mce_update_cstate_info(&cstate_info);
|
||||
|
||||
/* Check if CCx state is allowed. */
|
||||
ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
|
||||
TEGRA_ARI_CORE_C7, wake_time[cpu], 0);
|
||||
if (ret)
|
||||
return PSTATE_ID_CORE_POWERDN;
|
||||
}
|
||||
|
||||
/* CPU off */
|
||||
if (lvl == MPIDR_AFFLVL1 && target == PLAT_MAX_OFF_STATE) {
|
||||
|
||||
/* find out the number of ON cpus in the cluster */
|
||||
do {
|
||||
target = *states++;
|
||||
if (target != PLAT_MAX_OFF_STATE)
|
||||
cluster_powerdn = 0;
|
||||
} while (--ncpu);
|
||||
|
||||
/* Enable cluster powerdn from last CPU in the cluster */
|
||||
if (cluster_powerdn) {
|
||||
|
||||
/* Enable CC7 state and turn off wake mask */
|
||||
cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
|
||||
cstate_info.update_wake_mask = 1;
|
||||
mce_update_cstate_info(&cstate_info);
|
||||
|
||||
/* Check if CCx state is allowed. */
|
||||
ret = mce_command_handler(MCE_CMD_IS_CCX_ALLOWED,
|
||||
TEGRA_ARI_CORE_C7,
|
||||
MCE_CORE_SLEEP_TIME_INFINITE,
|
||||
0);
|
||||
if (ret)
|
||||
return PSTATE_ID_CORE_POWERDN;
|
||||
|
||||
} else {
|
||||
|
||||
/* Turn off wake_mask */
|
||||
cstate_info.update_wake_mask = 1;
|
||||
mce_update_cstate_info(&cstate_info);
|
||||
}
|
||||
}
|
||||
|
||||
/* System Suspend */
|
||||
if ((lvl == MPIDR_AFFLVL2) || (target == PSTATE_ID_SOC_POWERDN))
|
||||
return PSTATE_ID_SOC_POWERDN;
|
||||
|
||||
/* default state */
|
||||
return PSCI_LOCAL_STATE_RUN;
|
||||
}
|
||||
|
||||
int tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state)
|
||||
{
|
||||
const plat_local_state_t *pwr_domain_state =
|
||||
|
@ -244,8 +288,7 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
{
|
||||
int stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL];
|
||||
int stateid_afflvl0 = target_state->pwr_domain_state[MPIDR_AFFLVL0];
|
||||
cpu_context_t *ctx = cm_get_context(NON_SECURE);
|
||||
gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
|
||||
mce_cstate_info_t cstate_info = { 0 };
|
||||
|
||||
/*
|
||||
* Reset power state info for CPUs when onlining, we set
|
||||
|
@ -256,11 +299,9 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
*/
|
||||
if (stateid_afflvl0 == PLAT_MAX_OFF_STATE) {
|
||||
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
|
||||
mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
|
||||
TEGRA_ARI_CLUSTER_CC1, 0, 0);
|
||||
cstate_info.cluster = TEGRA_ARI_CLUSTER_CC1;
|
||||
cstate_info.update_wake_mask = 1;
|
||||
mce_update_cstate_info(&cstate_info);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -280,15 +321,15 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
tegra_smmu_init();
|
||||
|
||||
/*
|
||||
* Reset power state info for the last core doing SC7 entry and exit,
|
||||
* we set deepest power state as CC7 and SC7 for SC7 entry which
|
||||
* may not be requested by non-secure SW which controls idle states.
|
||||
* Reset power state info for the last core doing SC7
|
||||
* entry and exit, we set deepest power state as CC7
|
||||
* and SC7 for SC7 entry which may not be requested by
|
||||
* non-secure SW which controls idle states.
|
||||
*/
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
|
||||
(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
|
||||
TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC1);
|
||||
cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
|
||||
cstate_info.system = TEGRA_ARI_SYSTEM_SC1;
|
||||
cstate_info.update_wake_mask = 1;
|
||||
mce_update_cstate_info(&cstate_info);
|
||||
}
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
|
@ -296,33 +337,22 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
|
|||
|
||||
int tegra_soc_pwr_domain_off(const psci_power_state_t *target_state)
|
||||
{
|
||||
cpu_context_t *ctx = cm_get_context(NON_SECURE);
|
||||
gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
|
||||
int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
|
||||
|
||||
assert(ctx);
|
||||
assert(gp_regs);
|
||||
|
||||
/* Turn off wake_mask */
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X4, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
|
||||
mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO, TEGRA_ARI_CLUSTER_CC7,
|
||||
0, 0);
|
||||
|
||||
/* Disable Denver's DCO operations */
|
||||
if (impl == DENVER_IMPL)
|
||||
denver_disable_dco();
|
||||
|
||||
/* Turn off CPU */
|
||||
return mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
|
||||
(void)mce_command_handler(MCE_CMD_ENTER_CSTATE, TEGRA_ARI_CORE_C7,
|
||||
MCE_CORE_SLEEP_TIME_INFINITE, 0);
|
||||
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
|
||||
__dead2 void tegra_soc_prepare_system_off(void)
|
||||
{
|
||||
cpu_context_t *ctx = cm_get_context(NON_SECURE);
|
||||
gp_regs_t *gp_regs = get_gpregs_ctx(ctx);
|
||||
mce_cstate_info_t cstate_info = { 0 };
|
||||
uint32_t val;
|
||||
|
||||
if (tegra186_system_powerdn_state == TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) {
|
||||
|
@ -333,11 +363,11 @@ __dead2 void tegra_soc_prepare_system_off(void)
|
|||
} else if (tegra186_system_powerdn_state == TEGRA_ARI_SYSTEM_SC8) {
|
||||
|
||||
/* Prepare for quasi power down */
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X4, 1);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X5, 0);
|
||||
write_ctx_reg(gp_regs, CTX_GPREG_X6, 1);
|
||||
(void)mce_command_handler(MCE_CMD_UPDATE_CSTATE_INFO,
|
||||
TEGRA_ARI_CLUSTER_CC7, 0, TEGRA_ARI_SYSTEM_SC8);
|
||||
cstate_info.cluster = TEGRA_ARI_CLUSTER_CC7;
|
||||
cstate_info.system = TEGRA_ARI_SYSTEM_SC8;
|
||||
cstate_info.system_state_force = 1;
|
||||
cstate_info.update_wake_mask = 1;
|
||||
mce_update_cstate_info(&cstate_info);
|
||||
|
||||
/* loop until other CPUs power down */
|
||||
do {
|
||||
|
@ -357,6 +387,9 @@ __dead2 void tegra_soc_prepare_system_off(void)
|
|||
/* power down core */
|
||||
prepare_cpu_pwr_dwn();
|
||||
|
||||
/* flush L1/L2 data caches */
|
||||
dcsw_op_all(DCCISW);
|
||||
|
||||
} else {
|
||||
ERROR("%s: unsupported power down state (%d)\n", __func__,
|
||||
tegra186_system_powerdn_state);
|
||||
|
|
|
@ -30,19 +30,25 @@
|
|||
|
||||
#include <arch_helpers.h>
|
||||
#include <assert.h>
|
||||
#include <bl31.h>
|
||||
#include <bl_common.h>
|
||||
#include <console.h>
|
||||
#include <context.h>
|
||||
#include <context_mgmt.h>
|
||||
#include <cortex_a57.h>
|
||||
#include <debug.h>
|
||||
#include <denver.h>
|
||||
#include <interrupt_mgmt.h>
|
||||
#include <mce.h>
|
||||
#include <platform.h>
|
||||
#include <tegra_def.h>
|
||||
#include <tegra_platform.h>
|
||||
#include <tegra_private.h>
|
||||
#include <xlat_tables.h>
|
||||
|
||||
DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1)
|
||||
extern uint64_t tegra_enable_l2_ecc_parity_prot;
|
||||
|
||||
/*******************************************************************************
|
||||
* The Tegra power domain tree has a single system level power domain i.e. a
|
||||
* single root node. The first entry in the power domain descriptor specifies
|
||||
|
@ -72,7 +78,13 @@ static const mmap_region_t tegra_mmap[] = {
|
|||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(TEGRA_MC_BASE, 0x10000, /* 64KB */
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB */
|
||||
MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000, /* 128KB - UART A, B*/
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000, /* 128KB - UART C, G */
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000, /* 192KB - UART D, E, F */
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(TEGRA_FUSE_BASE, 0x10000, /* 64KB */
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x20000, /* 128KB */
|
||||
MT_DEVICE | MT_RW | MT_SECURE),
|
||||
|
@ -142,6 +154,51 @@ uint32_t plat_get_console_from_id(int id)
|
|||
return tegra186_uart_addresses[id];
|
||||
}
|
||||
|
||||
/* represent chip-version as concatenation of major (15:12), minor (11:8) and subrev (7:0) */
|
||||
#define TEGRA186_VER_A02P 0x1201
|
||||
|
||||
/*******************************************************************************
|
||||
* Handler for early platform setup
|
||||
******************************************************************************/
|
||||
void plat_early_platform_setup(void)
|
||||
{
|
||||
int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
|
||||
uint32_t chip_subrev, val;
|
||||
|
||||
/* sanity check MCE firmware compatibility */
|
||||
mce_verify_firmware_version();
|
||||
|
||||
/*
|
||||
* Enable ECC and Parity Protection for Cortex-A57 CPUs
|
||||
* for Tegra A02p SKUs
|
||||
*/
|
||||
if (impl != DENVER_IMPL) {
|
||||
|
||||
/* get the major, minor and sub-version values */
|
||||
chip_subrev = mmio_read_32(TEGRA_FUSE_BASE + OPT_SUBREVISION) &
|
||||
SUBREVISION_MASK;
|
||||
|
||||
/* prepare chip version number */
|
||||
val = (tegra_get_chipid_major() << 12) |
|
||||
(tegra_get_chipid_minor() << 8) |
|
||||
chip_subrev;
|
||||
|
||||
/* enable L2 ECC for Tegra186 A02P and beyond */
|
||||
if (val >= TEGRA186_VER_A02P) {
|
||||
|
||||
val = read_l2ctlr_el1();
|
||||
val |= L2_ECC_PARITY_PROTECTION_BIT;
|
||||
write_l2ctlr_el1(val);
|
||||
|
||||
/*
|
||||
* Set the flag to enable ECC/Parity Protection
|
||||
* when we exit System Suspend or Cluster Powerdn
|
||||
*/
|
||||
tegra_enable_l2_ecc_parity_prot = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Secure IRQs for Tegra186 */
|
||||
static const irq_sec_cfg_t tegra186_sec_irqs[] = {
|
||||
{
|
||||
|
@ -173,9 +230,25 @@ void plat_gic_setup(void)
|
|||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Handler for early platform setup
|
||||
* Return pointer to the BL31 params from previous bootloader
|
||||
******************************************************************************/
|
||||
void plat_early_platform_setup(void)
|
||||
bl31_params_t *plat_get_bl31_params(void)
|
||||
{
|
||||
mce_verify_firmware_version();
|
||||
uint32_t val;
|
||||
|
||||
val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
|
||||
|
||||
return (bl31_params_t *)(uintptr_t)val;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Return pointer to the BL31 platform params from previous bootloader
|
||||
******************************************************************************/
|
||||
plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
|
||||
|
||||
return (plat_params_from_bl2_t *)(uintptr_t)val;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ extern uint32_t tegra186_system_powerdn_state;
|
|||
#define TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE 0x82FFFF0E
|
||||
#define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0x82FFFF0F
|
||||
#define TEGRA_SIP_MCE_CMD_ENABLE_LATIC 0x82FFFF10
|
||||
#define TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ 0x82FFFF11
|
||||
|
||||
/*******************************************************************************
|
||||
* This function is responsible for handling all T186 SiP calls
|
||||
|
@ -102,6 +103,7 @@ int plat_sip_handler(uint32_t smc_fid,
|
|||
case TEGRA_SIP_MCE_CMD_ROC_FLUSH_CACHE:
|
||||
case TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE:
|
||||
case TEGRA_SIP_MCE_CMD_ENABLE_LATIC:
|
||||
case TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ:
|
||||
|
||||
/* clean up the high bits */
|
||||
smc_fid &= MCE_CMD_MASK;
|
||||
|
@ -112,32 +114,6 @@ int plat_sip_handler(uint32_t smc_fid,
|
|||
|
||||
return 0;
|
||||
|
||||
case TEGRA_SIP_NEW_VIDEOMEM_REGION:
|
||||
/* clean up the high bits */
|
||||
x1 = (uint32_t)x1;
|
||||
x2 = (uint32_t)x2;
|
||||
|
||||
/*
|
||||
* Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
|
||||
* or falls outside of the valid DRAM range
|
||||
*/
|
||||
mce_ret = bl31_check_ns_address(x1, x2);
|
||||
if (mce_ret)
|
||||
return -ENOTSUP;
|
||||
|
||||
/*
|
||||
* Check if Video Memory is aligned to 1MB.
|
||||
*/
|
||||
if ((x1 & 0xFFFFF) || (x2 & 0xFFFFF)) {
|
||||
ERROR("Unaligned Video Memory base address!\n");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* new video memory carveout settings */
|
||||
tegra_memctrl_videomem_setup(x1, x2);
|
||||
|
||||
return 0;
|
||||
|
||||
case TEGRA_SIP_SYSTEM_SHUTDOWN_STATE:
|
||||
|
||||
/* clean up the high bits */
|
||||
|
|
|
@ -32,9 +32,18 @@
|
|||
ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1
|
||||
$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
|
||||
|
||||
RELOCATE_TO_BL31_BASE := 1
|
||||
$(eval $(call add_define,RELOCATE_TO_BL31_BASE))
|
||||
|
||||
ENABLE_CHIP_VERIFICATION_HARNESS := 0
|
||||
$(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
|
||||
|
||||
RESET_TO_BL31 := 1
|
||||
|
||||
PROGRAMMABLE_RESET_ADDRESS := 1
|
||||
|
||||
COLD_BOOT_SINGLE_CPU := 1
|
||||
|
||||
# platform settings
|
||||
TZDRAM_BASE := 0x30000000
|
||||
$(eval $(call add_define,TZDRAM_BASE))
|
||||
|
|
Loading…
Reference in New Issue