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

#include <skiboot.h>
#include <device.h>
#include <console.h>
#include <psi.h>
#include <chip.h>
#include <xscom.h>
#include <ast.h>
#include <ipmi.h>
#include <bt.h>
#include <errorlog.h>
#include <lpc.h>
#include <timebase.h>

#include "astbmc.h"

/* UART1 config */
#define UART_IO_BASE	0x3f8
#define UART_IO_COUNT	8
#define UART_LPC_IRQ	4

/* BT config */
#define BT_IO_BASE	0xe4
#define BT_IO_COUNT	3
#define BT_LPC_IRQ	10

/* MBOX config */
#define MBOX_IO_BASE 0x1000
#define MBOX_IO_COUNT 6
#define MBOX_LPC_IRQ 9

/* MCTP config */
#define MCTP_IO_BASE	0xca2
#define MCTP_IO_COUNT	2
#define MCTP_LPC_IRQ	11

void astbmc_ext_irq_serirq_cpld(unsigned int chip_id)
{
	lpc_all_interrupts(chip_id);
}

static void astbmc_ipmi_error(struct ipmi_msg *msg)
{
        prlog(PR_DEBUG, "ASTBMC: error sending msg. cc = %02x\n", msg->cc);

        ipmi_free_msg(msg);
}

static void astbmc_ipmi_setenables(void)
{
        struct ipmi_msg *msg;

        struct {
                uint8_t oem2_en : 1;
                uint8_t oem1_en : 1;
                uint8_t oem0_en : 1;
                uint8_t reserved : 1;
                uint8_t sel_en : 1;
                uint8_t msgbuf_en : 1;
                uint8_t msgbuf_full_int_en : 1;
                uint8_t rxmsg_queue_int_en : 1;
        } data;

        memset(&data, 0, sizeof(data));

        /* The spec says we need to read-modify-write to not clobber
         * the state of the other flags. These are set on by the bmc */
        data.rxmsg_queue_int_en = 1;
        data.sel_en = 1;

        /* These are the ones we want to set on */
        data.msgbuf_en = 1;

        msg = ipmi_mkmsg_simple(IPMI_SET_ENABLES, &data, sizeof(data));
        if (!msg) {
		/**
		 * @fwts-label ASTBMCFailedSetEnables
		 * @fwts-advice AST BMC is likely to be non-functional
		 * when accessed from host.
		 */
                prlog(PR_ERR, "ASTBMC: failed to set enables\n");
                return;
        }

        msg->error = astbmc_ipmi_error;

        ipmi_queue_msg(msg);

}

static int astbmc_fru_init(void)
{
	const struct dt_property *prop;
	struct dt_node *node;
	uint8_t fru_id;

	node = dt_find_by_path(dt_root, "bmc");
	if (!node)
		return -1;

	prop = dt_find_property(node, "firmware-fru-id");
	if (!prop)
		return -1;

	fru_id = dt_property_get_cell(prop, 0) & 0xff;
	ipmi_fru_init(fru_id);
	return 0;
}


void astbmc_init(void)
{
	/* Register the BT interface with the IPMI layer
	 *
	 * Initialise this first to enable PNOR access
	 */
	bt_init();

	/* Initialize PNOR/NVRAM */
	pnor_init();

	/* Initialize elog */
	elog_init();
	ipmi_sel_init();
	ipmi_wdt_init();
	ipmi_rtc_init();
	ipmi_opal_init();
	astbmc_fru_init();
	ipmi_sensor_init();

	/* Request BMC information */
	ipmi_get_bmc_info_request();

	/* As soon as IPMI is up, inform BMC we are in "S0" */
	ipmi_set_power_state(IPMI_PWR_SYS_S0_WORKING, IPMI_PWR_NOCHANGE);

        /* Enable IPMI OEM message interrupts */
        astbmc_ipmi_setenables();

	ipmi_set_fw_progress_sensor(IPMI_FW_MOTHERBOARD_INIT);

	/* Setup UART console for use by Linux via OPAL API */
	set_opal_console(&uart_opal_con);
}

int64_t astbmc_ipmi_power_down(uint64_t request)
{
	if (request != IPMI_CHASSIS_PWR_DOWN) {
		prlog(PR_WARNING, "PLAT: unexpected shutdown request %llx\n",
				   request);
	}

	return ipmi_chassis_control(request);
}

int64_t astbmc_ipmi_reboot(void)
{
	return ipmi_chassis_control(IPMI_CHASSIS_HARD_RESET);
}

void astbmc_seeprom_update(void)
{
	int flag_set, counter, rc;

	rc = ipmi_get_chassis_boot_opt_request();

	if (rc) {
		prlog(PR_WARNING, "Failed to check SBE validation flag\n");
		return;
	}

	flag_set = ipmi_chassis_check_sbe_validation();

	if (flag_set <= 0) {
		prlog(PR_DEBUG, "SBE validation flag unset or invalid\n");
		return;
	}

	/*
	 * Flag is set, wait until SBE validation is complete and the flag
	 * has been reset.
	 */
	prlog(PR_WARNING, "SBE validation required, waiting for completion\n");
	prlog(PR_WARNING, "System will be powered off if validation fails\n");
	counter = 0;

	while (flag_set > 0) {
		time_wait_ms(10000);
		if (++counter % 3 == 0) {
			/* Let the user know we're alive every 30s */
			prlog(PR_WARNING, "waiting for completion...\n");
		}
		if (counter == 180) {
			/* This is longer than expected and we have no way of
			 * checking if it's still running. Apologies if you
			 * ever see this message.
			 */
			prlog(PR_WARNING, "30 minutes has elapsed, this is longer than expected for verification\n");
			prlog(PR_WARNING, "If no progress is made a power reset of the BMC and Host may be required\n");
			counter = 0;
		}

		/* As above, loop anyway if we fail to check the flag */
		rc = ipmi_get_chassis_boot_opt_request();
		if (rc == 0)
			flag_set = ipmi_chassis_check_sbe_validation();
		else
			prlog(PR_WARNING, "Failed to check SBE validation flag\n");
	}

	/*
	 * The SBE validation can (will) leave the SBE in a bad state,
	 * preventing timers from working properly. Reboot so that we
	 * can boot normally with everything intact.
	 */
	prlog(PR_WARNING, "SBE validation complete, rebooting\n");
	if (platform.cec_reboot)
		platform.cec_reboot();
	else
		abort();
	while(true);
}

static void astbmc_fixup_dt_system_id(void)
{
	/* Make sure we don't already have one */
	if (dt_find_property(dt_root, "system-id"))
		return;

	dt_add_property_strings(dt_root, "system-id", "unavailable");
}

#ifdef CONFIG_PLDM
static void astbmc_fixup_dt_mctp(struct dt_node *lpc)
{
	struct dt_node *mctp;
	char namebuf[32];

	if (!lpc)
		return;

	/* First check if the mbox interface is already there */
	dt_for_each_child(lpc, mctp) {
		if (dt_node_is_compatible(mctp, "mctp"))
			return;
	}

	snprintf(namebuf, sizeof(namebuf), "mctp@i%x", MCTP_IO_BASE);
	mctp = dt_new(lpc, namebuf);

	dt_add_property_cells(mctp, "reg",
			      1, /* IO space */
			      MCTP_IO_BASE, MCTP_IO_COUNT);
	dt_add_property_strings(mctp, "compatible", "mctp");

	/* Mark it as reserved to avoid Linux trying to claim it */
	dt_add_property_strings(mctp, "status", "reserved");

	dt_add_property_cells(mctp, "interrupts", MCTP_LPC_IRQ);
	dt_add_property_cells(mctp, "interrupt-parent", lpc->phandle);
}
#endif

static void astbmc_fixup_dt_bt(struct dt_node *lpc)
{
	struct dt_node *bt;
	char namebuf[32];

	/* First check if the BT interface is already there */
	dt_for_each_child(lpc, bt) {
		if (dt_node_is_compatible(bt, "bt"))
			return;
	}

	snprintf(namebuf, sizeof(namebuf), "ipmi-bt@i%x", BT_IO_BASE);
	bt = dt_new(lpc, namebuf);

	dt_add_property_cells(bt, "reg",
			      1, /* IO space */
			      BT_IO_BASE, BT_IO_COUNT);
	dt_add_property_strings(bt, "compatible", "ipmi-bt");

	/* Mark it as reserved to avoid Linux trying to claim it */
	dt_add_property_strings(bt, "status", "reserved");

	dt_add_property_cells(bt, "interrupts", BT_LPC_IRQ);
	dt_add_property_cells(bt, "interrupt-parent", lpc->phandle);
}

static void astbmc_fixup_dt_mbox(struct dt_node *lpc)
{
	struct dt_node *mbox;
	char namebuf[32];

	if (!lpc)
		return;

	/*
	 * P9 machines always use hiomap, either by ipmi or mbox. P8 machines
	 * can indicate they support mbox using the scratch register, or ipmi
	 * by configuring the hiomap ipmi command. If neither are configured
	 * for P8 then skiboot will drive the flash controller directly.
	 * XXX P10
	 */
	if (proc_gen == proc_gen_p8 && !ast_scratch_reg_is_mbox())
		return;

	/* First check if the mbox interface is already there */
	dt_for_each_child(lpc, mbox) {
		if (dt_node_is_compatible(mbox, "mbox"))
			return;
	}

	snprintf(namebuf, sizeof(namebuf), "mbox@i%x", MBOX_IO_BASE);
	mbox = dt_new(lpc, namebuf);

	dt_add_property_cells(mbox, "reg",
			      1, /* IO space */
			      MBOX_IO_BASE, MBOX_IO_COUNT);
	dt_add_property_strings(mbox, "compatible", "mbox");

	/* Mark it as reserved to avoid Linux trying to claim it */
	dt_add_property_strings(mbox, "status", "reserved");

	dt_add_property_cells(mbox, "interrupts", MBOX_LPC_IRQ);
	dt_add_property_cells(mbox, "interrupt-parent", lpc->phandle);
}

static void astbmc_fixup_dt_uart(struct dt_node *lpc)
{
	/*
	 * The official OF ISA/LPC binding is a bit odd, it prefixes
	 * the unit address for IO with "i". It uses 2 cells, the first
	 * one indicating IO vs. Memory space (along with bits to
	 * represent aliasing).
	 *
	 * We pickup that binding and add to it "2" as a indication
	 * of FW space.
	 */
	struct dt_node *uart;
	char namebuf[32];

	/* First check if the UART is already there */
	dt_for_each_child(lpc, uart) {
		if (dt_node_is_compatible(uart, "ns16550"))
			return;
	}

	/* Otherwise, add a node for it */
	snprintf(namebuf, sizeof(namebuf), "serial@i%x", UART_IO_BASE);
	uart = dt_new(lpc, namebuf);

	dt_add_property_cells(uart, "reg",
			      1, /* IO space */
			      UART_IO_BASE, UART_IO_COUNT);
	dt_add_property_strings(uart, "compatible",
				"ns16550",
				"pnpPNP,501");
	dt_add_property_cells(uart, "clock-frequency", 1843200);
	dt_add_property_cells(uart, "current-speed", 115200);

	/*
	 * This is needed by Linux for some obscure reasons,
	 * we'll eventually need to sanitize it but in the meantime
	 * let's make sure it's there
	 */
	dt_add_property_strings(uart, "device_type", "serial");

	/* Add interrupt */
	dt_add_property_cells(uart, "interrupts", UART_LPC_IRQ);
	dt_add_property_cells(uart, "interrupt-parent", lpc->phandle);
}

static void del_compatible(struct dt_node *node)
{
	struct dt_property *prop;

	prop = __dt_find_property(node, "compatible");
	if (prop)
		dt_del_property(node, prop);
}


static void astbmc_fixup_bmc_sensors(void)
{
	struct dt_node *parent, *node;

	parent = dt_find_by_path(dt_root, "bmc");
	if (!parent)
		return;
	del_compatible(parent);

	parent = dt_find_by_name(parent, "sensors");
	if (!parent)
		return;
	del_compatible(parent);

	dt_for_each_child(parent, node) {
		if (dt_find_property(node, "compatible"))
			continue;
		dt_add_property_string(node, "compatible", "ibm,ipmi-sensor");
	}
}

static struct dt_node *dt_find_primary_lpc(void)
{
	struct dt_node *n, *primary_lpc = NULL;

	/* Find the primary LPC bus */
	dt_for_each_compatible(dt_root, n, "ibm,power8-lpc") {
		if (!primary_lpc || dt_has_node_property(n, "primary", NULL))
			primary_lpc = n;
		if (dt_has_node_property(n, "#address-cells", NULL))
			break;
	}
	dt_for_each_compatible(dt_root, n, "ibm,power9-lpc") {
		if (!primary_lpc || dt_has_node_property(n, "primary", NULL))
			primary_lpc = n;
		if (dt_has_node_property(n, "#address-cells", NULL))
			break;
	}

	return primary_lpc;
}

static void astbmc_fixup_dt(void)
{
	struct dt_node *primary_lpc;

	primary_lpc = dt_find_primary_lpc();

	if (!primary_lpc)
		return;

	/* Fixup the UART, that might be missing from HB */
	astbmc_fixup_dt_uart(primary_lpc);

	/* BT is not in HB either */
	astbmc_fixup_dt_bt(primary_lpc);

#ifdef CONFIG_PLDM
	/* Fixup the MCTP, that might be missing from HB */
	astbmc_fixup_dt_mctp(primary_lpc);
#endif

	/* The pel logging code needs a system-id property to work so
	   make sure we have one. */
	astbmc_fixup_dt_system_id();

	if (proc_gen == proc_gen_p8)
		astbmc_fixup_bmc_sensors();
}

static void astbmc_fixup_psi_bar(void)
{
	struct proc_chip *chip = next_chip(NULL);
	uint64_t psibar;

	/* This is P8 specific */
	if (proc_gen != proc_gen_p8)
		return;

	/* Read PSI BAR */
	if (xscom_read(chip->id, 0x201090A, &psibar)) {
		prerror("PLAT: Error reading PSI BAR\n");
		return;
	}
	/* Already configured, bail out */
	if (psibar & 1)
		return;

	/* Hard wire ... yuck */
	psibar = 0x3fffe80000001UL;

	printf("PLAT: Fixing up PSI BAR on chip %d BAR=%llx\n",
	       chip->id, psibar);

	/* Now write it */
	xscom_write(chip->id, 0x201090A, psibar);
}

static void astbmc_fixup_uart(void)
{
	/*
	 * Depending on which image we are running, it may be configuring the
	 * virtual UART or not.  Check if VUART is enabled and use SIO if not.
	 * We also correct the configuration of VUART as some BMC images don't
	 * setup the interrupt properly
	 */
	if (ast_is_vuart1_enabled()) {
		printf("PLAT: Using virtual UART\n");
		ast_disable_sio_uart1();
		ast_setup_vuart1(UART_IO_BASE, UART_LPC_IRQ);
	} else {
		printf("PLAT: Using SuperIO UART\n");
		ast_setup_sio_uart1(UART_IO_BASE, UART_LPC_IRQ);
	}
}

void astbmc_early_init(void)
{
	/* Hostboot's device-tree isn't quite right yet */
	astbmc_fixup_dt();

	/* Hostboot forgets to populate the PSI BAR */
	astbmc_fixup_psi_bar();

	if (ast_sio_init()) {
		if (ast_io_init()) {
			astbmc_fixup_uart();
			ast_setup_ibt(BT_IO_BASE, BT_LPC_IRQ);
		} else
			prerror("PLAT: AST IO initialisation failed!\n");

		/*
		 * P9 prefers IPMI for HIOMAP but will use MBOX if IPMI is not
		 * supported. P8 either uses IPMI HIOMAP or direct IO, and
		 * never MBOX. Thus only populate the MBOX node on P9 to allow
		 * fallback.
		 */
		if (proc_gen >= proc_gen_p9) {
			astbmc_fixup_dt_mbox(dt_find_primary_lpc());
			ast_setup_sio_mbox(MBOX_IO_BASE, MBOX_LPC_IRQ);
		}
	} else {
		/*
		 * This may or may not be an error depending on if we set up
		 * hiomap or not. In the old days it *was* an error, but now
		 * with the way we configure the BMC hardware, this is actually
		 * the not error case.
		 */
		prlog(PR_INFO, "PLAT: AST SIO unavailable!\n");
	}

	/* Setup UART and use it as console */
	uart_init();

	prd_init();
}

void astbmc_exit(void)
{
	ipmi_wdt_final_reset();

	ipmi_set_boot_count();

	/*
	 * Booting into an OS that may not call back into skiboot for
	 * some time. Ensure all IPMI messages are processed first.
	 */
	ipmi_flush();
}

static const struct bmc_sw_config bmc_sw_ami = {
	.ipmi_oem_partial_add_esel   = IPMI_CODE(0x3a, 0xf0),
	.ipmi_oem_pnor_access_status = IPMI_CODE(0x3a, 0x07),
	.ipmi_oem_hiomap_cmd         = IPMI_CODE(0x3a, 0x5a),
};

static const struct bmc_sw_config bmc_sw_openbmc = {
	.ipmi_oem_partial_add_esel   = IPMI_CODE(0x3a, 0xf0),
	.ipmi_oem_hiomap_cmd         = IPMI_CODE(0x3a, 0x5a),
};

/* Extracted from a Palmetto */
const struct bmc_hw_config bmc_hw_ast2400 = {
	.scu_revision_id = 0x2010303,
	.mcr_configuration = 0x00000577,
	.mcr_scu_mpll = 0x000050c0,
	.mcr_scu_strap = 0x00000000,
};

/* Extracted from a Witherspoon */
const struct bmc_hw_config bmc_hw_ast2500 = {
	.scu_revision_id = 0x04030303,
	.mcr_configuration = 0x11200756,
	.mcr_scu_mpll = 0x000071C1,
	.mcr_scu_strap = 0x00000000,
};

/* XXX P10: Update with Rainier values */
const struct bmc_hw_config bmc_hw_ast2600 = {
	.scu_revision_id = 0x05000303,
	.mcr_configuration = 0x11200756,
	.mcr_scu_mpll = 0x1008405F,
	.mcr_scu_strap = 0x000030E0,
};

const struct bmc_platform bmc_plat_ast2400_ami = {
	.name = "ast2400:ami",
	.hw = &bmc_hw_ast2400,
	.sw = &bmc_sw_ami,
};

const struct bmc_platform bmc_plat_ast2500_ami = {
	.name = "ast2500:ami",
	.hw = &bmc_hw_ast2500,
	.sw = &bmc_sw_ami,
};

const struct bmc_platform bmc_plat_ast2500_openbmc = {
	.name = "ast2500:openbmc",
	.hw = &bmc_hw_ast2500,
	.sw = &bmc_sw_openbmc,
};

const struct bmc_platform bmc_plat_ast2600_openbmc = {
	.name = "ast2600:openbmc",
	.hw = &bmc_hw_ast2600,
	.sw = &bmc_sw_openbmc,
};
