Tegra186: read activity monitor's clock counter values

This patch adds a new SMC function ID to read the refclk and coreclk
clock counter values from the Activity Monitor. The non-secure world
requires this information to calculate the CPU's frequency.

Formula: "freq = (delta_coreclk / delta_refclk) * refclk_freq"

The following CPU registers have to be set by the non-secure driver
before issuing the SMC:

X1 = MPIDR of the target core
X2 = MIDR of the target core

Change-Id: I296d835def1f5788c17640c0c456b8f8f0e90824
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
This commit is contained in:
Varun Wadekar 2016-09-23 14:28:16 -07:00
parent e698a822f0
commit 691bc22de9
4 changed files with 50 additions and 4 deletions

View File

@ -261,10 +261,16 @@
#define SECURE_SCRATCH_RSV55_HI 0x80C
/*******************************************************************************
* Tegra Memory Mapped Control Register Access Bus constants
* Tegra Memory Mapped Control Register Access constants
******************************************************************************/
#define TEGRA_MMCRAB_BASE 0x0E000000
/*******************************************************************************
* Tegra Memory Mapped Activity Monitor Register Access constants
******************************************************************************/
#define TEGRA_ARM_ACTMON_CTR_BASE 0x0E060000
#define TEGRA_DENVER_ACTMON_CTR_BASE 0x0E070000
/*******************************************************************************
* Tegra SMMU Controller constants
******************************************************************************/

View File

@ -102,6 +102,8 @@ static const mmap_region_t tegra_mmap[] = {
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_MMCRAB_BASE, 0x60000, /* 384KB */
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_ARM_ACTMON_CTR_BASE, 0x20000, /* 128KB - ARM/Denver */
MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(TEGRA_SMMU_BASE, 0x1000000, /* 64KB */
MT_DEVICE | MT_RW | MT_SECURE),
{0}

View File

@ -34,6 +34,7 @@
#include <bl_common.h>
#include <context_mgmt.h>
#include <debug.h>
#include <denver.h>
#include <errno.h>
#include <mce.h>
#include <memctrl.h>
@ -43,11 +44,16 @@
extern uint32_t tegra186_system_powerdn_state;
/*******************************************************************************
* Offset to read the ref_clk counter value
******************************************************************************/
#define REF_CLK_OFFSET 4
/*******************************************************************************
* Tegra186 SiP SMCs
******************************************************************************/
#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003
#define TEGRA_SIP_SYSTEM_SHUTDOWN_STATE 0x82FFFE01
#define TEGRA_SIP_GET_ACTMON_CLK_COUNTERS 0x82FFFE02
#define TEGRA_SIP_MCE_CMD_ENTER_CSTATE 0x82FFFF00
#define TEGRA_SIP_MCE_CMD_UPDATE_CSTATE_INFO 0x82FFFF01
#define TEGRA_SIP_MCE_CMD_UPDATE_CROSSOVER_TIME 0x82FFFF02
@ -81,6 +87,8 @@ int plat_sip_handler(uint32_t smc_fid,
uint64_t flags)
{
int mce_ret;
int impl, cpu;
uint32_t base, core_clk_ctr, ref_clk_ctr;
switch (smc_fid) {
@ -143,6 +151,36 @@ int plat_sip_handler(uint32_t smc_fid,
return 0;
/*
* This function ID reads the Activity monitor's core/ref clock
* counter values for a core/cluster.
*
* x1 = MPIDR of the target core
* x2 = MIDR of the target core
*/
case TEGRA_SIP_GET_ACTMON_CLK_COUNTERS:
cpu = (uint32_t)x1 & MPIDR_CPU_MASK;
impl = ((uint32_t)x2 >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK;
/* sanity check target CPU number */
if (cpu > PLATFORM_MAX_CPUS_PER_CLUSTER)
return -EINVAL;
/* get the base address for the current CPU */
base = (impl == DENVER_IMPL) ? TEGRA_DENVER_ACTMON_CTR_BASE :
TEGRA_ARM_ACTMON_CTR_BASE;
/* read the clock counter values */
core_clk_ctr = mmio_read_32(base + (8 * cpu));
ref_clk_ctr = mmio_read_32(base + (8 * cpu) + REF_CLK_OFFSET);
/* return the counter values as two different parameters */
write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, core_clk_ctr);
write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, ref_clk_ctr);
return 0;
default:
break;
}

View File

@ -57,10 +57,10 @@ $(eval $(call add_define,PLATFORM_CLUSTER_COUNT))
PLATFORM_MAX_CPUS_PER_CLUSTER := 4
$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
MAX_XLAT_TABLES := 20
MAX_XLAT_TABLES := 24
$(eval $(call add_define,MAX_XLAT_TABLES))
MAX_MMAP_REGIONS := 20
MAX_MMAP_REGIONS := 24
$(eval $(call add_define,MAX_MMAP_REGIONS))
# platform files