/*
 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <assert.h>
#include <errno.h>
#include <stdbool.h>

#include <arch.h>
#include <common/debug.h>
#include <drivers/arm/ccn.h>
#include <lib/bakery_lock.h>
#include <lib/mmio.h>

#include "ccn_private.h"

static const ccn_desc_t *ccn_plat_desc;
#if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
DEFINE_BAKERY_LOCK(ccn_lock);
#endif

/*******************************************************************************
 * This function takes the base address of the CCN's programmer's view (PV), a
 * region ID of one of the 256 regions (0-255) and a register offset within the
 * region. It converts the first two parameters into a base address and uses it
 * to read the register at the offset.
 ******************************************************************************/
static inline unsigned long long ccn_reg_read(uintptr_t periphbase,
			     unsigned int region_id,
			     unsigned int register_offset)
{
	uintptr_t region_base;

	assert(periphbase);
	assert(region_id < REGION_ID_LIMIT);

	region_base = periphbase + region_id_to_base(region_id);
	return mmio_read_64(region_base + register_offset);
}

/*******************************************************************************
 * This function takes the base address of the CCN's programmer's view (PV), a
 * region ID of one of the 256 regions (0-255), a register offset within the
 * region and a value. It converts the first two parameters into a base address
 * and uses it to write the value in the register at the offset.
 ******************************************************************************/
static inline void ccn_reg_write(uintptr_t periphbase,
			  unsigned int region_id,
			  unsigned int register_offset,
			  unsigned long long value)
{
	uintptr_t region_base;

	assert(periphbase);
	assert(region_id < REGION_ID_LIMIT);

	region_base = periphbase + region_id_to_base(region_id);
	mmio_write_64(region_base + register_offset, value);
}

#if ENABLE_ASSERTIONS

typedef struct rn_info {
		unsigned char node_desc[MAX_RN_NODES];
	} rn_info_t;

/*******************************************************************************
 * This function takes the base address of the CCN's programmer's view (PV) and
 * the node ID of a Request Node (RN-D or RN-I). It returns the maximum number
 * of master interfaces resident on that node. This number is equal to the least
 * significant two bits of the node type ID + 1.
 ******************************************************************************/
static unsigned int ccn_get_rni_mcount(uintptr_t periphbase,
				       unsigned int rn_id)
{
	unsigned int rn_type_id;

	/* Use the node id to find the type of RN-I/D node */
	rn_type_id = get_node_type(ccn_reg_read(periphbase,
						rn_id + RNI_REGION_ID_START,
						REGION_ID_OFFSET));

	/* Return the number master interfaces based on node type */
	return rn_type_id_to_master_cnt(rn_type_id);
}

/*******************************************************************************
 * This function reads the CCN registers to find the following information about
 * the ACE/ACELite/ACELite+DVM/CHI interfaces resident on the various types of
 * Request Nodes (RN-Fs, RN-Is and RN-Ds) in the system:
 *
 * 1. The total number of such interfaces that this CCN IP supports. This is the
 *    cumulative number of interfaces across all Request node types. It is
 *    passed back as the return value of this function.
 *
 * 2. The maximum number of interfaces of a type resident on a Request node of
 *    one of the three types. This information is populated in the 'info'
 *    array provided by the caller as described next.
 *
 *    The array has 64 entries. Each entry corresponds to a Request node. The
 *    Miscellaneous node's programmer's view has RN-F, RN-I and RN-D ID
 *    registers. For each RN-I and RN-D ID indicated as being present in these
 *    registers, its identification register (offset 0xFF00) is read. This
 *    register specifies the maximum number of master interfaces the node
 *    supports. For RN-Fs it is assumed that there can be only a single fully
 *    coherent master resident on each node. The counts for each type of node
 *    are use to populate the array entry at the index corresponding to the node
 *    ID i.e. rn_info[node ID] = <number of master interfaces>
 ******************************************************************************/
static unsigned int ccn_get_rn_master_info(uintptr_t periphbase,
					   rn_info_t *info)
{
	unsigned int num_masters = 0;
	rn_types_t rn_type;

	assert (info);

	for (rn_type = RN_TYPE_RNF; rn_type < NUM_RN_TYPES; rn_type++) {
		unsigned int mn_reg_off, node_id;
		unsigned long long rn_bitmap;

		/*
		 * RN-F, RN-I, RN-D node registers in the MN region occupy
		 * contiguous 16 byte apart offsets.
		 */
		mn_reg_off = MN_RNF_NODEID_OFFSET + (rn_type << 4);
		rn_bitmap = ccn_reg_read(periphbase, MN_REGION_ID, mn_reg_off);

		FOR_EACH_PRESENT_NODE_ID(node_id, rn_bitmap) {
			unsigned int node_mcount;

			/*
			 * A RN-F does not have a node type since it does not
			 * export a programmer's interface. It can only have a
			 * single fully coherent master residing on it. If the
			 * offset of the MN(Miscellaneous Node) register points
			 * to a RN-I/D node then the master count is set to the
			 * maximum number of master interfaces that can possibly
			 * reside on the node.
			 */
			node_mcount = (mn_reg_off == MN_RNF_NODEID_OFFSET ? 1 :
				       ccn_get_rni_mcount(periphbase, node_id));

			/*
			 * Use this value to increment the maximum possible
			 * master interfaces in the system.
			 */
			num_masters += node_mcount;

			/*
			 * Update the entry in 'info' for this node ID with
			 * the maximum number of masters than can sit on
			 * it. This information will be used to validate the
			 * node information passed by the platform later.
			 */
			info->node_desc[node_id] = node_mcount;
		}
	}

	return num_masters;
}

/*******************************************************************************
 * This function validates parameters passed by the platform (in a debug build).
 * It collects information about the maximum number of master interfaces that:
 * a) the CCN IP can accommodate and
 * b) can exist on each Request node.
 * It compares this with the information provided by the platform to determine
 * the validity of the latter.
 ******************************************************************************/
static void __init ccn_validate_plat_params(const ccn_desc_t *plat_desc)
{
	unsigned int master_id, num_rn_masters;
	rn_info_t info = { {0} };

	assert(plat_desc);
	assert(plat_desc->periphbase);
	assert(plat_desc->master_to_rn_id_map);
	assert(plat_desc->num_masters);
	assert(plat_desc->num_masters < CCN_MAX_RN_MASTERS);

	/*
	 * Find the number and properties of fully coherent, IO coherent and IO
	 * coherent + DVM master interfaces
	 */
	num_rn_masters = ccn_get_rn_master_info(plat_desc->periphbase, &info);
	assert(plat_desc->num_masters < num_rn_masters);

	/*
	 * Iterate through the Request nodes specified by the platform.
	 * Decrement the count of the masters in the 'info' array for each
	 * Request node encountered. If the count would drop below 0 then the
	 * platform's view of this aspect of CCN configuration is incorrect.
	 */
	for (master_id = 0; master_id < plat_desc->num_masters; master_id++) {
		unsigned int node_id;

		node_id = plat_desc->master_to_rn_id_map[master_id];
		assert(node_id < MAX_RN_NODES);
		assert(info.node_desc[node_id]);
		info.node_desc[node_id]--;
	}
}
#endif /* ENABLE_ASSERTIONS */

/*******************************************************************************
 * This function validates parameters passed by the platform (in a debug build)
 * and initialises its internal data structures. A lock is required to prevent
 * simultaneous CCN operations at runtime (only BL31) to add and remove Request
 * nodes from coherency.
 ******************************************************************************/
void __init ccn_init(const ccn_desc_t *plat_desc)
{
#if ENABLE_ASSERTIONS
	ccn_validate_plat_params(plat_desc);
#endif

	ccn_plat_desc = plat_desc;
}

/*******************************************************************************
 * This function converts a bit map of master interface IDs to a bit map of the
 * Request node IDs that they reside on.
 ******************************************************************************/
static unsigned long long ccn_master_to_rn_id_map(unsigned long long master_map)
{
	unsigned long long rn_id_map = 0;
	unsigned int node_id, iface_id;

	assert(master_map);
	assert(ccn_plat_desc);

	FOR_EACH_PRESENT_MASTER_INTERFACE(iface_id, master_map) {
		assert(iface_id < ccn_plat_desc->num_masters);

		/* Convert the master ID into the node ID */
		node_id = ccn_plat_desc->master_to_rn_id_map[iface_id];

		/* Set the bit corresponding to this node ID */
		rn_id_map |= (1ULL << node_id);
	}

	return rn_id_map;
}

/*******************************************************************************
 * This function executes the necessary operations to add or remove Request node
 * IDs specified in the 'rn_id_map' bitmap from the snoop/DVM domains specified
 * in the 'hn_id_map'. The 'region_id' specifies the ID of the first HN-F/MN
 * on which the operation should be performed. 'op_reg_offset' specifies the
 * type of operation (add/remove). 'stat_reg_offset' specifies the register
 * which should be polled to determine if the operation has completed or not.
 ******************************************************************************/
static void ccn_snoop_dvm_do_op(unsigned long long rn_id_map,
				unsigned long long hn_id_map,
				unsigned int region_id,
				unsigned int op_reg_offset,
				unsigned int stat_reg_offset)
{
	unsigned int start_region_id;

	assert(ccn_plat_desc);
	assert(ccn_plat_desc->periphbase);

#if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
	bakery_lock_get(&ccn_lock);
#endif
	start_region_id = region_id;
	FOR_EACH_PRESENT_REGION_ID(start_region_id, hn_id_map) {
		ccn_reg_write(ccn_plat_desc->periphbase,
			      start_region_id,
			      op_reg_offset,
			      rn_id_map);
	}

	start_region_id = region_id;

	FOR_EACH_PRESENT_REGION_ID(start_region_id, hn_id_map) {
		WAIT_FOR_DOMAIN_CTRL_OP_COMPLETION(start_region_id,
						   stat_reg_offset,
						   op_reg_offset,
						   rn_id_map);
	}

#if defined(IMAGE_BL31) || (defined(AARCH32) && defined(IMAGE_BL32))
	bakery_lock_release(&ccn_lock);
#endif
}

/*******************************************************************************
 * The following functions provide the boot and runtime API to the platform for
 * adding and removing master interfaces from the snoop/DVM domains. A bitmap of
 * master interfaces IDs is passed as a parameter. It is converted into a bitmap
 * of Request node IDs using the mapping provided by the platform while
 * initialising the driver.
 * For example, consider a dual cluster system where the clusters have values 0
 * & 1 in the affinity level 1 field of their respective MPIDRs. While
 * initialising this driver, the platform provides the mapping between each
 * cluster and the corresponding Request node. To add or remove a cluster from
 * the snoop and dvm domain, the bit position corresponding to the cluster ID
 * should be set in the 'master_iface_map' i.e. to remove both clusters the
 * bitmap would equal 0x11.
 ******************************************************************************/
void ccn_enter_snoop_dvm_domain(unsigned long long master_iface_map)
{
	unsigned long long rn_id_map;

	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
	ccn_snoop_dvm_do_op(rn_id_map,
			    CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase,
						  MN_HNF_NODEID_OFFSET),
			    HNF_REGION_ID_START,
			    HNF_SDC_SET_OFFSET,
			    HNF_SDC_STAT_OFFSET);

	ccn_snoop_dvm_do_op(rn_id_map,
			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
			    MN_REGION_ID,
			    MN_DDC_SET_OFFSET,
			    MN_DDC_STAT_OFFSET);
}

void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map)
{
	unsigned long long rn_id_map;

	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
	ccn_snoop_dvm_do_op(rn_id_map,
			    CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase,
						  MN_HNF_NODEID_OFFSET),
			    HNF_REGION_ID_START,
			    HNF_SDC_CLR_OFFSET,
			    HNF_SDC_STAT_OFFSET);

	ccn_snoop_dvm_do_op(rn_id_map,
			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
			    MN_REGION_ID,
			    MN_DDC_CLR_OFFSET,
			    MN_DDC_STAT_OFFSET);
}

void ccn_enter_dvm_domain(unsigned long long master_iface_map)
{
	unsigned long long rn_id_map;

	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
	ccn_snoop_dvm_do_op(rn_id_map,
			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
			    MN_REGION_ID,
			    MN_DDC_SET_OFFSET,
			    MN_DDC_STAT_OFFSET);
}

void ccn_exit_dvm_domain(unsigned long long master_iface_map)
{
	unsigned long long rn_id_map;

	rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
	ccn_snoop_dvm_do_op(rn_id_map,
			    CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
			    MN_REGION_ID,
			    MN_DDC_CLR_OFFSET,
			    MN_DDC_STAT_OFFSET);
}

/*******************************************************************************
 * This function returns the run mode of all the L3 cache partitions in the
 * system. The state is expected to be one of NO_L3, SF_ONLY, L3_HAM or
 * L3_FAM. Instead of comparing the states reported by all HN-Fs, the state of
 * the first present HN-F node is reported. Since the driver does not export an
 * interface to program them separately, there is no reason to perform this
 * check. An HN-F could report that the L3 cache is transitioning from one mode
 * to another e.g. HNF_PM_NOL3_2_SFONLY. In this case, the function waits for
 * the transition to complete and reports the final state.
 ******************************************************************************/
unsigned int ccn_get_l3_run_mode(void)
{
	unsigned long long hnf_pstate_stat;

	assert(ccn_plat_desc);
	assert(ccn_plat_desc->periphbase);

	/*
	 * Wait for a L3 cache partition to enter any run mode. The pstate
	 * parameter is read from an HN-F P-state status register. A non-zero
	 * value in bits[1:0] means that the cache is transitioning to a run
	 * mode.
	 */
	do {
		hnf_pstate_stat = ccn_reg_read(ccn_plat_desc->periphbase,
					       HNF_REGION_ID_START,
					       HNF_PSTATE_STAT_OFFSET);
	} while (hnf_pstate_stat & 0x3);

	return PSTATE_TO_RUN_MODE(hnf_pstate_stat);
}

/*******************************************************************************
 * This function sets the run mode of all the L3 cache partitions in the
 * system to one of NO_L3, SF_ONLY, L3_HAM or L3_FAM depending upon the state
 * specified by the 'mode' argument.
 ******************************************************************************/
void ccn_set_l3_run_mode(unsigned int mode)
{
	unsigned long long mn_hnf_id_map, hnf_pstate_stat;
	unsigned int region_id;

	assert(ccn_plat_desc);
	assert(ccn_plat_desc->periphbase);
	assert(mode <= CCN_L3_RUN_MODE_FAM);

	mn_hnf_id_map = ccn_reg_read(ccn_plat_desc->periphbase,
				     MN_REGION_ID,
				     MN_HNF_NODEID_OFFSET);
	region_id = HNF_REGION_ID_START;

	/* Program the desired run mode */
	FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {
		ccn_reg_write(ccn_plat_desc->periphbase,
			      region_id,
			      HNF_PSTATE_REQ_OFFSET,
			      mode);
	}

	/* Wait for the caches to transition to the run mode */
	region_id = HNF_REGION_ID_START;
	FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {
		/*
		 * Wait for a L3 cache partition to enter a target run
		 * mode. The pstate parameter is read from an HN-F P-state
		 * status register.
		 */
		do {
			hnf_pstate_stat = ccn_reg_read(ccn_plat_desc->periphbase,
					       region_id,
					       HNF_PSTATE_STAT_OFFSET);
		} while (((hnf_pstate_stat & HNF_PSTATE_MASK) >> 2) != mode);
	}
}

/*******************************************************************************
 * This function configures system address map and provides option to enable the
 * 3SN striping mode of Slave node operation. The Slave node IDs and the Top
 * Address bit1 and bit0 are provided as parameters to this function. This
 * configuration is needed only if network contains a single SN-F or 3 SN-F and
 * must be completed before the first request by the system to normal memory.
 ******************************************************************************/
void ccn_program_sys_addrmap(unsigned int sn0_id,
		 unsigned int sn1_id,
		 unsigned int sn2_id,
		 unsigned int top_addr_bit0,
		 unsigned int top_addr_bit1,
		 unsigned char three_sn_en)
{
	unsigned long long mn_hnf_id_map, hnf_sam_ctrl_value;
	unsigned int region_id;

	assert(ccn_plat_desc);
	assert(ccn_plat_desc->periphbase);

	mn_hnf_id_map = ccn_reg_read(ccn_plat_desc->periphbase,
				     MN_REGION_ID,
				     MN_HNF_NODEID_OFFSET);
	region_id = HNF_REGION_ID_START;
	hnf_sam_ctrl_value = MAKE_HNF_SAM_CTRL_VALUE(sn0_id,
						     sn1_id,
						     sn2_id,
						     top_addr_bit0,
						     top_addr_bit1,
						     three_sn_en);

	FOR_EACH_PRESENT_REGION_ID(region_id, mn_hnf_id_map) {

		/* Program the SAM control register */
		ccn_reg_write(ccn_plat_desc->periphbase,
			      region_id,
			      HNF_SAM_CTRL_OFFSET,
			      hnf_sam_ctrl_value);
	}

}

/*******************************************************************************
 * This function returns the part0 id from the peripheralID 0 register
 * in CCN. This id can be used to distinguish the CCN variant present in the
 * system.
 ******************************************************************************/
int ccn_get_part0_id(uintptr_t periphbase)
{
	assert(periphbase);
	return (int)(mmio_read_64(periphbase
			+ MN_PERIPH_ID_0_1_OFFSET) & 0xFF);
}

/*******************************************************************************
 * This function returns the region id corresponding to a node_id of node_type.
 ******************************************************************************/
static unsigned int get_region_id_for_node(node_types_t node_type,
						unsigned int node_id)
{
	unsigned int mn_reg_off, region_id;
	unsigned long long node_bitmap;
	unsigned int loc_node_id, node_pos_in_map = 0;

	assert(node_type < NUM_NODE_TYPES);
	assert(node_id < MAX_RN_NODES);

	switch (node_type) {
	case NODE_TYPE_RNI:
		region_id = RNI_REGION_ID_START;
		break;
	case NODE_TYPE_HNF:
		region_id = HNF_REGION_ID_START;
		break;
	case NODE_TYPE_HNI:
		region_id = HNI_REGION_ID_START;
		break;
	case NODE_TYPE_SN:
		region_id = SBSX_REGION_ID_START;
		break;
	default:
		ERROR("Un-supported Node Type = %d.\n", node_type);
		assert(false);
		return REGION_ID_LIMIT;
	}
	/*
	 * RN-I, HN-F, HN-I, SN node registers in the MN region
	 * occupy contiguous 16 byte apart offsets.
	 *
	 * RN-F and RN-D node are not supported as
	 * none of them exposes any memory map to
	 * configure any of their offset registers.
	 */

	mn_reg_off = MN_RNF_NODEID_OFFSET + (node_type << 4);
	node_bitmap = ccn_reg_read(ccn_plat_desc->periphbase,
					MN_REGION_ID, mn_reg_off);

	assert((node_bitmap & (1ULL << (node_id))) != 0U);


	FOR_EACH_PRESENT_NODE_ID(loc_node_id, node_bitmap) {
		INFO("Index = %u with loc_nod=%u and input nod=%u\n",
					node_pos_in_map, loc_node_id, node_id);
		if (loc_node_id == node_id)
			break;
		node_pos_in_map++;
	}

	if (node_pos_in_map == CCN_MAX_RN_MASTERS) {
		ERROR("Node Id = %d, is not found.\n", node_id);
		assert(false);
		return REGION_ID_LIMIT;
	}

	/*
	 * According to section 3.1.1 in CCN specification, region offset for
	 * the RN-I components is calculated as (128 + NodeID of RN-I).
	 */
	if (node_type == NODE_TYPE_RNI)
		region_id += node_id;
	else
		region_id += node_pos_in_map;

	return region_id;
}

/*******************************************************************************
 * This function sets the value 'val' to the register at register_offset from
 * the base address pointed to by the region_id.
 * where, region id is mapped to a node_id of node_type.
 ******************************************************************************/
void ccn_write_node_reg(node_types_t node_type, unsigned int node_id,
			unsigned int reg_offset, unsigned long long val)
{
	unsigned int region_id = get_region_id_for_node(node_type, node_id);

	if (reg_offset > REGION_ID_OFFSET) {
		ERROR("Invalid Register offset 0x%x is provided.\n",
								reg_offset);
		assert(false);
		return;
	}

	/* Setting the value of Auxiliary Control Register of the Node */
	ccn_reg_write(ccn_plat_desc->periphbase, region_id, reg_offset, val);
	VERBOSE("Value is successfully written at address 0x%lx.\n",
			(ccn_plat_desc->periphbase
			+ region_id_to_base(region_id))
			+ reg_offset);
}

/*******************************************************************************
 * This function read the value 'val' stored in the register at register_offset
 * from the base address pointed to by the region_id.
 * where, region id is mapped to a node_id of node_type.
 ******************************************************************************/
unsigned long long ccn_read_node_reg(node_types_t node_type,
					unsigned int node_id,
					unsigned int reg_offset)
{
	unsigned long long val;
	unsigned int region_id = get_region_id_for_node(node_type, node_id);

	if (reg_offset > REGION_ID_OFFSET) {
		ERROR("Invalid Register offset 0x%x is provided.\n",
								reg_offset);
		assert(false);
		return ULL(0);
	}

	/* Setting the value of Auxiliary Control Register of the Node */
	val = ccn_reg_read(ccn_plat_desc->periphbase, region_id, reg_offset);
	VERBOSE("Value is successfully read from address 0x%lx.\n",
			(ccn_plat_desc->periphbase
			+ region_id_to_base(region_id))
			+ reg_offset);

	return val;
}
