// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/*
 * In-Memory Counters (IMC)
 * Sometimes called IMA, but that's also a different thing.
 *
 * Copyright 2016-2019 IBM Corp.
 */

#define pr_fmt(fmt)  "IMC: " fmt
#include <skiboot.h>
#include <xscom.h>
#include <imc.h>
#include <chip.h>
#include <libxz/xz.h>
#include <device.h>
#include <p9_stop_api.H>

/*
 * IMC trace scom values
 */
#define IMC_TRACE_SAMPLESEL_VAL	1	/* select cpmc2 */
#define IMC_TRACE_CPMCLOAD_VAL	0xfa	/*
					 * Value to be loaded into cpmc2
					 * at sampling start
					 */
#define IMC_TRACE_CPMC2SEL_VAL	2	/* Event: CPM_32MHZ_CYC */
#define IMC_TRACE_BUFF_SIZE	0	/*
					 * b’000’- 4K entries * 64 per
					 * entry = 256K buffersize
					 */
/*
 * Nest IMC PMU names along with their bit values as represented in the
 * imc_chip_avl_vector(in struct imc_chip_cb, look at include/imc.h).
 * nest_pmus[] is an array containing all the possible nest IMC PMU node names.
 */
static char const *nest_pmus[] = {
	"powerbus0",
	"mcs0",
	"mcs1",
	"mcs2",
	"mcs3",
	"mcs4",
	"mcs5",
	"mcs6",
	"mcs7",
	"mba0",
	"mba1",
	"mba2",
	"mba3",
	"mba4",
	"mba5",
	"mba6",
	"mba7",
	"cen0",
	"cen1",
	"cen2",
	"cen3",
	"cen4",
	"cen5",
	"cen6",
	"cen7",
	"xlink0",
	"xlink1",
	"xlink2",
	"mcd0",
	"mcd1",
	"phb0",
	"phb1",
	"phb2",
	"phb3",
	"phb4",
	"phb5",
	"nx",
	"capp0",
	"capp1",
	"vas",
	"int",
	"alink0",
	"alink1",
	"alink2",
	"alink3",
	"nvlink0",
	"nvlink1",
	"nvlink2",
	"nvlink3",
	"nvlink4",
	"nvlink5",
	/* reserved bits : 51 - 63 */
};

/*
 * Due to Nest HW/OCC restriction, microcode will not support individual unit
 * events for these nest units mcs0, mcs1 ... mcs7 in the accumulation mode.
 * And events to monitor each mcs units individually will be supported only
 * in the debug mode (which will be supported by microcode in the future).
 * These will be advertised only when OPAL provides interface for the it.
 */
static char const *debug_mode_units[] = {
	"mcs0",
	"mcs1",
	"mcs2",
	"mcs3",
	"mcs4",
	"mcs5",
	"mcs6",
	"mcs7",
};

/*
 * Combined unit node events are counted when any of the individual
 * unit is enabled in the availability vector. That is,
 * ex, mcs01 unit node should be enabled only when mcs0 or mcs1 enabled.
 * mcs23 unit node should be enabled only when mcs2 or mcs3 is enabled
 */
static struct combined_units_node cu_node[] = {
	{ .name = "mcs01", .unit1 = PPC_BIT(1), .unit2 = PPC_BIT(2) },
	{ .name = "mcs23", .unit1 = PPC_BIT(3), .unit2 = PPC_BIT(4) },
	{ .name = "mcs45", .unit1 = PPC_BIT(5), .unit2 = PPC_BIT(6) },
	{ .name = "mcs67", .unit1 = PPC_BIT(7), .unit2 = PPC_BIT(8) },
};

static char *compress_buf;
static size_t compress_buf_size;
const char **prop_to_fix(struct dt_node *node);
static const char *props_to_fix[] = {"events", NULL};

static bool is_nest_mem_initialized(struct imc_chip_cb *ptr)
{
	/*
	 * Non zero value in "Status" field indicate memory initialized.
	 */
	if (!ptr->imc_chip_run_status)
		return false;

	return true;
}

/*
 * A Quad contains 4 cores in Power 9, and there are 4 addresses for
 * the Core Hardware Trace Macro (CHTM) attached to each core.
 * So, for core index 0 to core index 3, we have a sequential range of
 * SCOM port addresses in the arrays below, each for Hardware Trace Macro (HTM)
 * mode and PDBAR.
 */
static unsigned int pdbar_scom_index[] = {
	0x1001220B,
	0x1001230B,
	0x1001260B,
	0x1001270B
};
static unsigned int htm_scom_index[] = {
	0x10012200,
	0x10012300,
	0x10012600,
	0x10012700
};

static struct imc_chip_cb *get_imc_cb(uint32_t chip_id)
{
	struct proc_chip *chip = get_chip(chip_id);
	struct imc_chip_cb *cb;

	if (!chip->homer_base)
		return NULL; /* The No Homers Club */

	cb = (struct imc_chip_cb *)(chip->homer_base + P9_CB_STRUCT_OFFSET);
	if (!is_nest_mem_initialized(cb))
		return NULL;

	return cb;
}

static int pause_microcode_at_boot(void)
{
	struct proc_chip *chip;
	struct imc_chip_cb *cb;

	for_each_chip(chip) {
		cb = get_imc_cb(chip->id);
		if (cb)
			cb->imc_chip_command =  cpu_to_be64(NEST_IMC_DISABLE);
		else
			return -1; /* ucode is not init-ed */
	}

	return 0;
}

/*
 * Function return list of properties names for the fixup
 */
const char **prop_to_fix(struct dt_node *node)
{
	if (dt_node_is_compatible(node, "ibm,imc-counters"))
		return props_to_fix;

	return NULL;
}

/* Helper to get the IMC device type for a device node */
static int get_imc_device_type(struct dt_node *node)
{
	const struct dt_property *type;
	u32 val=0;

	if (!node)
		return -1;

	type = dt_find_property(node, "type");
	if (!type)
		return -1;

	val = dt_prop_get_u32(node, "type");
	switch (val){
	case IMC_COUNTER_CHIP:
		return IMC_COUNTER_CHIP;
	case IMC_COUNTER_CORE:
		return IMC_COUNTER_CORE;
	case IMC_COUNTER_THREAD:
		return IMC_COUNTER_THREAD;
	case IMC_COUNTER_TRACE:
		return IMC_COUNTER_TRACE;
	default:
		break;
	}

	/* Unknown/Unsupported IMC device type */
	return -1;
}

static bool is_nest_node(struct dt_node *node)
{
	if (get_imc_device_type(node) == IMC_COUNTER_CHIP)
		return true;

	return false;
}

static bool is_imc_device_type_supported(struct dt_node *node)
{
	u32 val = get_imc_device_type(node);
	struct proc_chip *chip = get_chip(this_cpu()->chip_id);
	uint64_t pvr;

	if ((val == IMC_COUNTER_CHIP) || (val == IMC_COUNTER_CORE) ||
						(val == IMC_COUNTER_THREAD))
		return true;

	if (val == IMC_COUNTER_TRACE) {
		pvr = mfspr(SPR_PVR);
		/*
		 * Trace mode is supported in Nimbus DD2.2
		 * and later versions.
		 */
		if ((chip->type == PROC_CHIP_P9_NIMBUS) &&
			(PVR_VERS_MAJ(pvr) == 2) && (PVR_VERS_MIN(pvr) >= 2))
			return true;
	}
	return false;
}

/*
 * Helper to check for the imc device type in the incoming device tree.
 * Remove unsupported device node.
 */
static void check_imc_device_type(struct dt_node *dev)
{
	struct dt_node *node;

	dt_for_each_compatible(dev, node, "ibm,imc-counters") {
		if (!is_imc_device_type_supported(node)) {
			/*
			 * ah nice, found a device type which I didnt know.
			 * Remove it and also mark node as NULL, since dt_next
			 * will try to fetch info for "prev" which is removed
			 * by dt_free.
			 */
			dt_free(node);
			node = NULL;
		}
	}

	return;
}

static void imc_dt_exports_prop_add(struct dt_node *dev)
{
	struct dt_node *node;
	struct proc_chip *chip;
	const struct dt_property *type;
	uint32_t offset = 0, size = 0;
	uint64_t baddr;
	char namebuf[32];


	dt_for_each_compatible(dev, node, "ibm,imc-counters") {
		type = dt_find_property(node, "type");
		if (type && is_nest_node(node)) {
			offset = dt_prop_get_u32(node, "offset");
			size = dt_prop_get_u32(node, "size");
		}
	}

	/*
	 * Enable only if we have valid values.
	 */
	if (!size && !offset)
		return;

	node = dt_find_by_name(opal_node, "exports");
	if (!node)
		return;

	for_each_chip(chip) {
		snprintf(namebuf, sizeof(namebuf), "imc_nest_chip_%x", chip->id);
		baddr = chip->homer_base;
		baddr += offset;
		dt_add_property_u64s(node, namebuf, baddr, size);
	}
}

/*
 * Remove the PMU device nodes from the incoming new subtree, if they are not
 * available in the hardware. The availability is described by the
 * control block's imc_chip_avl_vector.
 * Each bit represents a device unit. If the device is available, then
 * the bit is set else its unset.
 */
static void disable_unavailable_units(struct dt_node *dev)
{
	uint64_t avl_vec;
	struct imc_chip_cb *cb;
	struct dt_node *target;
	int i;
	bool disable_all_nests = false;
	struct proc_chip *chip;

	/*
	 * Check the state of ucode in all the chip.
	 * Disable the nest unit if ucode is not initialized
	 * in any of the chip.
	 */
	for_each_chip(chip) {
		cb = get_imc_cb(chip->id);
		if (!cb) {
			/*
			 * At least currently, if one chip isn't functioning,
			 * none of the IMC Nest units will be functional.
			 * So while you may *think* this should be per chip,
			 * it isn't.
			 */
			disable_all_nests = true;
			break;
		}
	}

	/* Add a property to "exports" node in opal_node */
	imc_dt_exports_prop_add(dev);

	/* Fetch the IMC control block structure */
	cb = get_imc_cb(this_cpu()->chip_id);
	if (cb && !disable_all_nests)
		avl_vec = be64_to_cpu(cb->imc_chip_avl_vector);
	else {
		avl_vec = 0; /* Remove only nest imc device nodes */

		/* Incase of mambo, just fake it */
		if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
			avl_vec = (0xffULL) << 56;
	}

	for (i = 0; i < ARRAY_SIZE(nest_pmus); i++) {
		if (!(PPC_BITMASK(i, i) & avl_vec)) {
			/* Check if the device node exists */
			target = dt_find_by_name(dev, nest_pmus[i]);
			if (!target)
				continue;
			/* Remove the device node */
			dt_free(target);
		}
	}

	/*
	 * Loop to detect debug mode units and remove them
	 * since the microcode does not support debug mode function yet.
	 */
	for (i = 0; i < ARRAY_SIZE(debug_mode_units); i++) {
		target = dt_find_by_name(dev, debug_mode_units[i]);
		if (!target)
			continue;
		/* Remove the device node */
		dt_free(target);
	}

	/*
	 * Based on availability unit vector from control block,
	 * check and enable combined unit nodes in the device tree.
	 */
	for (i = 0; i < MAX_NEST_COMBINED_UNITS ; i++ ) {
		if (!(cu_node[i].unit1 & avl_vec) &&
				!(cu_node[i].unit2 & avl_vec)) {
			target = dt_find_by_name(dev, cu_node[i].name);
			if (!target)
				continue;

			/* Remove the device node */
			dt_free(target);
		}
	}

	return;
}

/*
 * Function to queue the loading of imc catalog data
 * from the IMC pnor partition.
 */
void imc_catalog_preload(void)
{
	uint32_t pvr = (mfspr(SPR_PVR) & ~(0xf0ff));
	int ret = OPAL_SUCCESS;
	compress_buf_size = MAX_COMPRESSED_IMC_DTB_SIZE;

	if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
		return;

	/* Enable only for power 9 */
	if (proc_gen != proc_gen_p9)
		return;

	compress_buf = malloc(MAX_COMPRESSED_IMC_DTB_SIZE);
	if (!compress_buf) {
		prerror("Memory allocation for catalog failed\n");
		return;
	}

	ret = start_preload_resource(RESOURCE_ID_IMA_CATALOG,
					pvr, compress_buf, &compress_buf_size);
	if (ret != OPAL_SUCCESS) {
		prerror("Failed to load IMA_CATALOG: %d\n", ret);
		free(compress_buf);
		compress_buf = NULL;
	}

	return;
}

static void imc_dt_update_nest_node(struct dt_node *dev)
{
	struct proc_chip *chip;
	__be64 *base_addr = NULL;
	__be32 *chipids = NULL;
	int i=0, nr_chip = nr_chips();
	struct dt_node *node;
	const struct dt_property *type;

	/* Add the base_addr and chip-id properties for the nest node */
	base_addr = malloc(sizeof(u64) * nr_chip);
	chipids = malloc(sizeof(u32) * nr_chip);
	for_each_chip(chip) {
		base_addr[i] = cpu_to_be64(chip->homer_base);
		chipids[i] = cpu_to_be32(chip->id);
		i++;
	}

	dt_for_each_compatible(dev, node, "ibm,imc-counters") {
		type = dt_find_property(node, "type");
		if (type && is_nest_node(node)) {
			dt_add_property(node, "base-addr", base_addr, (i * sizeof(u64)));
			dt_add_property(node, "chip-id", chipids, (i * sizeof(u32)));
		}
	}
}

static struct xz_decompress *imc_xz;

void imc_decompress_catalog(void)
{
	void *decompress_buf = NULL;
	uint32_t pvr = (mfspr(SPR_PVR) & ~(0xf0ff));
	int ret;

	/* Check we succeeded in starting the preload */
	if (compress_buf == NULL)
		return;

	ret = wait_for_resource_loaded(RESOURCE_ID_IMA_CATALOG, pvr);
	if (ret != OPAL_SUCCESS) {
		prerror("IMC Catalog load failed\n");
		return;
	}

	/*
	 * Memory for decompression.
	 */
	decompress_buf = malloc(MAX_DECOMPRESSED_IMC_DTB_SIZE);
	if (!decompress_buf) {
		prerror("No memory for decompress_buf \n");
		return;
	}

	/*
	 * Decompress the compressed buffer
	 */
	imc_xz = malloc(sizeof(struct xz_decompress));
	if (!imc_xz) {
		prerror("No memory to decompress IMC catalog\n");
		free(decompress_buf);
		return;
	}

	imc_xz->dst = decompress_buf;
	imc_xz->src = compress_buf;
	imc_xz->dst_size = MAX_DECOMPRESSED_IMC_DTB_SIZE;
	imc_xz->src_size = compress_buf_size;
	xz_start_decompress(imc_xz);
}

/*
 * Load the IMC pnor partition and find the appropriate sub-partition
 * based on the platform's PVR.
 * Decompress the sub-partition and link the imc device tree to the
 * existing device tree.
 */
void imc_init(void)
{
	struct dt_node *dev;
	int err_flag = -1;

	if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS) {
		dev = dt_find_compatible_node(dt_root, NULL,
					"ibm,opal-in-memory-counters");
		if (!dev)
			return;

		goto imc_mambo;
	}

	/* Enable only for power 9 */
	if (proc_gen != proc_gen_p9)
		return;

	if (!imc_xz)
		return;

	wait_xz_decompress(imc_xz);
	if (imc_xz->status != OPAL_SUCCESS) {
		prerror("IMC: xz_decompress failed\n");
		goto err;
	}

	/*
	 * Flow of the data from PNOR to main device tree:
	 *
	 * PNOR -> compressed local buffer (compress_buf)
	 * compressed local buffer -> decompressed local buf (decompress_buf)
	 * decompress local buffer -> main device tree
	 * free compressed local buffer
	 */


	/* Create a device tree entry for imc counters */
	dev = dt_new_root("imc-counters");
	if (!dev) {
		prerror("IMC: Failed to add an imc-counters root node\n");
		goto err;
	}

	/*
	 * Attach the new decompress_buf to the imc-counters node.
	 * dt_expand_node() does sanity checks for fdt_header, piggyback
	 */
	if (dt_expand_node(dev, imc_xz->dst, 0) < 0) {
		dt_free(dev);
		prerror("IMC: dt_expand_node failed\n");
		goto err;
	}

imc_mambo:
	/* Check and remove unsupported imc device types */
	check_imc_device_type(dev);

	/*
	 * Check and remove unsupported nest unit nodes by the microcode,
	 * from the incoming device tree.
	 */
	disable_unavailable_units(dev);

	/* Fix the phandle in the incoming device tree */
	dt_adjust_subtree_phandle(dev, prop_to_fix);

	/* Update the base_addr and chip-id for nest nodes */
	imc_dt_update_nest_node(dev);

	if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
		return;

	/*
	 * IMC nest counters has both in-band (ucode access) and out of band
	 * access to it. Since not all nest counter configurations are supported
	 * by ucode, out of band tools are used to characterize other
	 * configuration.
	 *
	 * If the ucode not paused and OS does not have IMC driver support,
	 * then out to band tools will race with ucode and end up getting
	 * undesirable values. Hence pause the ucode if it is already running.
	 */
	if (pause_microcode_at_boot()) {
		prerror("IMC: Pausing ucode failed\n");
		goto err;
	}

	/*
	 * If the dt_attach_root() fails, "imc-counters" node will not be
	 * seen in the device-tree and hence OS should not make any
	 * OPAL_IMC_* calls.
	 */
	if (!dt_attach_root(dt_root, dev)) {
		dt_free(dev);
		prerror("IMC: Failed to attach imc-counter node to dt root\n");
		goto err;
	}

	err_flag = OPAL_SUCCESS;

err:
	if (err_flag != OPAL_SUCCESS)
		prerror("IMC Devices not added\n");

	free(compress_buf);
	free(imc_xz->dst);
	free(imc_xz);
}

static int stop_api_init(struct proc_chip *chip, int phys_core_id,
			uint32_t scoms,  uint64_t data,
			const ScomOperation_t operation,
			const ScomSection_t section,
			const char *type)
{
	int ret;

	prlog(PR_DEBUG, "Configuring stopapi for IMC\n");
	ret = p9_stop_save_scom((void *)chip->homer_base, scoms,
				data, operation, section);
	if (ret) {
		prerror("IMC %s stopapi ret = %d, scoms = %x (core id = %x)\n",\
				type, ret, scoms, phys_core_id);
		if (ret != STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED)
			wakeup_engine_state = WAKEUP_ENGINE_FAILED;
		else
			prerror("SCOM entries are full\n");
		return OPAL_HARDWARE;
	}

	return ret;
}

/*
 * opal_imc_counters_init : This call initialize the IMC engine.
 *
 * For Nest IMC, this is no-op and returns OPAL_SUCCESS at this point.
 * For Core IMC, this initializes core IMC Engine, by initializing
 * these scoms "PDBAR", "HTM_MODE" and the "EVENT_MASK" in a given cpu.
 */
static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr, uint64_t cpu_pir)
{
	struct cpu_thread *c = find_cpu_by_pir(cpu_pir);
	int port_id, phys_core_id;
	int ret;
	uint32_t scoms;
	uint64_t trace_scom_val = TRACE_IMC_SCOM(IMC_TRACE_SAMPLESEL_VAL,
						 IMC_TRACE_CPMCLOAD_VAL, 0,
						 IMC_TRACE_CPMC2SEL_VAL,
						 IMC_TRACE_BUFF_SIZE);
	switch (type) {
	case OPAL_IMC_COUNTERS_NEST:
		return OPAL_SUCCESS;
	case OPAL_IMC_COUNTERS_CORE:
		if (!c)
			return OPAL_PARAMETER;

		/*
		 * Core IMC hardware mandates setting of htm_mode and
		 * pdbar in specific scom ports. port_id are in
		 * pdbar_scom_index[] and htm_scom_index[].
		 */
		phys_core_id = pir_to_core_id(c->pir);
		port_id = phys_core_id % 4;

		if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
			return OPAL_SUCCESS;

		/*
		 * Core IMC hardware mandate initing of three scoms
		 * to enbale or disable of the Core IMC engine.
		 *
		 * PDBAR: Scom contains the real address to store per-core
		 *        counter data in memory along with other bits.
		 *
		 * EventMask: Scom contain bits to denote event to multiplex
		 *            at different MSR[HV PR] values, along with bits for
		 *            sampling duration.
		 *
		 * HTM Scom: scom to enable counter data movement to memory.
		 */


		 if (xscom_write(c->chip_id,
				XSCOM_ADDR_P9_EQ(phys_core_id,
						pdbar_scom_index[port_id]),
				(u64)(CORE_IMC_PDBAR_MASK & addr))) {
			prerror("error in xscom_write for pdbar\n");
			return OPAL_HARDWARE;
		}

		if (has_deep_states) {
			if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT) {
				struct proc_chip *chip = get_chip(c->chip_id);

				scoms = XSCOM_ADDR_P9_EQ(phys_core_id,
						pdbar_scom_index[port_id]);
				ret = stop_api_init(chip, phys_core_id, scoms,
						(u64)(CORE_IMC_PDBAR_MASK & addr),
						P9_STOP_SCOM_REPLACE,
						P9_STOP_SECTION_EQ_SCOM,
						"pdbar");
				if (ret)
					return ret;
				scoms = XSCOM_ADDR_P9_EC(phys_core_id,
						CORE_IMC_EVENT_MASK_ADDR);
				ret = stop_api_init(chip, phys_core_id, scoms,
						(u64)CORE_IMC_EVENT_MASK,
						P9_STOP_SCOM_REPLACE,
						P9_STOP_SECTION_CORE_SCOM,
						"event_mask");
				if (ret)
					return ret;
			} else {
				prerror("IMC: Wakeup engine not present!");
				return OPAL_HARDWARE;
			}
		}

		if (xscom_write(c->chip_id,
				XSCOM_ADDR_P9_EC(phys_core_id,
					 CORE_IMC_EVENT_MASK_ADDR),
				(u64)CORE_IMC_EVENT_MASK)) {
			prerror("error in xscom_write for event mask\n");
			return OPAL_HARDWARE;
		}

		if (xscom_write(c->chip_id,
				XSCOM_ADDR_P9_EQ(phys_core_id,
						htm_scom_index[port_id]),
				(u64)CORE_IMC_HTM_MODE_DISABLE)) {
			prerror("error in xscom_write for htm mode\n");
			return OPAL_HARDWARE;
		}
		return OPAL_SUCCESS;
	case OPAL_IMC_COUNTERS_TRACE:
		if (!c)
			return OPAL_PARAMETER;

		phys_core_id = pir_to_core_id(c->pir);
		port_id = phys_core_id % 4;

		if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
			return OPAL_SUCCESS;

		if (has_deep_states) {
			if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT) {
				struct proc_chip *chip = get_chip(c->chip_id);

				scoms = XSCOM_ADDR_P9_EC(phys_core_id,
							 TRACE_IMC_ADDR);
				ret = stop_api_init(chip, phys_core_id, scoms,
						    trace_scom_val,
						    P9_STOP_SCOM_REPLACE,
						    P9_STOP_SECTION_CORE_SCOM,
						    "trace_imc");
				if (ret)
					return ret;
			} else {
				prerror("IMC-trace:Wakeup engine not present!");
				return OPAL_HARDWARE;
			}
		}
		if (xscom_write(c->chip_id,
			XSCOM_ADDR_P9_EQ(phys_core_id, htm_scom_index[port_id]),
					(u64)CORE_IMC_HTM_MODE_DISABLE)) {
				prerror("IMC-trace: error in xscom_write for htm mode\n");
				return OPAL_HARDWARE;
		}
		if (xscom_write(c->chip_id,
			XSCOM_ADDR_P9_EC(phys_core_id,
					TRACE_IMC_ADDR), trace_scom_val)) {
			prerror("IMC-trace: error in xscom_write for trace mode\n");
			return OPAL_HARDWARE;
		}
		return OPAL_SUCCESS;

	}

	return OPAL_SUCCESS;
}
opal_call(OPAL_IMC_COUNTERS_INIT, opal_imc_counters_init, 3);

/* opal_imc_counters_control_start: This call starts the nest/core imc engine. */
static int64_t opal_imc_counters_start(uint32_t type, uint64_t cpu_pir)
{
	u64 op;
	struct cpu_thread *c = find_cpu_by_pir(cpu_pir);
	struct imc_chip_cb *cb;
	int port_id, phys_core_id;

	if (!c)
		return OPAL_PARAMETER;

	switch (type) {
	case OPAL_IMC_COUNTERS_NEST:
		/* Fetch the IMC control block structure */
		cb = get_imc_cb(c->chip_id);
		if (!cb)
			return OPAL_HARDWARE;

		/* Set the run command */
		op = NEST_IMC_ENABLE;

		if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
			return OPAL_SUCCESS;

		/* Write the command to the control block now */
		cb->imc_chip_command = cpu_to_be64(op);

		return OPAL_SUCCESS;
	case OPAL_IMC_COUNTERS_CORE:
	case OPAL_IMC_COUNTERS_TRACE:
		/*
		 * Core IMC hardware mandates setting of htm_mode in specific
		 * scom ports (port_id are in htm_scom_index[])
		 */
		phys_core_id = pir_to_core_id(c->pir);
		port_id = phys_core_id % 4;

		if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
			return OPAL_SUCCESS;

		/*
		 * Enables the core imc engine by appropriately setting
		 * bits 4-9 of the HTM_MODE scom port. No initialization
		 * is done in this call. This just enables the the counters
		 * to count with the previous initialization.
		 */
		if (xscom_write(c->chip_id,
				XSCOM_ADDR_P9_EQ(phys_core_id,
						htm_scom_index[port_id]),
				(u64)CORE_IMC_HTM_MODE_ENABLE)) {
			prerror("IMC OPAL_start: error in xscom_write for htm_mode\n");
			return OPAL_HARDWARE;
		}

		return OPAL_SUCCESS;
	}

	return OPAL_SUCCESS;
}
opal_call(OPAL_IMC_COUNTERS_START, opal_imc_counters_start, 2);

/* opal_imc_counters_control_stop: This call stops the nest imc engine. */
static int64_t opal_imc_counters_stop(uint32_t type, uint64_t cpu_pir)
{
	u64 op;
	struct imc_chip_cb *cb;
	struct cpu_thread *c = find_cpu_by_pir(cpu_pir);
	int port_id, phys_core_id;

	if (!c)
		return OPAL_PARAMETER;

	switch (type) {
	case OPAL_IMC_COUNTERS_NEST:
		/* Fetch the IMC control block structure */
		cb = get_imc_cb(c->chip_id);
		if (!cb)
			return OPAL_HARDWARE;

		/* Set the run command */
		op = NEST_IMC_DISABLE;

		if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
			return OPAL_SUCCESS;

		/* Write the command to the control block */
		cb->imc_chip_command = cpu_to_be64(op);

		return OPAL_SUCCESS;

	case OPAL_IMC_COUNTERS_CORE:
	case OPAL_IMC_COUNTERS_TRACE:
		/*
		 * Core IMC hardware mandates setting of htm_mode in specific
		 * scom ports (port_id are in htm_scom_index[])
		 */
		phys_core_id = pir_to_core_id(c->pir);
		port_id = phys_core_id % 4;

		if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS)
			return OPAL_SUCCESS;

		/*
		 * Disables the core imc engine by clearing
		 * bits 4-9 of the HTM_MODE scom port.
		 */
		if (xscom_write(c->chip_id,
				XSCOM_ADDR_P9_EQ(phys_core_id,
						htm_scom_index[port_id]),
				(u64) CORE_IMC_HTM_MODE_DISABLE)) {
			prerror("error in xscom_write for htm_mode\n");
			return OPAL_HARDWARE;
		}

		return OPAL_SUCCESS;
	}

	return OPAL_SUCCESS;
}
opal_call(OPAL_IMC_COUNTERS_STOP, opal_imc_counters_stop, 2);
