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

#include <device.h>
#include "spira.h"
#include <cpu.h>
#include <vpd.h>
#include <ccan/str/str.h>
#include <interrupts.h>
#include <inttypes.h>
#include <phys-map.h>
#include <chip.h>
#include <ipmi.h>

#include "hdata.h"

enum sp_type {
	SP_BAD = 0,
	SP_UNKNOWN,
	SP_FSP,
	SP_BMC,
};

static const char * const sp_names[] = {
	"Broken", "Unknown", "FSP", "BMC",
};

static enum sp_type find_service_proc_type(const struct HDIF_common_hdr *spss,
		int index)
{
	const struct spss_sp_impl *sp_impl;
	int hw_ver, sw_ver, flags;
	enum sp_type sp_type;
	bool functional, installed;

	/* Find an check the SP Implementation structure */
	sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL);
	if (!CHECK_SPPTR(sp_impl)) {
		prerror("SP #%d: SPSS/SP_Implementation not found !\n", index);
		return SP_BAD;
	}

	hw_ver = be16_to_cpu(sp_impl->hw_version);
	sw_ver = be16_to_cpu(sp_impl->sw_version);
	flags  = be16_to_cpu(sp_impl->func_flags);

	switch (hw_ver) {
	case 0x1:
	case 0x2: /* We only support FSP2 */
		sp_type = SP_FSP;
		break;
	case 0x3:
		sp_type = SP_BMC;
		break;
	default:
		sp_type = SP_UNKNOWN;
	}

	if (sp_type == SP_UNKNOWN)
		return SP_UNKNOWN;

	installed  = !!(flags & SPSS_SP_IMPL_FLAGS_INSTALLED);
	functional = !!(flags & SPSS_SP_IMPL_FLAGS_FUNCTIONAL);

	if (!installed || !functional) {
		prerror("%s #%d not usable: %sinstalled, %sfunctional\n",
			sp_names[sp_type], index,
			installed  ? "" : "not ",
			functional ? "" : "not ");

		return SP_BAD;
	}

	prlog(PR_INFO, "%s #%d: HW version %d, SW version %d, chip DD%d.%d\n",
	      sp_names[sp_type], index, hw_ver, sw_ver,
	      sp_impl->chip_version >> 4,
	      sp_impl->chip_version & 0xf);

	return sp_type;
}

/*
 * Note on DT representation of the PSI links and FSPs:
 *
 * We create a XSCOM node for each PSI host bridge(one per chip),
 *
 * This is done in spira.c
 *
 * We do not create the /psi MMIO variant at this stage, it will
 * be added by the psi driver in skiboot.
 *
 * We do not put the FSP(s) as children of these. Instead, we create
 * a top-level /fsps node with the FSPs as children.
 *
 * Each FSP then has a "links" property which is an array of chip IDs
 */

static struct dt_node *fsp_create_node(const void *spss, int i,
				       struct dt_node *parent)
{
	const struct spss_sp_impl *sp_impl;
	struct dt_node *node;

	sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL);

	node = dt_new_addr(parent, "fsp", i);
	assert(node);

	dt_add_property_cells(node, "reg", i);

	if (be16_to_cpu(sp_impl->hw_version) == 1) {
		dt_add_property_strings(node, "compatible", "ibm,fsp",
				"ibm,fsp1");
		/* Offset into the FSP MMIO space where the mailbox
		 * registers are */
		/* seen in the FSP1 spec */
		dt_add_property_cells(node, "reg-offset", 0xb0016000);
	} else if (be16_to_cpu(sp_impl->hw_version) == 2) {
		dt_add_property_strings(node, "compatible", "ibm,fsp",
				"ibm,fsp2");
		dt_add_property_cells(node, "reg-offset", 0xb0011000);
	}
	dt_add_property_cells(node, "hw-version", be16_to_cpu(sp_impl->hw_version));
	dt_add_property_cells(node, "sw-version", be16_to_cpu(sp_impl->sw_version));

	if (be16_to_cpu(sp_impl->func_flags) & SPSS_SP_IMPL_FLAGS_PRIMARY)
		dt_add_property(node, "primary", NULL, 0);

	return node;
}

static uint32_t fsp_create_link(const struct spss_iopath *iopath, int index,
				int fsp_index)
{
	struct dt_node *node;
	const char *ststr;
	bool current = false;
	bool working = false;
	uint32_t chip_id;

	switch(be16_to_cpu(iopath->psi.link_status)) {
	case SPSS_IO_PATH_PSI_LINK_BAD_FRU:
		ststr = "Broken";
		break;
	case SPSS_IO_PATH_PSI_LINK_CURRENT:
		ststr = "Active";
		current = working = true;
		break;
	case SPSS_IO_PATH_PSI_LINK_BACKUP:
		ststr = "Backup";
		working = true;
		break;
	default:
		ststr = "Unknown";
	}
	prlog(PR_DEBUG, "FSP #%d: IO PATH %d is %s PSI Link, GXHB at %" PRIx64 "\n",
	      fsp_index, index, ststr, be64_to_cpu(iopath->psi.gxhb_base));

	chip_id = pcid_to_chip_id(be32_to_cpu(iopath->psi.proc_chip_id));
	node = dt_find_compatible_node_on_chip(dt_root, NULL, "ibm,psihb-x",
					       chip_id);
	if (!node) {
		prerror("FSP #%d: Can't find psihb node for link %d\n",
			fsp_index, index);
	} else {
		if (current)
			dt_add_property(node, "boot-link", NULL, 0);
		dt_add_property_strings(node, "status", working ? "ok" : "bad");
	}

	return chip_id;
}

static void fsp_create_links(const void *spss, int index,
			     struct dt_node *fsp_node)
{
	__be32 *links = NULL;
	unsigned int i, lp, lcount = 0;
	int count;

	count = HDIF_get_iarray_size(spss, SPSS_IDATA_SP_IOPATH);
	if (count < 0) {
		prerror("FSP #%d: Can't find IO PATH array size !\n", index);
		return;
	}
	prlog(PR_DEBUG, "FSP #%d: Found %d IO PATH\n", index, count);

	/* Iterate all links */
	for (i = 0; i < count; i++) {
		const struct spss_iopath *iopath;
		unsigned int iopath_sz;
		uint32_t chip;

		iopath = HDIF_get_iarray_item(spss, SPSS_IDATA_SP_IOPATH,
					      i, &iopath_sz);
		if (!CHECK_SPPTR(iopath)) {
			prerror("FSP #%d: Can't find IO PATH %d\n", index, i);
			break;
		}
		if (be16_to_cpu(iopath->iopath_type) != SPSS_IOPATH_TYPE_PSI) {
			prerror("FSP #%d: Unsupported IO PATH %d type 0x%04x\n",
				index, i, iopath->iopath_type);
			continue;
		}

		chip = fsp_create_link(iopath, i, index);
		lp = lcount++;
		links = realloc(links, 4 * lcount);
		links[lp] = cpu_to_be32(chip);
	}
	if (links)
		dt_add_property(fsp_node, "ibm,psi-links", links, lcount * 4);

	free(links);
}

static struct dt_node *add_lpc_io_node(struct dt_node *parent,
	const char *name, u32 offset, u32 size)
{
	struct dt_node *n;
	char buffer[32];

	/*
	 * LPC bus addresses have strange DT names, they have the
	 * Bus address space embedded into the unit address e.g.
	 * serial@i3f8 - refers to offset 0x3f8 in the IO space
	 */

	snprintf(buffer, sizeof(buffer), "%s@i%x", name, offset);
	n = dt_new(parent, buffer);
	assert(n);

	/* first address cell of 1 indicates the LPC IO space */
	dt_add_property_cells(n, "reg", 1, offset, size);

	return n;
}

static void add_uart(const struct spss_iopath *iopath, struct dt_node *lpc)
{
	struct dt_node *serial;
	u64 base;

	/* XXX: The spec says this is supposed to be a MMIO address.
	 *      However, in practice we get an LPC IO Space offset.
	 */
	base = be64_to_cpu(iopath->lpc.uart_base);

	serial = add_lpc_io_node(lpc, "serial", base,
		be32_to_cpu(iopath->lpc.uart_size));

	dt_add_property_string(serial, "compatible", "ns16550");

	dt_add_property_cells(serial, "current-speed",
		be32_to_cpu(iopath->lpc.uart_baud));
	dt_add_property_cells(serial, "clock-frequency",
		be32_to_cpu(iopath->lpc.uart_clk));
	dt_add_property_cells(serial, "interrupts",
			      iopath->lpc.uart_int_number);
	dt_add_property_string(serial, "device_type", "serial");


	prlog(PR_DEBUG, "LPC UART: base addr = %#" PRIx64" (%#" PRIx64 ") size = %#x clk = %u, baud = %u\n",
		be64_to_cpu(iopath->lpc.uart_base),
		base,
		be32_to_cpu(iopath->lpc.uart_size),
		be32_to_cpu(iopath->lpc.uart_clk),
		be32_to_cpu(iopath->lpc.uart_baud));
}

static void add_chip_id_to_sensors(struct dt_node *sensor_node, uint32_t slca_index)
{
	unsigned int i;
	const void *hdif;
	const struct slca_entry *slca;
	const struct spira_fru_id *fru_id;
	const struct sppcrd_chip_info *cinfo;

	slca = slca_get_entry(slca_index);
	if (slca == NULL) {
		prlog(PR_WARNING, "SENSORS: Invalid slca index\n");
		return;
	}

	for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i, SPPCRD_HDIF_SIG) {
		fru_id = HDIF_get_idata(hdif, SPPCRD_IDATA_FRU_ID, NULL);
		if (!fru_id)
			return;

		if (fru_id->rsrc_id != slca->rsrc_id)
			continue;

		cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
		if (!CHECK_SPPTR(cinfo)) {
			prlog(PR_ERR, "SENSORS: Bad ChipID data %d\n", i);
			return;
		}

		dt_add_property_cells(sensor_node,
				      "ibm,chip-id", be32_to_cpu(cinfo->xscom_id));
		return;
	}
}

static void add_ipmi_sensors(struct dt_node *bmc_node)
{
	int i;
	const struct HDIF_common_hdr *hdif_sensor;
	const struct ipmi_sensors *ipmi_sensors;
	struct dt_node *sensors_node, *sensor_node;

	hdif_sensor = get_hdif(&spira.ntuples.ipmi_sensor, IPMI_SENSORS_HDIF_SIG);
	if (!hdif_sensor) {
		prlog(PR_DEBUG, "SENSORS: Missing IPMI sensors mappings tuple\n");
		return;
	}

	ipmi_sensors = HDIF_get_idata(hdif_sensor, IPMI_SENSORS_IDATA_SENSORS, NULL);
	if (!ipmi_sensors) {
		prlog(PR_DEBUG, "SENSORS: bad data\n");
		return;
	}

	sensors_node = dt_new(bmc_node, "sensors");
	assert(sensors_node);

	dt_add_property_cells(sensors_node, "#address-cells", 1);
	dt_add_property_cells(sensors_node, "#size-cells", 0);

	for (i = 0; i < be32_to_cpu(ipmi_sensors->count); i++) {
		if(dt_find_by_name_addr(sensors_node, "sensor",
					ipmi_sensors->data[i].id)) {
			prlog(PR_WARNING, "SENSORS: Duplicate sensor ID : %x\n",
			      ipmi_sensors->data[i].id);
			continue;
		}

		/* We support only < MAX_IPMI_SENSORS sensors */
		if (!(ipmi_sensors->data[i].type < MAX_IPMI_SENSORS))
			continue;

		sensor_node = dt_new_addr(sensors_node, "sensor",
					  ipmi_sensors->data[i].id);
		assert(sensor_node);
		dt_add_property_string(sensor_node, "compatible", "ibm,ipmi-sensor");
		dt_add_property_cells(sensor_node, "reg", ipmi_sensors->data[i].id);
		dt_add_property_cells(sensor_node, "ipmi-sensor-type",
				      ipmi_sensors->data[i].type);

		add_chip_id_to_sensors(sensor_node,
				be32_to_cpu(ipmi_sensors->data[i].slca_index));
	}
}

static void bmc_create_node(const struct HDIF_common_hdr *sp)
{
	struct dt_node *bmc_node;
	u32 fw_bar, io_bar, mem_bar, internal_bar;
	const struct spss_iopath *iopath;
	const struct spss_sp_impl *sp_impl;
	struct dt_node *lpcm, *lpc, *n;
	u64 lpcm_base, lpcm_end;
	uint32_t chip_id;
	int size;

	bmc_node = dt_new(dt_root, "bmc");
	assert(bmc_node);

	dt_add_property_cells(bmc_node, "#address-cells", 1);
	dt_add_property_cells(bmc_node, "#size-cells", 0);

	/* Add sensor info under /bmc */
	add_ipmi_sensors(bmc_node);

	sp_impl = HDIF_get_idata(sp, SPSS_IDATA_SP_IMPL, &size);
	if (CHECK_SPPTR(sp_impl) && (size > 8)) {
		dt_add_property_strings(bmc_node, "compatible", sp_impl->sp_family);
		prlog(PR_INFO, "SP Family is %s\n", sp_impl->sp_family);
	}

	iopath = HDIF_get_iarray_item(sp, SPSS_IDATA_SP_IOPATH, 0, NULL);

	if (be16_to_cpu(iopath->iopath_type) != SPSS_IOPATH_TYPE_LPC) {
		prerror("BMC: Non-LPC IOPATH, this is probably broken\n");
		return;
	}

	/*
	 * For now we only instantiate the LPC node for the LPC that is used
	 * for Host <-> BMC comms. The secondary LPCs can be skipped.
	 */
	if (be16_to_cpu(iopath->lpc.link_status) != LPC_STATUS_ACTIVE)
		return;

#define GB (1024ul * 1024ul * 1024ul)
	/*
	 * convert the hdat chip ID the HW chip id so we get the right
	 * phys map offset
	 */
	chip_id = pcid_to_chip_id(be32_to_cpu(iopath->lpc.chip_id));

	phys_map_get(chip_id, LPC_BUS, 0, &lpcm_base, NULL);
	lpcm = dt_new_addr(dt_root, "lpcm-opb", lpcm_base);
	assert(lpcm);

	dt_add_property_cells(lpcm, "#address-cells", 1);
	dt_add_property_cells(lpcm, "#size-cells", 1);
	dt_add_property_strings(lpcm, "compatible",
		"ibm,power9-lpcm-opb", "simple-bus");
	dt_add_property_u64s(lpcm, "reg", lpcm_base, 0x100000000ul);

	dt_add_property_cells(lpcm, "ibm,chip-id", chip_id);

	/* Setup the ranges for the MMIO LPC */
	lpcm_end = lpcm_base + 2 * GB;
	dt_add_property_cells(lpcm, "ranges",
		0x00000000, hi32(lpcm_base), lo32(lpcm_base), 2 * GB,
		0x80000000, hi32(lpcm_end),  lo32(lpcm_end),  2 * GB);

	/*
	 * Despite the name the "BAR" values provided through the HDAT are
	 * the base addresses themselves rather than the BARs
	 */
	fw_bar = be32_to_cpu(iopath->lpc.firmware_bar);
	mem_bar = be32_to_cpu(iopath->lpc.memory_bar);
	io_bar = be32_to_cpu(iopath->lpc.io_bar);
	internal_bar = be32_to_cpu(iopath->lpc.internal_bar);

	prlog(PR_DEBUG, "LPC: IOPATH chip id = %x\n", chip_id);
	prlog(PR_DEBUG, "LPC: FW BAR       = %#x\n", fw_bar);
	prlog(PR_DEBUG, "LPC: MEM BAR      = %#x\n", mem_bar);
	prlog(PR_DEBUG, "LPC: IO BAR       = %#x\n", io_bar);
	prlog(PR_DEBUG, "LPC: Internal BAR = %#x\n", internal_bar);

	/*
	 * The internal address space BAR actually points to the LPC master
	 * registers. So we "fix" it by masking off the low bits.
	 *
	 * XXX: we probably need separate base addresses for all these things
	 */
	internal_bar &= 0xf0000000;

	/* Add the various internal bus devices */
	n = dt_new_addr(lpcm, "opb-master", internal_bar + 0x10000);
	dt_add_property_string(n, "compatible", "ibm,power9-lpcm-opb-master");
	dt_add_property_cells(n, "reg", internal_bar + 0x10000, 0x60);

	n = dt_new_addr(lpcm, "opb-arbiter", internal_bar + 0x11000);
	dt_add_property_string(n, "compatible", "ibm,power9-lpcm-opb-arbiter");
	dt_add_property_cells(n, "reg", internal_bar + 0x11000, 0x8);

	n = dt_new_addr(lpcm, "lpc-controller", internal_bar + 0x12000);
	dt_add_property_string(n, "compatible", "ibm,power9-lpc-controller");
	dt_add_property_cells(n, "reg", internal_bar + 0x12000, 0x100);

	/*
	 * FIXME: lpc@0 might not be accurate, but i'm pretty sure
	 * lpc@f0000000 isn't right either.
	 */
	lpc = dt_new_addr(lpcm, "lpc", 0x0);
	dt_add_property_cells(lpc, "#address-cells", 2);
	dt_add_property_cells(lpc, "#size-cells", 1);
	dt_add_property_strings(lpc, "compatible",
				"ibm,power9-lpc", "ibm,power8-lpc");

	dt_add_property_cells(lpc, "ranges",
		0, 0, mem_bar, 0x10000000, /* MEM space */
		1, 0, io_bar,  0x00010000, /* IO space  */
		/* we don't expose the internal space */
		3, 0, fw_bar,  0x10000000  /* FW space  */
	);

	add_uart(iopath, lpc);

	/* BT device info isn't currently populated */
	prlog(PR_DEBUG, "LPC: BT [%#"PRIx64", %#x] sms_int: %u, bmc_int: %u\n",
		iopath->lpc.bt_base, iopath->lpc.bt_size,
		iopath->lpc.bt_sms_int_num, iopath->lpc.bt_bmc_response_int_num
	);
}

/*
 * Search for and instanciate BMC nodes. This is mostly the same as fsp_parse()
 * below, but it can be called earlier since BMCs don't depend on the psihb
 * nodes being added.
 */
void bmc_parse(void)
{
	bool found = false;
	const void *sp;
	int i;

	sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG);
	if (!sp)
		return;

	for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, i, SPSS_HDIF_SIG) {
		if (find_service_proc_type(sp, i) == SP_BMC) {
			bmc_create_node(sp);
			found = true;
		}
	}

	if (found)
		early_uart_init();
}

void fsp_parse(void)
{
	struct dt_node *fsp_root = NULL, *fsp_node;
	const void *sp;
	int index;

	/* Find SPSS tuple in SPIRA */
	sp = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG);
	if (!sp) {
		prlog(PR_WARNING, "HDAT: No FSP/BMC found!\n");
		return;
	}

	for_each_ntuple_idx(&spira.ntuples.sp_subsys, sp, index, SPSS_HDIF_SIG) {
		switch (find_service_proc_type(sp, index)) {
		case SP_FSP:
			if (!fsp_root) {
				fsp_root = dt_new(dt_root, "fsps");
				assert(fsp_root);

				dt_add_property_cells(fsp_root,
					"#address-cells", 1);
				dt_add_property_cells(fsp_root,
					"#size-cells", 0);
			}

			fsp_node = fsp_create_node(sp, index, fsp_root);
			if (fsp_node)
				fsp_create_links(sp, index, fsp_node);

			break;

		case SP_BMC:
			/* Handled above */
			break;

		case SP_BAD:
			break;

		default:
			prerror("SP #%d: This service processor is not supported\n", index);
			break;
		}
	}
}
