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

#define pr_fmt(fmt) "AST-MCTP: " fmt

#include <lock.h>
#include <lpc.h>
#include <interrupts.h>
#include <timer.h>
#include <timebase.h>
#include <debug_descriptor.h>
#include <device.h>
#include <ast.h>
#include <console.h>
#include <pldm.h>
#include <libmctp.h>
#include <libmctp-cmds.h>
#include <libmctp-log.h>
#include <libmctp-astlpc.h>

static struct mctp *mctp;
static struct mctp_binding_astlpc *astlpc;
static struct astlpc_ops_data *ops_data;
static struct lock mctp_lock = LOCK_UNLOCKED;

/* Keyboard Controller Style (KCS) data register address */
#define KCS_DATA_REG 0xca2

/* Keyboard Controller Style (KCS) status register address */
#define KCS_STATUS_REG 0xca3

#define KCS_STATUS_BMC_READY 0x80
#define KCS_STATUS_OBF       0x01

#define HOST_MAX_INCOMING_MESSAGE_ALLOCATION 131072
#define DESIRED_MTU 32768

#define TX_POLL_MAX 5

/*
 * The AST LPC binding is described here:
 *
 * https://github.com/openbmc/libmctp/blob/master/docs/bindings/vendor-ibm-astlpc.md
 *
 * Most of the binding is implemented in libmctp, but we need to provide
 * accessors for the LPC FW space (for the packet buffer) and for the KCS
 * peripheral (for the interrupt mechanism).
 */

struct astlpc_ops_data {
	uint16_t kcs_data_addr; /* LPC IO space offset for the data register */
	uint16_t kcs_stat_addr;

	/* address of the packet exchange buffer in FW space */
	uint32_t lpc_fw_addr;
};

static int astlpc_kcs_reg_read(void *binding_data,
			       enum mctp_binding_astlpc_kcs_reg reg,
			       uint8_t *val)
{
	struct astlpc_ops_data *ops_data = binding_data;
	uint32_t addr;

	if (reg == MCTP_ASTLPC_KCS_REG_STATUS)
		addr = ops_data->kcs_stat_addr;
	else if (reg == MCTP_ASTLPC_KCS_REG_DATA)
		addr = ops_data->kcs_data_addr;
	else
		return OPAL_PARAMETER;

	*val = lpc_inb(addr);

	return OPAL_SUCCESS;
}

static int astlpc_kcs_reg_write(void *binding_data,
				enum mctp_binding_astlpc_kcs_reg reg,
				uint8_t val)
{
	struct astlpc_ops_data *ops_data = binding_data;
	uint32_t addr;

	prlog(PR_TRACE, "%s 0x%hhx to %s\n",
			__func__, val, reg ? "status" : "data");

	if (reg == MCTP_ASTLPC_KCS_REG_STATUS)
		addr = ops_data->kcs_stat_addr;
	else if (reg == MCTP_ASTLPC_KCS_REG_DATA)
		addr = ops_data->kcs_data_addr;
	else
		return OPAL_PARAMETER;

	lpc_outb(val, addr);

	return OPAL_SUCCESS;
}

static int astlpc_read(void *binding_data, void *buf, long offset,
		       size_t len)
{
	struct astlpc_ops_data *ops_data = binding_data;

	prlog(PR_TRACE, "%s %zu bytes from 0x%lx (lpc: 0x%lx)\n",
			__func__, len, offset,
			ops_data->lpc_fw_addr + offset);
	return lpc_fw_read(ops_data->lpc_fw_addr + offset, buf, len);
}

static int astlpc_write(void *binding_data, const void *buf,
			long offset, size_t len)
{
	struct astlpc_ops_data *ops_data = binding_data;

	prlog(PR_TRACE, "%s %zu bytes to offset 0x%lx (lpc: 0x%lx)\n",
			__func__, len, offset,
			ops_data->lpc_fw_addr + offset);
	return lpc_fw_write(ops_data->lpc_fw_addr + offset, buf, len);
}

static const struct mctp_binding_astlpc_ops astlpc_ops = {
	.kcs_read = astlpc_kcs_reg_read,
	.kcs_write = astlpc_kcs_reg_write,
	.lpc_read = astlpc_read,
	.lpc_write = astlpc_write,
};

/* we need a poller to crank the mctp state machine during boot */
static void astlpc_poller(void *data)
{
	struct mctp_binding_astlpc *astlpc = (struct mctp_binding_astlpc *)data;

	if (astlpc)
		mctp_astlpc_poll(astlpc);
}

/* at runtime the interrupt should handle it */
static void astlpc_interrupt(uint32_t chip_id __unused,
			     uint32_t irq_msk __unused)
{
	if (astlpc)
		mctp_astlpc_poll(astlpc);
}

static struct lpc_client kcs_lpc_client = {
	.reset = NULL,
	.interrupt = astlpc_interrupt,
};

static void drain_odr(struct astlpc_ops_data *ops_data)
{
	uint8_t kcs_status, kcs_data;
	uint8_t drain_counter = 255;

	astlpc_kcs_reg_read(ops_data, MCTP_ASTLPC_KCS_REG_STATUS, &kcs_status);

	while (--drain_counter && (kcs_status & KCS_STATUS_OBF)) {
		astlpc_kcs_reg_read(ops_data, MCTP_ASTLPC_KCS_REG_DATA, &kcs_data);
		time_wait_ms(5);
		astlpc_kcs_reg_read(ops_data, MCTP_ASTLPC_KCS_REG_STATUS, &kcs_status);
	}
}

static int astlpc_binding(void)
{
	struct mctp_bus *bus;
	int counter = 0;

	ops_data = zalloc(sizeof(struct astlpc_ops_data));
	if (!ops_data)
		return OPAL_NO_MEM;

	/*
	 * Current OpenBMC systems put the MCTP buffer 1MB down from
	 * the end of the LPC FW range.
	 *
	 * The size of the FW range is: 0x1000_0000 so the window be at:
	 *
	 *   0x1000_0000 - 2**20 == 0xff00000
	 */
	ops_data->lpc_fw_addr = 0xff00000;

	/* values chosen by the OpenBMC driver */
	ops_data->kcs_data_addr = KCS_DATA_REG;
	ops_data->kcs_stat_addr = KCS_STATUS_REG;

	/* Initialise the binding */
	astlpc = mctp_astlpc_init(MCTP_BINDING_ASTLPC_MODE_HOST,
				  DESIRED_MTU,
				  NULL,
				  &astlpc_ops,
				  ops_data);
	if (!astlpc) {
		prlog(PR_ERR, "binding init failed\n");
		return OPAL_HARDWARE;
	}

	/* Read and discard any potentially stale messages in the ODR */
	drain_odr(ops_data);

	/* Register the binding to the LPC bus we are using for this
	 * MCTP configuration.
	 */
	if (mctp_register_bus(mctp,
			      mctp_binding_astlpc_core(astlpc),
			      HOST_EID)) {
		prlog(PR_ERR, "failed to register bus\n");
		goto err;
	}

	/* lpc/kcs status register poller */
	opal_add_poller(astlpc_poller, astlpc);

	/* Don't start sending messages to the BMC until the bus has
	 * been registered and tx has been enabled
	 */
	bus = mctp_binding_astlpc_core(astlpc)->bus;

	while ((bus == NULL) ||
	      (mctp_bus_get_state(bus) == mctp_bus_state_constructed)) {
		if (++counter >= 1000) {
			prlog(PR_ERR, "failed to initialize MCTP channel\n");
			goto err;
		}
		time_wait_ms(5);

		/* Update bus pointer if it is a nullptr */
		if (bus == NULL)
			bus = mctp_binding_astlpc_core(astlpc)->bus;
	}

	return OPAL_SUCCESS;

err:
	mctp_astlpc_destroy(astlpc);
	free(ops_data);

	return OPAL_HARDWARE;
}

static void *mctp_malloc(size_t size) { return malloc(size); }
static void mctp_free(void *ptr) { return free(ptr); }
static void *mctp_realloc(void *ptr, size_t size)
{
	return realloc(ptr, size);
}

#ifdef AST_MCTP_DEBUG
char buffer[320];
static void mctp_log(int log_lvl, const char *fmt, va_list va)
{
	snprintf(buffer, sizeof(buffer), "%s\n", fmt);
	vprlog(log_lvl, buffer, va);
}
#endif

int ast_mctp_message_tx(bool tag_owner, uint8_t msg_tag,
			uint8_t *msg, int msg_len)
{
	unsigned long stop_time;
	int rc = OPAL_SUCCESS;

	lock(&mctp_lock);

	rc = mctp_message_tx(mctp, BMC_EID, tag_owner, msg_tag,
			     msg, msg_len);
	unlock(&mctp_lock);

	/* do not poll when we respond to a BMC request */
	if (tag_owner)
		return rc;

	/* read the Rx_complete command out of the ODR */
	stop_time = mftb() + msecs_to_tb(TX_POLL_MAX);
	while (mftb() < stop_time && !mctp_astlpc_tx_done(astlpc))
		mctp_astlpc_poll(astlpc);

	return rc;
}

static void message_rx(uint8_t eid, bool tag_owner,
		       uint8_t msg_tag, void *data __unused,
		       void *vmsg, size_t len)
{
	uint8_t *msg = (uint8_t *)vmsg;

	prlog(PR_TRACE, "message received: msg type: %x, len %zd"
			" (eid: %d), rx tag %d owner %d\n",
			 *msg, len, eid, tag_owner, msg_tag);

	/* The first byte defines the type of MCTP packet payload
	 * contained in the message data portion of the MCTP message.
	 * (See DSP0236 for more details about MCTP packet fields).
	 * For now we only support PLDM over MCTP.
	 */
	switch (*msg) {
	case MCTP_MSG_TYPE_PLDM:
		/* handle the PLDM message */
		pldm_mctp_message_rx(eid, tag_owner, msg_tag,
				     msg + sizeof(uint8_t),
				     len - sizeof(uint8_t));
		break;
	default:
		prlog(PR_ERR, "%s - not a pldm message type (type: %x)\n",
			      __func__, *msg);
	}
}

/*
 * Initialize mctp binding for hbrt and provide interfaces for sending
 * and receiving mctp messages.
 */
int ast_mctp_init(void)
{
	uint32_t kcs_serial_irq;
	struct dt_node *n;

	/* Search mctp node */
	n = dt_find_compatible_node(dt_root, NULL, "mctp");
	if (!n) {
		prlog(PR_ERR, "No MCTP device\n");
		return OPAL_PARAMETER;
	}

	/* skiboot's malloc/free/realloc are macros so they need
	 * wrappers
	 */
	mctp_set_alloc_ops(mctp_malloc, mctp_free, mctp_realloc);

	/*
	 * /-----\                                        /---------\
	 * | bmc | (eid: 8) <- lpc pcie / kcs -> (eid: 9) | skiboot |
	 * \-----/                                        \---------/
	 */
	mctp = mctp_init();
	if (!mctp) {
		prlog(PR_ERR, "mctp init failed\n");
		return OPAL_HARDWARE;
	}

#ifdef AST_MCTP_DEBUG
	/* Setup the trace hook */
	mctp_set_log_custom(mctp_log);
#endif

	/* Set the max message size to be large enough */
	mctp_set_max_message_size(mctp, HOST_MAX_INCOMING_MESSAGE_ALLOCATION);

	/* Setup the message rx callback */
	mctp_set_rx_all(mctp, message_rx, NULL);

	/* Initialize the binding */
	if (astlpc_binding())
		goto err;

	/* register an lpc client so we get an interrupt */
	kcs_serial_irq = dt_prop_get_u32(n, "interrupts");
	kcs_lpc_client.interrupts = LPC_IRQ(kcs_serial_irq);
	lpc_register_client(dt_get_chip_id(n), &kcs_lpc_client, IRQ_ATTR_TARGET_OPAL);

	return OPAL_SUCCESS;

err:
	prlog(PR_ERR, "Unable to initialize MCTP\n");
	mctp_destroy(mctp);
	mctp = NULL;

	return OPAL_HARDWARE;
}

void ast_mctp_exit(void)
{
	if (astlpc) {
		mctp_astlpc_destroy(astlpc);
		astlpc = NULL;
	}

	if (mctp) {
		mctp_destroy(mctp);
		mctp = NULL;
	}
}
