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

#ifndef __PLATFORM_H__
#define __PLATFORM_H__

#include <stdint.h>
#include <timer.h>
#include <xlat_tables_v2.h>

#define PLAT_PSCI_DUMMY_STATE_ID		0xF

#define PWR_STATE_INIT_INDEX			(-1)

#define INIT_PWR_LEVEL_INDEX(array_name)					\
	do {									\
		unsigned int var;						\
		assert(ARRAY_SIZE(array_name) == (PLAT_MAX_PWR_LEVEL + 1));	\
		for (var = 0; var <= PLAT_MAX_PWR_LEVEL; var++)			\
			array_name[var] = PWR_STATE_INIT_INDEX;			\
	} while (0)

/*
 * The platform structure to represent the valid local power state
 * properties for a particular affinity level. The platform needs to
 * export the array of valid local low power states for each affinity level
 * it supports which can be queried by TFTF tests to construct the required
 * composite power state.
 *
 * TODO: Currently the power levels are identity mapped to affinity level in
 * TFTF which need to be decoupled.
 */
typedef struct plat_state_prop {
	/*
	 * This field has a value in the increasing order of the suspend
	 * depth. Deeper the suspend state, higher the value.
	 */
	unsigned int suspend_depth;
	/* The local state ID for the idle state at this level. */
	unsigned int state_ID;
	/* Flag which indicates whether is a retention or power down state */
	unsigned int is_pwrdown;
} plat_state_prop_t;

void tftf_plat_arch_setup(void);
void tftf_early_platform_setup(void);
void tftf_platform_setup(void);

void tftf_plat_enable_mmu(void);
void tftf_plat_configure_mmu(void);

void tftf_platform_end(void);
void tftf_platform_watchdog_set(void);
void tftf_platform_watchdog_reset(void);

/* Helper that returns a linear core ID from a MPID */
unsigned int platform_get_core_pos(u_register_t mpid);

/* Crash console functions */
int plat_crash_console_init(void);
int plat_crash_console_putc(int c);
int plat_crash_console_flush(void);

/* Gets a handle for the initialised IO entity */
void plat_get_nvm_handle(uintptr_t *handle);

/* Initialize and get a pointer to a uint64_t[2] array with a 128-key */
uint64_t *plat_init_apiakey(void);

/*
 * Returns the platform topology description array. The size of this
 * array should be PLATFORM_NUM_AFFS - PLATFORM_CORE_COUNT + 1.
 */
const unsigned char *tftf_plat_get_pwr_domain_tree_desc(void);

/*
 * Function to query the MPIDR of a CPU identified by 'core_pos' which is
 * the number returned by platform_get_core() API.
 * In case the CPU is absent, then this API returns INVALID_MPID. This
 * function will be queried only during topology setup in TFTF and thereafter
 * the internal node data will be used to get the MPIDR corresponding
 * to the 'core_pos'.
 */
uint64_t tftf_plat_get_mpidr(unsigned int core_pos);

/*
 * Get the state property array for all the valid states from platform for
 * a specified 'level'. The array is expected to be NULL terminated after the
 * last entry.
 */
const plat_state_prop_t *plat_get_state_prop(unsigned int level);

/*
 * Initialises state info data structures for generating various combinations
 * of state ID's. It also calls tftf_detect_pstate_format() which detects the
 * PSTATE format accepted by EL3 firmware.
 * This function needs to be invoked once during cold boot prior to the
 * invocation of any PSCI power state helper functions.
 */
void tftf_init_pstate_framework(void);

/*
 * This function is used to generate all possible combinations of composite
 * state ID's possible for a given set of power states at each level.
 * Ex: If a system implements 4 levels and each level has 3 local power states.
 * Then, the total combinations of composite power down states possible are:
 *                                                       3 * 3 * 3 * 3 = 81
 *
 * A single call to set_next_state_id_pointers(), sets pointer to pstate_id_idx
 * at all levels for a possible combination out of 81.
 *
 * A caller can confirm when all combinations are completed by checking if
 * pwr_lvel_state_indexes for power_level 0 is PWR_STATE_INIT_INDEX
 */
void tftf_set_next_state_id_idx(unsigned int power_level,
					unsigned int pstate_id_idx[]);

/*
 * This function sets the index for the next state ID of the given power level
 */
void tftf_set_next_local_state_id_idx(unsigned int power_level,
					unsigned int pstate_id_idx[]);

/*
 * This function sets the index corresponding to the deepest power state at
 * a given power level.
 */
void tftf_set_deepest_pstate_idx(unsigned int power_level,
				unsigned int pstate_id_idx[]);

/*
 * Helper function to get the state ID, state type, power level in power_state
 * parameter of CPU_SUSPEND. The generated values are based on the
 * pstate_id_idx values of a core.
 *
 * This helper expects a valid pstate_id_idx till the max valid levels
 * and it detects the max valid level to be terminated by PWR_STATE_INIT value
 *
 * It returns the expected PSCI return value of a suspend request
 */
int tftf_get_pstate_vars(unsigned int *test_power_level,
				unsigned int *test_suspend_type,
				unsigned int *suspend_state_id,
				unsigned int pstate_id_idx[]);

/*
 * This function gets the platform specific timer driver information and
 * initialises platform specific drivers.
 * Returns 0 on success.
 */
int plat_initialise_timer_ops(const plat_timer_t **timer_ops);

struct mem_region {
	uintptr_t addr;
	size_t size;
};

typedef struct mem_region mem_region_t;

/*******************************************************************************
 * Optional functions. A default, weak implementation of those functions is
 * provided, it may be overridden by platform code.
 ******************************************************************************/
unsigned long platform_get_stack(unsigned long mpidr);
/*
 * plat_get_prot_regions: It returns a pointer to a
 * set of regions used to test mem_protect_check.
 * The number of elements are stored in the variable
 *  pointed by nelem.
 */
const mem_region_t *plat_get_prot_regions(int *nelem);

void tftf_plat_reset(void);

const mmap_region_t *tftf_platform_get_mmap(void);

/*
 * Return an IO device handle and specification which can be used
 * to access an image. Use this to enforce platform load policy.
 */
int plat_get_image_source(unsigned int image_id,
		uintptr_t *dev_handle,
		uintptr_t *image_spec);

void plat_fwu_io_setup(void);

#endif /* __PLATFORM_H__ */
