// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2019 IBM Corp. */

/*
 *
 * We currently construct our associativity properties as such:
 *
 * - For "chip" devices (bridges, memory, ...), 4 entries:
 *
 *     - CCM node ID
 *     - HW card ID
 *     - HW module ID
 *     - Chip ID
 *
 *   The information is constructed based on the chip ID which (unlike
 *   pHyp) is our HW chip ID (aka "XSCOM" chip ID). We use it to retrieve
 *   the other properties from the corresponding chip/xscom node in the
 *   device-tree. If those properties are absent, 0 is used.
 *
 * - For "core" devices, we add a 5th entry:
 *
 *     - Core ID
 *
 *   Here too, we do not use the "cooked" HW processor ID from HDAT but
 *   instead use the real HW core ID which is basically the interrupt
 *   server number of thread 0 on that core.
 *
 *
 * The ibm,associativity-reference-points property is currently set to
 * 4,4 indicating that the chip ID is our only reference point. This
 * should be extended to encompass the node IDs eventually.
 */
#include <skiboot.h>
#include <opal.h>
#include <device.h>
#include <console.h>
#include <trace.h>
#include <chip.h>
#include <cpu.h>
#include <affinity.h>

static uint32_t get_chip_node_id(struct proc_chip *chip)
{
	/* If the xscom node has an ibm,ccm-node-id property, use it */
	if (dt_has_node_property(chip->devnode, "ibm,ccm-node-id", NULL))
		return dt_prop_get_u32(chip->devnode, "ibm,ccm-node-id");

	/*
	 * Else use the 3 top bits of the chip ID which should be
	 * the node on P8
	 */
	return chip->id >> 3;
}

void add_associativity_ref_point(void)
{
	int ref2 = 0x4;

	/*
	 * Note about our use of reference points:
	 *
	 * Linux currently supports up to three levels of NUMA. We use the
	 * first reference point for the node ID and the second reference
	 * point for a second level of affinity. We always use the chip ID
	 * (4) for the first reference point.
	 *
	 * Choosing the second level of affinity is model specific
	 * unfortunately. Current POWER8E models should use the DCM
	 * as a second level of NUMA.
	 *
	 * If there is a way to obtain this information from the FSP
	 * that would be ideal, but for now hardwire our POWER8E setting.
	 *
	 * For GPU nodes we add a third level of NUMA, such that the
	 * distance of the GPU node from all other nodes is uniformly
	 * the highest.
	 */
	if (PVR_TYPE(mfspr(SPR_PVR)) == PVR_TYPE_P8E)
		ref2 = 0x3;

	dt_add_property_cells(opal_node, "ibm,associativity-reference-points",
			      0x4, ref2, 0x2);
}

void add_chip_dev_associativity(struct dt_node *dev)
{
	uint32_t chip_id = dt_get_chip_id(dev);
	struct proc_chip *chip = get_chip(chip_id);
	uint32_t hw_cid, hw_mid;

	if (!chip)
		return;

	hw_cid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-card-id", 0);
	hw_mid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-module-id", 0);

	dt_add_property_cells(dev, "ibm,associativity", 4,
			      get_chip_node_id(chip),
			      hw_cid, hw_mid, chip_id);
}

void add_core_associativity(struct cpu_thread *cpu)
{
	struct proc_chip *chip = get_chip(cpu->chip_id);
	uint32_t hw_cid, hw_mid, core_id;

	if (!chip)
		return;

	if (proc_gen == proc_gen_p8)
		core_id = (cpu->pir >> 3) & 0xf;
	else if (proc_gen == proc_gen_p9)
		core_id = (cpu->pir >> 2) & 0x1f;
	else
		return;

	hw_cid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-card-id", 0);
	hw_mid = dt_prop_get_u32_def(chip->devnode, "ibm,hw-module-id", 0);

	dt_add_property_cells(cpu->node, "ibm,associativity", 5,
			      get_chip_node_id(chip),
			      hw_cid, hw_mid, chip->id, core_id);
}
