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

#include <assert.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(__aarch64__) && 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(__aarch64__) && 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(__aarch64__) && 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;
}
