Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
Arm Trusted Firmware
Commits
82720675
Commit
82720675
authored
Apr 05, 2017
by
davidcunado-arm
Committed by
GitHub
Apr 05, 2017
Browse files
Merge pull request #884 from vwadekar/tegra186-platform-support-v3
Tegra186 platform support v3
parents
ffe102ca
c61cd638
Changes
12
Hide whitespace changes
Inline
Side-by-side
plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
View file @
82720675
...
@@ -38,6 +38,7 @@
...
@@ -38,6 +38,7 @@
#include <smmu.h>
#include <smmu.h>
#include <string.h>
#include <string.h>
#include <tegra_def.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <xlat_tables.h>
#include <xlat_tables.h>
#define TEGRA_GPU_RESET_REG_OFFSET 0x30
#define TEGRA_GPU_RESET_REG_OFFSET 0x30
...
@@ -495,7 +496,6 @@ void tegra_memctrl_setup(void)
...
@@ -495,7 +496,6 @@ void tegra_memctrl_setup(void)
uint32_t
num_overrides
=
sizeof
(
streamid_overrides
)
/
sizeof
(
uint32_t
);
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_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
num_txn_overrides
=
sizeof
(
mc_override_cfgs
)
/
sizeof
(
mc_txn_override_cfg_t
);
uint32_t
chip_minor
,
chip_major
;
int
i
;
int
i
;
INFO
(
"Tegra Memory Controller (v2)
\n
"
);
INFO
(
"Tegra Memory Controller (v2)
\n
"
);
...
@@ -543,12 +543,8 @@ void tegra_memctrl_setup(void)
...
@@ -543,12 +543,8 @@ void tegra_memctrl_setup(void)
/*
/*
* Set the MC_TXN_OVERRIDE registers for write clients.
* Set the MC_TXN_OVERRIDE registers for write clients.
*/
*/
chip_major
=
(
mmio_read_32
(
TEGRA_MISC_BASE
+
HARDWARE_REVISION_OFFSET
)
>>
if
(
!
tegra_platform_is_silicon
()
||
MAJOR_VERSION_SHIFT
)
&
MAJOR_VERSION_MASK
;
(
tegra_platform_is_silicon
()
&&
tegra_get_chipid_minor
()
==
1
))
{
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
))
{
/* GPU and NVENC settings for rev. A01 */
/* GPU and NVENC settings for rev. A01 */
val
=
tegra_mc_read_32
(
MC_TXN_OVERRIDE_CONFIG_GPUSWR
);
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)
...
@@ -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
)
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
;
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
)
for
(
index
=
MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0
;
return
;
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
* Allow CPU read/write access to the aperture
* the TZRAM carveout
*/
*/
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
);
* Set the TZRAM base. TZRAM base must be 4k aligned, at least.
tegra_mc_write_32
(
MC_TZRAM_END
,
(
uint32_t
)
tzram_end
);
*/
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
;
* Set the TZRAM size
val
|=
(((
uint32_t
)(
tzram_end
>>
32
)
&
TZRAM_ADDR_HI_BITS_MASK
)
<<
*
TZRAM_END_HI_BITS_SHIFT
);
* total size = (number of 128KB blocks) + (number of remaining 4KB
tegra_mc_write_32
(
MC_TZRAM_HI_ADDR_BITS
,
val
);
* 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
* MCE propogates the security configuration values across the
...
...
plat/nvidia/tegra/include/drivers/memctrl_v2.h
View file @
82720675
...
@@ -350,7 +350,7 @@ typedef struct mc_streamid_security_cfg {
...
@@ -350,7 +350,7 @@ typedef struct mc_streamid_security_cfg {
.override_enable = OVERRIDE_ ## access \
.override_enable = OVERRIDE_ ## access \
}
}
#endif
/* __ASS
M
EBLY__ */
#endif
/* __ASSE
M
BLY__ */
/*******************************************************************************
/*******************************************************************************
* TZDRAM carveout configuration registers
* TZDRAM carveout configuration registers
...
@@ -367,15 +367,35 @@ typedef struct mc_streamid_security_cfg {
...
@@ -367,15 +367,35 @@ typedef struct mc_streamid_security_cfg {
#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
#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_BASE_LO 0x2194
#define MC_TZRAM_END 0x1854
#define TZRAM_BASE_LO_SHIFT 12
#define MC_TZRAM_HI_ADDR_BITS 0x1588
#define TZRAM_BASE_LO_MASK 0xFFFFF
#define TZRAM_ADDR_HI_BITS_MASK 0x3
#define MC_TZRAM_BASE_HI 0x2198
#define TZRAM_END_HI_BITS_SHIFT 8
#define TZRAM_BASE_HI_SHIFT 0
#define MC_TZRAM_REG_CTRL 0x185c
#define TZRAM_BASE_HI_MASK 3
#define DISABLE_TZRAM_ACCESS 1
#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
* Memory Controller Reset Control registers
...
...
plat/nvidia/tegra/include/drivers/smmu.h
View file @
82720675
...
@@ -599,9 +599,16 @@
...
@@ -599,9 +599,16 @@
* SMMU Global Secure Aux. Configuration Register
* SMMU Global Secure Aux. Configuration Register
******************************************************************************/
******************************************************************************/
#define SMMU_GSR0_SECURE_ACR 0x10
#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_SHIFT 16
#define SMMU_GSR0_PGSIZE_4K (0 << SMMU_GSR0_PGSIZE_SHIFT)
#define SMMU_GSR0_PGSIZE_4K (0 << SMMU_GSR0_PGSIZE_SHIFT)
#define SMMU_GSR0_PGSIZE_64K (1 << 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
* SMMU configuration constants
...
...
plat/nvidia/tegra/include/t186/tegra_def.h
View file @
82720675
...
@@ -76,10 +76,6 @@
...
@@ -76,10 +76,6 @@
******************************************************************************/
******************************************************************************/
#define TEGRA_MISC_BASE 0x00100000
#define TEGRA_MISC_BASE 0x00100000
#define HARDWARE_REVISION_OFFSET 0x4
#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
#define MISCREG_PFCFG 0x200C
...
@@ -105,6 +101,13 @@
...
@@ -105,6 +101,13 @@
#define TEGRA_UARTF_BASE 0x03150000
#define TEGRA_UARTF_BASE 0x03150000
#define TEGRA_UARTG_BASE 0x0C290000
#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
* GICv2 & interrupt handling related constants
******************************************************************************/
******************************************************************************/
...
@@ -143,6 +146,8 @@
...
@@ -143,6 +146,8 @@
#define SECURE_SCRATCH_RSV6 0x680
#define SECURE_SCRATCH_RSV6 0x680
#define SECURE_SCRATCH_RSV11_LO 0x6A8
#define SECURE_SCRATCH_RSV11_LO 0x6A8
#define SECURE_SCRATCH_RSV11_HI 0x6AC
#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
* Tegra Memory Mapped Control Register Access Bus constants
...
@@ -158,6 +163,6 @@
...
@@ -158,6 +163,6 @@
* Tegra TZRAM constants
* Tegra TZRAM constants
******************************************************************************/
******************************************************************************/
#define TEGRA_TZRAM_BASE 0x30000000
#define TEGRA_TZRAM_BASE 0x30000000
#define TEGRA_TZRAM_SIZE 0x
5
0000
#define TEGRA_TZRAM_SIZE 0x
4
0000
#endif
/* __TEGRA_DEF_H__ */
#endif
/* __TEGRA_DEF_H__ */
plat/nvidia/tegra/soc/t186/drivers/include/mce.h
View file @
82720675
...
@@ -95,12 +95,31 @@ typedef enum mce_cmd {
...
@@ -95,12 +95,31 @@ typedef enum mce_cmd {
MCE_CMD_ROC_FLUSH_CACHE
,
MCE_CMD_ROC_FLUSH_CACHE
,
MCE_CMD_ROC_CLEAN_CACHE
,
MCE_CMD_ROC_CLEAN_CACHE
,
MCE_CMD_ENABLE_LATIC
,
MCE_CMD_ENABLE_LATIC
,
MCE_CMD_UNCORE_PERFMON_REQ
,
MCE_CMD_IS_CCX_ALLOWED
=
0xFE
,
MCE_CMD_IS_CCX_ALLOWED
=
0xFE
,
MCE_CMD_MAX
=
0xFF
,
MCE_CMD_MAX
=
0xFF
,
}
mce_cmd_t
;
}
mce_cmd_t
;
#define MCE_CMD_MASK 0xFF
#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
* Macros to prepare CSTATE info request
******************************************************************************/
******************************************************************************/
...
@@ -183,6 +202,54 @@ typedef union mca_arg {
...
@@ -183,6 +202,54 @@ typedef union mca_arg {
uint64_t
data
;
uint64_t
data
;
}
mca_arg_t
;
}
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
* Structure populated by arch specific code to export routines which perform
* common low level MCE functions
* common low level MCE functions
...
@@ -313,6 +380,12 @@ typedef struct arch_mce_ops {
...
@@ -313,6 +380,12 @@ typedef struct arch_mce_ops {
* reset the entire system
* reset the entire system
*/
*/
void
(
*
enter_ccplex_state
)(
uint32_t
ari_base
,
uint32_t
state_idx
);
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
;
}
arch_mce_ops_t
;
int
mce_command_handler
(
mce_cmd_t
cmd
,
uint64_t
arg0
,
uint64_t
arg1
,
int
mce_command_handler
(
mce_cmd_t
cmd
,
uint64_t
arg0
,
uint64_t
arg1
,
...
@@ -322,6 +395,7 @@ int mce_update_gsc_videomem(void);
...
@@ -322,6 +395,7 @@ int mce_update_gsc_videomem(void);
int
mce_update_gsc_tzdram
(
void
);
int
mce_update_gsc_tzdram
(
void
);
int
mce_update_gsc_tzram
(
void
);
int
mce_update_gsc_tzram
(
void
);
__dead2
void
mce_enter_ccplex_state
(
uint32_t
state_idx
);
__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
);
void
mce_verify_firmware_version
(
void
);
/* declarations for ARI/NVG handler functions */
/* declarations for ARI/NVG handler functions */
...
@@ -344,6 +418,8 @@ int ari_roc_clean_cache(uint32_t ari_base);
...
@@ -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
);
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
);
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
);
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_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
,
int
nvg_update_cstate_info
(
uint32_t
ari_base
,
uint32_t
cluster
,
uint32_t
ccplex
,
...
...
plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
View file @
82720675
...
@@ -389,3 +389,41 @@ void ari_enter_ccplex_state(uint32_t ari_base, uint32_t state_idx)
...
@@ -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
);
(
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
;
}
plat/nvidia/tegra/soc/t186/drivers/mce/mce.c
View file @
82720675
...
@@ -42,6 +42,7 @@
...
@@ -42,6 +42,7 @@
#include <sys/errno.h>
#include <sys/errno.h>
#include <t18x_ari.h>
#include <t18x_ari.h>
#include <tegra_def.h>
#include <tegra_def.h>
#include <tegra_platform.h>
/* NVG functions handlers */
/* NVG functions handlers */
static
arch_mce_ops_t
nvg_mce_ops
=
{
static
arch_mce_ops_t
nvg_mce_ops
=
{
...
@@ -61,7 +62,8 @@ 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
,
.
roc_clean_cache
=
ari_roc_clean_cache
,
.
read_write_mca
=
ari_read_write_mca
,
.
read_write_mca
=
ari_read_write_mca
,
.
update_ccplex_gsc
=
ari_update_ccplex_gsc
,
.
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 */
/* ARI functions handlers */
...
@@ -82,7 +84,8 @@ static arch_mce_ops_t ari_mce_ops = {
...
@@ -82,7 +84,8 @@ static arch_mce_ops_t ari_mce_ops = {
.
roc_clean_cache
=
ari_roc_clean_cache
,
.
roc_clean_cache
=
ari_roc_clean_cache
,
.
read_write_mca
=
ari_read_write_mca
,
.
read_write_mca
=
ari_read_write_mca
,
.
update_ccplex_gsc
=
ari_update_ccplex_gsc
,
.
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
{
typedef
struct
mce_config
{
...
@@ -173,6 +176,7 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
...
@@ -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
;
uint64_t
ret64
=
0
,
arg3
,
arg4
,
arg5
;
int
ret
=
0
;
int
ret
=
0
;
mca_cmd_t
mca_cmd
;
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
);
...
@@ -374,6 +378,15 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
...
@@ -374,6 +378,15 @@ int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1,
break
;
break
;
#endif
#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:
default:
ERROR
(
"unknown MCE command (%d)
\n
"
,
cmd
);
ERROR
(
"unknown MCE command (%d)
\n
"
,
cmd
);
return
EINVAL
;
return
EINVAL
;
...
@@ -448,6 +461,19 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx)
...
@@ -448,6 +461,19 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx)
panic
();
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
* Handler to read the MCE firmware version and check if it is compatible
* with interface header the BL3-1 was compiled against
* with interface header the BL3-1 was compiled against
...
@@ -457,7 +483,13 @@ void mce_verify_firmware_version(void)
...
@@ -457,7 +483,13 @@ void mce_verify_firmware_version(void)
arch_mce_ops_t
*
ops
;
arch_mce_ops_t
*
ops
;
uint32_t
cpu_ari_base
;
uint32_t
cpu_ari_base
;
uint64_t
version
;
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 */
/* get a pointer to the CPU's arch_mce_ops_t struct */
ops
=
mce_get_curr_cpu_ops
();
ops
=
mce_get_curr_cpu_ops
();
...
@@ -476,17 +508,6 @@ void mce_verify_firmware_version(void)
...
@@ -476,17 +508,6 @@ void mce_verify_firmware_version(void)
INFO
(
"MCE Version - HW=%d:%d, SW=%d:%d
\n
"
,
major
,
minor
,
INFO
(
"MCE Version - HW=%d:%d, SW=%d:%d
\n
"
,
major
,
minor
,
TEGRA_ARI_VERSION_MAJOR
,
TEGRA_ARI_VERSION_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
* Verify that the MCE firmware version and the interface header
* match
* match
...
...
plat/nvidia/tegra/soc/t186/drivers/smmu/smmu.c
View file @
82720675
...
@@ -465,15 +465,42 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
...
@@ -465,15 +465,42 @@ void tegra_smmu_save_context(uint64_t smmu_ctx_addr)
(
uint32_t
)(
smmu_ctx_addr
>>
32
));
(
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
* Init SMMU during boot or "System Suspend" exit
*/
*/
void
tegra_smmu_init
(
void
)
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
=
tegra_smmu_read_32
(
SMMU_GSR0_SECURE_ACR
);
val
|=
SMMU_GSR0_PGSIZE_64K
;
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
);
tegra_smmu_write_32
(
SMMU_GSR0_SECURE_ACR
,
val
);
}
}
plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
View file @
82720675
...
@@ -37,6 +37,7 @@
...
@@ -37,6 +37,7 @@
#include <debug.h>
#include <debug.h>
#include <denver.h>
#include <denver.h>
#include <mce.h>
#include <mce.h>
#include <platform.h>
#include <psci.h>
#include <psci.h>
#include <smmu.h>
#include <smmu.h>
#include <string.h>
#include <string.h>
...
@@ -71,12 +72,9 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
...
@@ -71,12 +72,9 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
psci_power_state_t
*
req_state
)
psci_power_state_t
*
req_state
)
{
{
int
state_id
=
psci_get_pstate_id
(
power_state
)
&
TEGRA186_STATE_ID_MASK
;
int
state_id
=
psci_get_pstate_id
(
power_state
)
&
TEGRA186_STATE_ID_MASK
;
int
cpu
=
read_mpidr
()
&
MPIDR_CPU_MASK
;
int
cpu
=
plat_my_core_pos
();
int
impl
=
(
read_midr
()
>>
MIDR_IMPL_SHIFT
)
&
MIDR_IMPL_MASK
;
if
(
impl
==
DENVER_IMPL
)
cpu
|=
0x4
;
/* save the core wake time (us) */
wake_time
[
cpu
]
=
(
power_state
>>
TEGRA186_WAKE_TIME_SHIFT
)
&
wake_time
[
cpu
]
=
(
power_state
>>
TEGRA186_WAKE_TIME_SHIFT
)
&
TEGRA186_WAKE_TIME_MASK
;
TEGRA186_WAKE_TIME_MASK
;
...
@@ -84,10 +82,10 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
...
@@ -84,10 +82,10 @@ int32_t tegra_soc_validate_power_state(unsigned int power_state,
switch
(
state_id
)
{
switch
(
state_id
)
{
case
PSTATE_ID_CORE_IDLE
:
case
PSTATE_ID_CORE_IDLE
:
case
PSTATE_ID_CORE_POWERDN
:
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_AFFLVL0
]
=
state_id
;
req_state
->
pwr_domain_state
[
MPIDR_AFFLVL1
]
=
state_id
;
break
;
break
;
...
@@ -103,20 +101,12 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
...
@@ -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
;
const
plat_local_state_t
*
pwr_domain_state
;
unsigned
int
stateid_afflvl0
,
stateid_afflvl2
;
unsigned
int
stateid_afflvl0
,
stateid_afflvl2
;
int
cpu
=
read_mpidr
()
&
MPIDR_CPU_MASK
;
int
cpu
=
plat_my_core_pos
();
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
);
plat_params_from_bl2_t
*
params_from_bl2
=
bl31_get_plat_params
();
plat_params_from_bl2_t
*
params_from_bl2
=
bl31_get_plat_params
();
mce_cstate_info_t
cstate_info
=
{
0
};
uint64_t
smmu_ctx_base
;
uint64_t
smmu_ctx_base
;
uint32_t
val
;
uint32_t
val
;
assert
(
ctx
);
assert
(
gp_regs
);
if
(
impl
==
DENVER_IMPL
)
cpu
|=
0x4
;
/* get the state ID */
/* get the state ID */
pwr_domain_state
=
target_state
->
pwr_domain_state
;
pwr_domain_state
=
target_state
->
pwr_domain_state
;
stateid_afflvl0
=
pwr_domain_state
[
MPIDR_AFFLVL0
]
&
stateid_afflvl0
=
pwr_domain_state
[
MPIDR_AFFLVL0
]
&
...
@@ -124,29 +114,14 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
...
@@ -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
]
&
stateid_afflvl2
=
pwr_domain_state
[
PLAT_MAX_PWR_LVL
]
&
TEGRA186_STATE_ID_MASK
;
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 */
/* Enter CPU idle/powerdown */
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X4
,
0
);
val
=
(
stateid_afflvl0
==
PSTATE_ID_CORE_IDLE
)
?
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X5
,
TEGRA186_CORE_WAKE_MASK
);
TEGRA_ARI_CORE_C6
:
TEGRA_ARI_CORE_C7
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X6
,
1
);
(
void
)
mce_command_handler
(
MCE_CMD_ENTER_CSTATE
,
val
,
(
void
)
mce_command_handler
(
MCE_CMD_UPDATE_CSTATE_INFO
,
0
,
0
,
0
);
wake_time
[
cpu
],
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
);
}
else
if
(
stateid_afflvl2
==
PSTATE_ID_SOC_POWERDN
)
{
}
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)
...
@@ -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
);
tegra_smmu_save_context
((
uintptr_t
)
smmu_ctx_base
);
/* Prepare for system suspend */
/* Prepare for system suspend */
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X4
,
1
)
;
cstate_info
.
cluster
=
TEGRA_ARI_CLUSTER_CC7
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X5
,
0
)
;
cstate_info
.
system
=
TEGRA_ARI_SYSTEM_SC7
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X6
,
1
)
;
cstate_info
.
system_state_force
=
1
;
(
void
)
mce_command_handler
(
MCE_CMD_UPDATE_CSTATE_INFO
,
cstate_info
.
update_wake_mask
=
1
;
TEGRA_ARI_CLUSTER_CC7
,
0
,
TEGRA_ARI_SYSTEM_SC7
);
mce_update_cstate_info
(
&
cstate_info
);
/* Loop until system suspend is allowed */
/* Loop until system suspend is allowed */
do
{
do
{
...
@@ -187,15 +162,84 @@ int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
...
@@ -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 */
/* Instruct the MCE to enter system suspend state */
(
void
)
mce_command_handler
(
MCE_CMD_ENTER_CSTATE
,
(
void
)
mce_command_handler
(
MCE_CMD_ENTER_CSTATE
,
TEGRA_ARI_CORE_C7
,
MCE_CORE_SLEEP_TIME_INFINITE
,
0
);
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
;
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
)
int
tegra_soc_pwr_domain_power_down_wfi
(
const
psci_power_state_t
*
target_state
)
{
{
const
plat_local_state_t
*
pwr_domain_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)
...
@@ -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_afflvl2
=
target_state
->
pwr_domain_state
[
PLAT_MAX_PWR_LVL
];
int
stateid_afflvl0
=
target_state
->
pwr_domain_state
[
MPIDR_AFFLVL0
];
int
stateid_afflvl0
=
target_state
->
pwr_domain_state
[
MPIDR_AFFLVL0
];
cpu_context_t
*
ctx
=
cm_get_context
(
NON_SECURE
);
mce_cstate_info_t
cstate_info
=
{
0
};
gp_regs_t
*
gp_regs
=
get_gpregs_ctx
(
ctx
);
/*
/*
* Reset power state info for CPUs when onlining, we set
* 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)
...
@@ -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
)
{
if
(
stateid_afflvl0
==
PLAT_MAX_OFF_STATE
)
{
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X4
,
0
);
cstate_info
.
cluster
=
TEGRA_ARI_CLUSTER_CC1
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X5
,
0
);
cstate_info
.
update_wake_mask
=
1
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X6
,
1
);
mce_update_cstate_info
(
&
cstate_info
);
mce_command_handler
(
MCE_CMD_UPDATE_CSTATE_INFO
,
TEGRA_ARI_CLUSTER_CC1
,
0
,
0
);
}
}
/*
/*
...
@@ -280,15 +321,15 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
...
@@ -280,15 +321,15 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
tegra_smmu_init
();
tegra_smmu_init
();
/*
/*
* Reset power state info for the last core doing SC7 entry and exit,
* Reset power state info for the last core doing SC7
* we set deepest power state as CC7 and SC7 for SC7 entry which
* entry and exit, we set deepest power state as CC7
* may not be requested by non-secure SW which controls idle states.
* 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
);
cstate_info
.
cluster
=
TEGRA_ARI_CLUSTER_CC7
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X5
,
0
);
cstate_info
.
system
=
TEGRA_ARI_SYSTEM_SC1
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X6
,
1
);
cstate_info
.
update_wake_mask
=
1
;
(
void
)
mce_command_handler
(
MCE_CMD_UPDATE_CSTATE_INFO
,
mce_update_cstate_info
(
&
cstate_info
);
TEGRA_ARI_CLUSTER_CC7
,
0
,
TEGRA_ARI_SYSTEM_SC1
);
}
}
return
PSCI_E_SUCCESS
;
return
PSCI_E_SUCCESS
;
...
@@ -296,33 +337,22 @@ int tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state)
...
@@ -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
)
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
;
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 */
/* Disable Denver's DCO operations */
if
(
impl
==
DENVER_IMPL
)
if
(
impl
==
DENVER_IMPL
)
denver_disable_dco
();
denver_disable_dco
();
/* Turn off CPU */
/* 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
);
MCE_CORE_SLEEP_TIME_INFINITE
,
0
);
return
PSCI_E_SUCCESS
;
}
}
__dead2
void
tegra_soc_prepare_system_off
(
void
)
__dead2
void
tegra_soc_prepare_system_off
(
void
)
{
{
cpu_context_t
*
ctx
=
cm_get_context
(
NON_SECURE
);
mce_cstate_info_t
cstate_info
=
{
0
};
gp_regs_t
*
gp_regs
=
get_gpregs_ctx
(
ctx
);
uint32_t
val
;
uint32_t
val
;
if
(
tegra186_system_powerdn_state
==
TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF
)
{
if
(
tegra186_system_powerdn_state
==
TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF
)
{
...
@@ -333,11 +363,11 @@ __dead2 void tegra_soc_prepare_system_off(void)
...
@@ -333,11 +363,11 @@ __dead2 void tegra_soc_prepare_system_off(void)
}
else
if
(
tegra186_system_powerdn_state
==
TEGRA_ARI_SYSTEM_SC8
)
{
}
else
if
(
tegra186_system_powerdn_state
==
TEGRA_ARI_SYSTEM_SC8
)
{
/* Prepare for quasi power down */
/* Prepare for quasi power down */
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X4
,
1
)
;
cstate_info
.
cluster
=
TEGRA_ARI_CLUSTER_CC7
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X5
,
0
)
;
cstate_info
.
system
=
TEGRA_ARI_SYSTEM_SC8
;
write_ctx_reg
(
gp_regs
,
CTX_GPREG_X6
,
1
)
;
cstate_info
.
system_state_force
=
1
;
(
void
)
mce_command_handler
(
MCE_CMD_UPDATE_CSTATE_INFO
,
cstate_info
.
update_wake_mask
=
1
;
TEGRA_ARI_CLUSTER_CC7
,
0
,
TEGRA_ARI_SYSTEM_SC8
);
mce_update_cstate_info
(
&
cstate_info
);
/* loop until other CPUs power down */
/* loop until other CPUs power down */
do
{
do
{
...
@@ -357,6 +387,9 @@ __dead2 void tegra_soc_prepare_system_off(void)
...
@@ -357,6 +387,9 @@ __dead2 void tegra_soc_prepare_system_off(void)
/* power down core */
/* power down core */
prepare_cpu_pwr_dwn
();
prepare_cpu_pwr_dwn
();
/* flush L1/L2 data caches */
dcsw_op_all
(
DCCISW
);
}
else
{
}
else
{
ERROR
(
"%s: unsupported power down state (%d)
\n
"
,
__func__
,
ERROR
(
"%s: unsupported power down state (%d)
\n
"
,
__func__
,
tegra186_system_powerdn_state
);
tegra186_system_powerdn_state
);
...
...
plat/nvidia/tegra/soc/t186/plat_setup.c
View file @
82720675
...
@@ -30,19 +30,25 @@
...
@@ -30,19 +30,25 @@
#include <arch_helpers.h>
#include <arch_helpers.h>
#include <assert.h>
#include <assert.h>
#include <bl31.h>
#include <bl_common.h>
#include <bl_common.h>
#include <console.h>
#include <console.h>
#include <context.h>
#include <context.h>
#include <context_mgmt.h>
#include <context_mgmt.h>
#include <cortex_a57.h>
#include <debug.h>
#include <debug.h>
#include <denver.h>
#include <denver.h>
#include <interrupt_mgmt.h>
#include <interrupt_mgmt.h>
#include <mce.h>
#include <mce.h>
#include <platform.h>
#include <platform.h>
#include <tegra_def.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
#include <tegra_private.h>
#include <xlat_tables.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
* 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
* single root node. The first entry in the power domain descriptor specifies
...
@@ -72,7 +78,13 @@ static const mmap_region_t tegra_mmap[] = {
...
@@ -72,7 +78,13 @@ static const mmap_region_t tegra_mmap[] = {
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
TEGRA_MC_BASE
,
0x10000
,
/* 64KB */
MAP_REGION_FLAT
(
TEGRA_MC_BASE
,
0x10000
,
/* 64KB */
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
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
),
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MAP_REGION_FLAT
(
TEGRA_GICD_BASE
,
0x20000
,
/* 128KB */
MAP_REGION_FLAT
(
TEGRA_GICD_BASE
,
0x20000
,
/* 128KB */
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
MT_DEVICE
|
MT_RW
|
MT_SECURE
),
...
@@ -142,6 +154,51 @@ uint32_t plat_get_console_from_id(int id)
...
@@ -142,6 +154,51 @@ uint32_t plat_get_console_from_id(int id)
return
tegra186_uart_addresses
[
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 */
/* Secure IRQs for Tegra186 */
static
const
irq_sec_cfg_t
tegra186_sec_irqs
[]
=
{
static
const
irq_sec_cfg_t
tegra186_sec_irqs
[]
=
{
{
{
...
@@ -173,9 +230,25 @@ void plat_gic_setup(void)
...
@@ -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
;
}
}
plat/nvidia/tegra/soc/t186/plat_sip_calls.c
View file @
82720675
...
@@ -65,6 +65,7 @@ extern uint32_t tegra186_system_powerdn_state;
...
@@ -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_FLUSH_CACHE 0x82FFFF0E
#define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0x82FFFF0F
#define TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE 0x82FFFF0F
#define TEGRA_SIP_MCE_CMD_ENABLE_LATIC 0x82FFFF10
#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
* This function is responsible for handling all T186 SiP calls
...
@@ -102,6 +103,7 @@ int plat_sip_handler(uint32_t smc_fid,
...
@@ -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_FLUSH_CACHE
:
case
TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE
:
case
TEGRA_SIP_MCE_CMD_ROC_CLEAN_CACHE
:
case
TEGRA_SIP_MCE_CMD_ENABLE_LATIC
:
case
TEGRA_SIP_MCE_CMD_ENABLE_LATIC
:
case
TEGRA_SIP_MCE_CMD_UNCORE_PERFMON_REQ
:
/* clean up the high bits */
/* clean up the high bits */
smc_fid
&=
MCE_CMD_MASK
;
smc_fid
&=
MCE_CMD_MASK
;
...
@@ -112,32 +114,6 @@ int plat_sip_handler(uint32_t smc_fid,
...
@@ -112,32 +114,6 @@ int plat_sip_handler(uint32_t smc_fid,
return
0
;
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
:
case
TEGRA_SIP_SYSTEM_SHUTDOWN_STATE
:
/* clean up the high bits */
/* clean up the high bits */
...
...
plat/nvidia/tegra/soc/t186/platform_t186.mk
View file @
82720675
...
@@ -32,9 +32,18 @@
...
@@ -32,9 +32,18 @@
ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
:=
1
ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
:=
1
$(eval
$(call
add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
$(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
ENABLE_CHIP_VERIFICATION_HARNESS
:=
0
$(eval
$(call
add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
$(eval
$(call
add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
RESET_TO_BL31
:=
1
PROGRAMMABLE_RESET_ADDRESS
:=
1
COLD_BOOT_SINGLE_CPU
:=
1
# platform settings
# platform settings
TZDRAM_BASE
:=
0x30000000
TZDRAM_BASE
:=
0x30000000
$(eval
$(call
add_define,TZDRAM_BASE))
$(eval
$(call
add_define,TZDRAM_BASE))
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment