/*
 * Copyright (c) 2018, Arm Limited. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef __PLAT_TOPOLOGY_H__
#define __PLAT_TOPOLOGY_H__

#include <arch.h>
#include <platform_def.h>
#include <stdint.h>

/*
 * This is the initial value of the power domain index when used
 * as argument to the tftf topology helpers. They are also used
 * to indicate the end of iterative topology navigation when returned
 * by the tftf topology helpers.
 */
#define PWR_DOMAIN_INIT		((unsigned int) -1)

/*
 * Return the total number of clusters in the system.
 * Currently there is correspondence between power level and affinity
 * level and hence cluster power level corresponds to affinity level 1.
 */
#define tftf_get_total_clusters_count()		tftf_get_total_aff_count(1)

/*
 * Return the total number of CPUs in the system (across all clusters).
 * Currently there is correspondence between power level and affinity
 * level and hence CPU power level correspond to affinity level 0.
 */
#define tftf_get_total_cpus_count()		tftf_get_total_aff_count(0)

/*
 * Converts a 'core_pos' into an MPIDR. The 'core_pos' is a unique number
 * corresponding to a CPU as returned by platform_get_core_pos() API
 */
#define tftf_core_pos_to_mpidr(core_pos)	\
			tftf_get_mpidr_from_node(core_pos + tftf_pwr_domain_start_idx[0])

/*
 * The following array stores the start index of each level in the power
 * domain topology tree.
 */
extern unsigned int tftf_pwr_domain_start_idx[PLATFORM_MAX_AFFLVL + 1];

/*
 * The following data structure represents a TFTF power domain node.
 */
typedef struct tftf_pwr_domain_node {
	/*
	 * Array index of the first CPU in the topology array for which this
	 * power domain is the parent. If this power domain is a CPU, then
	 * `cpu_start_node` will be its own index in the power domain
	 * topology array.
	 */
	unsigned int cpu_start_node;

	/*
	 * Number of CPU power domains which belong to this power domain.
	 * i.e. all the CPUs in the range 'cpu_start_node
	 * -> cpu_start_node + ncpus - 1 ' will belong to this power domain.
	 * If this power domain is a CPU then 'ncpus' will be 1.
	 */
	unsigned int ncpus;

	/* Valid only for CPU power domains */
	unsigned int mpidr;

	/* Index of the parent power domain node */
	unsigned int parent_node;

	/*
	 * The level of this power domain node in the power domain topology
	 * tree. It could correspond to the affinity level but the platform
	 * could have power levels which do not match affinity levels.
	 */
	unsigned int level;

	/*
	 * The 'is_present' field is used to cater for power domains
	 * which are absent.
	 */
	unsigned char is_present;
} tftf_pwr_domain_node_t;

extern tftf_pwr_domain_node_t tftf_pd_nodes[PLATFORM_NUM_AFFS];

/*
 * Detect and store the platform topology so that test cases can query it later.
 */
void tftf_init_topology(void);

/*
 * Return the number of affinity instances implemented at the affinity level
 * passed as an argument. This function returns 0 for any other affinity
 * level higher than that supported by the platform.
 */
unsigned int tftf_get_total_aff_count(unsigned int aff_lvl);

/*
 * Returns the index of the next power domain after `pwr_domain_idx`
 * in the topology tree at the same `aff_lvl`. The `pwr_domain_idx`
 * has to be initialized to PWR_DOMAIN_INIT to get the first entry.
 * It returns PWR_DOMAIN_INIT if none is found.
 */
unsigned int tftf_get_next_peer_domain(unsigned int pwr_domain_idx,
				      unsigned int pwr_lvl);

/*
 * Returns the index of the next CPU after the current CPU `cpu_node`
 * which belongs to the power domain `pwr_domain_idx`. The `cpu_node`
 * has to be initialized to PWR_DOMAIN_INIT to get the first entry.
 * It returns PWR_DOMAIN_INIT if none is found.
 */
unsigned int tftf_get_next_cpu_in_pwr_domain(unsigned int pwr_domain_idx,
				      unsigned int cpu_node);

/*
 * Return the node index of the next CPU after 'cpu_node' in the topology tree.
 * Skip absent CPUs.
 * cpu_node: Node index of the current CPU.
 */
unsigned int tftf_topology_next_cpu(unsigned int cpu_node);

/*
 * Iterate over every CPU. Skip absent CPUs.
 * cpu: unsigned integer corresponding to the index of the cpu in
 * the topology array.
 */
#define for_each_cpu(cpu)					\
	for (cpu = tftf_topology_next_cpu(PWR_DOMAIN_INIT);	\
		cpu != PWR_DOMAIN_INIT;				\
		cpu = tftf_topology_next_cpu(cpu))

/*
 * Iterate over every power domain idx for a given level.
 * - idx: unsigned integer corresponding to the power domain index.
 * - lvl: level
 */
#define for_each_power_domain_idx(idx, lvl)				\
	for (idx = tftf_get_next_peer_domain(PWR_DOMAIN_INIT, (lvl));	\
		idx != PWR_DOMAIN_INIT;					\
		idx = tftf_get_next_peer_domain(idx, (lvl)))

/*
 * Iterate over every CPU in a power domain idx.
 * - cpu_idx: CPU index.
 * - pwr_domain_idx: unsigned integer corresponding to the power domain index.
 */
#define for_each_cpu_in_power_domain(cpu_idx, pwr_domain_idx)		\
	for (cpu_idx = tftf_get_next_cpu_in_pwr_domain(			\
			(pwr_domain_idx), PWR_DOMAIN_INIT);		\
		cpu_idx != PWR_DOMAIN_INIT;				\
		cpu_idx = tftf_get_next_cpu_in_pwr_domain(		\
			(pwr_domain_idx), cpu_idx))

/*
 * Returns the MPIDR of the CPU power domain node indexed by `cpu_node`
 * or INVALID_MPID if it is absent.
 */
unsigned int tftf_get_mpidr_from_node(unsigned int cpu_node);


/*
 * Returns the index corresponding to the parent power domain at `pwrlvl` of the
 * CPU specified by `mpidr`. Returns POWER_DOMAIN_INIT if any of input arguments
 * are incorrect.
 */
unsigned int tftf_get_parent_node_from_mpidr(unsigned int mpidr,
		unsigned int pwrlvl);


/*
 * Query the platform topology to find another CPU than the one specified
 * as an argument.
 * Return the MPID of this other CPU, or INVALID_MPID if none could be found.
 */
unsigned int tftf_find_any_cpu_other_than(unsigned int exclude_mpid);

/*
 * Query the platform topology to find a random CPU other than the one specified
 * as an argument.
 * The difference between this function and tftf_find_any_cpu_other_than is
 * the randomness in selecting a CPU.
 * Return the MPID of this other CPU, or INVALID_MPID if none could be found.
 */
unsigned int tftf_find_random_cpu_other_than(unsigned int exclude_mpid);

#endif /* __PLAT_TOPOLOGY_H__ */
