Commit ae8ac2d2 authored by Varun Wadekar's avatar Varun Wadekar
Browse files

Tegra: allow platforms to override plat_core_pos_by_mpidr()



This patch makes the default implementation of plat_core_pos_by_mpidr()
as weakly linked, so that platforms can override it with their own.

Tegra186, for one, does not have CPU IDs 2 and 3, so it has its own
implementation of plat_core_pos_by_mpidr().

Change-Id: I7a5319869c01ede3775386cb95af1431792f74b3
Signed-off-by: default avatarVarun Wadekar <vwadekar@nvidia.com>
parent 06803cfd
/* /*
* Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <psci.h> #include <psci.h>
extern const unsigned char tegra_power_domain_tree_desc[]; extern const unsigned char tegra_power_domain_tree_desc[];
#pragma weak plat_core_pos_by_mpidr
/******************************************************************************* /*******************************************************************************
* This function returns the Tegra default topology tree information. * This function returns the Tegra default topology tree information.
...@@ -52,23 +53,18 @@ int plat_core_pos_by_mpidr(u_register_t mpidr) ...@@ -52,23 +53,18 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
{ {
unsigned int cluster_id, cpu_id; unsigned int cluster_id, cpu_id;
mpidr &= MPIDR_AFFINITY_MASK;
if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
return -1;
cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
if (cluster_id >= PLATFORM_CLUSTER_COUNT) if (cluster_id >= PLATFORM_CLUSTER_COUNT)
return -1; return PSCI_E_NOT_PRESENT;
/* /*
* Validate cpu_id by checking whether it represents a CPU in * Validate cpu_id by checking whether it represents a CPU in
* one of the two clusters present on the platform. * one of the two clusters present on the platform.
*/ */
if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
return -1; return PSCI_E_NOT_PRESENT;
return (cpu_id + (cluster_id * 4)); return (cpu_id + (cluster_id * 4));
} }
...@@ -49,6 +49,13 @@ ...@@ -49,6 +49,13 @@
DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1) DEFINE_RENAME_SYSREG_RW_FUNCS(l2ctlr_el1, L2CTLR_EL1)
extern uint64_t tegra_enable_l2_ecc_parity_prot; extern uint64_t tegra_enable_l2_ecc_parity_prot;
/*******************************************************************************
* Tegra186 CPU numbers in cluster #0
*******************************************************************************
*/
#define TEGRA186_CLUSTER0_CORE2 2
#define TEGRA186_CLUSTER0_CORE3 3
/******************************************************************************* /*******************************************************************************
* 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
...@@ -256,3 +263,40 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void) ...@@ -256,3 +263,40 @@ plat_params_from_bl2_t *plat_get_bl31_plat_params(void)
return (plat_params_from_bl2_t *)(uintptr_t)val; return (plat_params_from_bl2_t *)(uintptr_t)val;
} }
/*******************************************************************************
* This function implements a part of the critical interface between the psci
* generic layer and the platform that allows the former to query the platform
* to convert an MPIDR to a unique linear index. An error code (-1) is returned
* in case the MPIDR is invalid.
******************************************************************************/
int plat_core_pos_by_mpidr(u_register_t mpidr)
{
unsigned int cluster_id, cpu_id, pos;
cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
/*
* Validate cluster_id by checking whether it represents
* one of the two clusters present on the platform.
*/
if (cluster_id >= PLATFORM_CLUSTER_COUNT)
return PSCI_E_NOT_PRESENT;
/*
* Validate cpu_id by checking whether it represents a CPU in
* one of the two clusters present on the platform.
*/
if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER)
return PSCI_E_NOT_PRESENT;
/* calculate the core position */
pos = cpu_id + (cluster_id << 2);
/* check for non-existent CPUs */
if (pos == TEGRA186_CLUSTER0_CORE2 || pos == TEGRA186_CLUSTER0_CORE3)
return PSCI_E_NOT_PRESENT;
return pos;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment