/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/io.h>
#include <console/console.h>
#include <device/smbus_def.h>
#include <device/smbus_host.h>
#include <types.h>

#if CONFIG(DEBUG_SMBUS)
#define dprintk(args...) printk(BIOS_DEBUG, ##args)
#else
#define dprintk(args...) do {} while (0)
#endif

/* SMBus register offsets. */
#define SMBHSTSTAT		0x0
#define SMBHSTCTL		0x2
#define SMBHSTCMD		0x3
#define SMBXMITADD		0x4
#define SMBHSTDAT0		0x5
#define SMBHSTDAT1		0x6
#define SMBBLKDAT		0x7
#define SMBTRNSADD		0x9
#define SMBSLVDATA		0xa
#define SMLINK_PIN_CTL		0xe
#define SMBUS_PIN_CTL		0xf
#define SMBSLVCMD		0x11

#define SMB_RCV_SLVA		SMBTRNSADD

/* I801 command constants */
#define I801_QUICK		(0 << 2)
#define I801_BYTE		(1 << 2)
#define I801_BYTE_DATA		(2 << 2)
#define I801_WORD_DATA		(3 << 2)
#define I801_PROCESS_CALL	(4 << 2)
#define I801_BLOCK_DATA		(5 << 2)
#define I801_I2C_BLOCK_DATA	(6 << 2) /* ICH5 and later */

/* I801 Host Control register bits */
#define SMBHSTCNT_INTREN	(1 << 0)
#define SMBHSTCNT_KILL		(1 << 1)
#define SMBHSTCNT_LAST_BYTE	(1 << 5)
#define SMBHSTCNT_START		(1 << 6)
#define SMBHSTCNT_PEC_EN	(1 << 7) /* ICH3 and later */

/* I801 Hosts Status register bits */
#define SMBHSTSTS_BYTE_DONE	(1 << 7)
#define SMBHSTSTS_INUSE_STS	(1 << 6)
#define SMBHSTSTS_SMBALERT_STS	(1 << 5)
#define SMBHSTSTS_FAILED	(1 << 4)
#define SMBHSTSTS_BUS_ERR	(1 << 3)
#define SMBHSTSTS_DEV_ERR	(1 << 2)
#define SMBHSTSTS_INTR		(1 << 1)
#define SMBHSTSTS_HOST_BUSY	(1 << 0)

/* For SMBXMITADD register. */
#define XMIT_WRITE(dev)		(((dev) << 1) | 0)
#define XMIT_READ(dev)		(((dev) << 1) | 1)

#define SMBUS_TIMEOUT		(10 * 1000 * 100)
#define SMBUS_BLOCK_MAXLEN	32

/* block_cmd_loop flags */
#define BLOCK_READ	0
#define BLOCK_WRITE	(1 << 0)
#define BLOCK_I2C	(1 << 1)

static void smbus_delay(void)
{
	inb(0x80);
}

static void host_outb(uintptr_t base, u8 reg, u8 value)
{
	outb(value, base + reg);
}

static u8 host_inb(uintptr_t base, u8 reg)
{
	return inb(base + reg);
}

static void host_and_or(uintptr_t base, u8 reg, u8 mask, u8 or)
{
	u8 value;
	value = host_inb(base, reg);
	value &= mask;
	value |= or;
	host_outb(base, reg, value);
}

void smbus_host_reset(uintptr_t base)
{
	/* Disable interrupt generation. */
	host_outb(base, SMBHSTCTL, 0);

	/* Clear any lingering errors, so transactions can run. */
	host_and_or(base, SMBHSTSTAT, 0xff, 0);
}

void smbus_set_slave_addr(uintptr_t base, u8 slave_address)
{
	host_outb(base, SMB_RCV_SLVA, slave_address);
}

static int host_completed(u8 status)
{
	if (status & SMBHSTSTS_HOST_BUSY)
		return 0;

	/* These status bits do not imply completion of transaction. */
	status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS |
		    SMBHSTSTS_SMBALERT_STS);
	return status != 0;
}

static int recover_master(uintptr_t base, int ret)
{
	/* TODO: Depending of the failure, drive KILL transaction
	 * or force soft reset on SMBus master controller.
	 */
	printk(BIOS_ERR, "SMBus: Fatal master timeout (%d)\n", ret);
	return ret;
}

static int cb_err_from_stat(u8 status)
{
	/* These status bits do not imply errors. */
	status &= ~(SMBHSTSTS_BYTE_DONE | SMBHSTSTS_INUSE_STS |
		    SMBHSTSTS_SMBALERT_STS);

	if (status == SMBHSTSTS_INTR)
		return 0;

	return SMBUS_ERROR;
}

static int setup_command(uintptr_t base, u8 ctrl, u8 xmitadd)
{
	unsigned int loops = SMBUS_TIMEOUT;
	u8 host_busy;

	do {
		smbus_delay();
		host_busy = host_inb(base, SMBHSTSTAT) & SMBHSTSTS_HOST_BUSY;
	} while (--loops && host_busy);

	if (loops == 0)
		return recover_master(base, SMBUS_WAIT_UNTIL_READY_TIMEOUT);

	/* Clear any lingering errors, so the transaction will run. */
	host_and_or(base, SMBHSTSTAT, 0xff, 0);

	/* Set up transaction */
	/* Disable interrupts */
	host_outb(base, SMBHSTCTL, ctrl);

	/* Set the device I'm talking to. */
	host_outb(base, SMBXMITADD, xmitadd);

	return 0;
}

static int execute_command(uintptr_t base)
{
	unsigned int loops = SMBUS_TIMEOUT;
	u8 status;

	/* Start the command. */
	host_and_or(base, SMBHSTCTL, 0xff, SMBHSTCNT_START);

	/* Poll for it to start. */
	do {
		smbus_delay();

		/* If we poll too slow, we could miss HOST_BUSY flag
		 * set and detect INTR or x_ERR flags instead here.
		 */
		status = host_inb(base, SMBHSTSTAT);
		status &= ~(SMBHSTSTS_SMBALERT_STS | SMBHSTSTS_INUSE_STS);
	} while (--loops && status == 0);

	if (loops == 0)
		return recover_master(base,
				      SMBUS_WAIT_UNTIL_ACTIVE_TIMEOUT);

	return 0;
}

static int complete_command(uintptr_t base)
{
	unsigned int loops = SMBUS_TIMEOUT;
	u8 status;

	do {
		smbus_delay();
		status = host_inb(base, SMBHSTSTAT);
	} while (--loops && !host_completed(status));

	if (loops == 0)
		return recover_master(base,
				      SMBUS_WAIT_UNTIL_DONE_TIMEOUT);

	return cb_err_from_stat(status);
}

static int smbus_read_cmd(uintptr_t base, u8 ctrl, u8 device, u8 address)
{
	int ret;
	u16 word;

	/* Set up for a byte data read. */
	ret = setup_command(base, ctrl, XMIT_READ(device));
	if (ret < 0)
		return ret;

	/* Set the command/address... */
	host_outb(base, SMBHSTCMD, address);

	/* Clear the data bytes... */
	host_outb(base, SMBHSTDAT0, 0);
	host_outb(base, SMBHSTDAT1, 0);

	/* Start the command */
	ret = execute_command(base);
	if (ret < 0)
		return ret;

	/* Poll for transaction completion */
	ret = complete_command(base);
	if (ret < 0)
		return ret;

	/* Read results of transaction */
	word = host_inb(base, SMBHSTDAT0);
	if (ctrl == I801_WORD_DATA)
		word |= host_inb(base, SMBHSTDAT1) << 8;

	return word;
}

static int smbus_write_cmd(uintptr_t base, u8 ctrl, u8 device, u8 address, u16 data)
{
	int ret;

	/* Set up for a byte data write. */
	ret = setup_command(base, ctrl, XMIT_WRITE(device));
	if (ret < 0)
		return ret;

	/* Set the command/address... */
	host_outb(base, SMBHSTCMD, address);

	/* Set the data bytes... */
	host_outb(base, SMBHSTDAT0, data & 0xff);
	if (ctrl == I801_WORD_DATA)
		host_outb(base, SMBHSTDAT1, data >> 8);

	/* Start the command */
	ret = execute_command(base);
	if (ret < 0)
		return ret;

	/* Poll for transaction completion */
	return complete_command(base);
}

static int block_cmd_loop(uintptr_t base, u8 *buf, size_t max_bytes, int flags)
{
	u8 status;
	unsigned int loops = SMBUS_TIMEOUT;
	int ret;
	size_t bytes = 0;
	int is_write_cmd = flags & BLOCK_WRITE;
	int sw_drives_nak = flags & BLOCK_I2C;

	/* Hardware limitations. */
	if (flags == (BLOCK_WRITE | BLOCK_I2C))
		return SMBUS_ERROR;

	/* Set number of bytes to transfer. */
	/* Reset number of bytes to transfer so we notice later it
	 * was really updated with the transaction. */
	if (!sw_drives_nak) {
		if (is_write_cmd)
			host_outb(base, SMBHSTDAT0, max_bytes);
		else
			host_outb(base, SMBHSTDAT0, 0);
	}

	/* Send first byte from buffer, bytes_sent increments after
	 * hardware acknowledges it.
	 */
	if (is_write_cmd)
		host_outb(base, SMBBLKDAT, *buf++);

	/* Start the command */
	ret = execute_command(base);
	if (ret < 0)
		return ret;

	/* Poll for transaction completion */
	do {
		status = host_inb(base, SMBHSTSTAT);

		if (status & SMBHSTSTS_BYTE_DONE) { /* Byte done */

			if (is_write_cmd) {
				bytes++;
				if (bytes < max_bytes)
					host_outb(base, SMBBLKDAT, *buf++);
			} else {
				if (bytes < max_bytes)
					*buf++ = host_inb(base, SMBBLKDAT);
				bytes++;

				/* Indicate that next byte is the last one. */
				if (sw_drives_nak && (bytes + 1 >= max_bytes)) {
					host_and_or(base, SMBHSTCTL, 0xff,
						    SMBHSTCNT_LAST_BYTE);
				}

			}

			/* Engine internally completes the transaction
			 * and clears HOST_BUSY flag once the byte count
			 * has been reached or LAST_BYTE was set.
			 */
			host_outb(base, SMBHSTSTAT, SMBHSTSTS_BYTE_DONE);
		}

	} while (--loops && !host_completed(status));

	dprintk("%s: status = %02x, len = %zd / %zd, loops = %d\n",
		__func__, status, bytes, max_bytes, SMBUS_TIMEOUT - loops);

	if (loops == 0)
		return recover_master(base, SMBUS_WAIT_UNTIL_DONE_TIMEOUT);

	ret = cb_err_from_stat(status);
	if (ret < 0)
		return ret;

	return bytes;
}

int do_smbus_read_byte(uintptr_t base, u8 device, u8 address)
{
	return smbus_read_cmd(base, I801_BYTE_DATA, device, address);
}

int do_smbus_read_word(uintptr_t base, u8 device, u8 address)
{
	return smbus_read_cmd(base, I801_WORD_DATA, device, address);
}

int do_smbus_write_byte(uintptr_t base, u8 device, u8 address, u8 data)
{
	return smbus_write_cmd(base, I801_BYTE_DATA, device, address, data);
}

int do_smbus_write_word(uintptr_t base, u8 device, u8 address, u16 data)
{
	return smbus_write_cmd(base, I801_WORD_DATA, device, address, data);
}

int do_smbus_block_read(uintptr_t base, u8 device, u8 cmd, size_t max_bytes, u8 *buf)
{
	int ret, slave_bytes;

	max_bytes = MIN(SMBUS_BLOCK_MAXLEN, max_bytes);

	/* Set up for a block data read. */
	ret = setup_command(base, I801_BLOCK_DATA, XMIT_READ(device));
	if (ret < 0)
		return ret;

	/* Set the command/address... */
	host_outb(base, SMBHSTCMD, cmd);

	/* Execute block transaction. */
	ret = block_cmd_loop(base, buf, max_bytes, BLOCK_READ);
	if (ret < 0)
		return ret;

	/* Post-check we received complete message. */
	slave_bytes = host_inb(base, SMBHSTDAT0);
	if (ret < slave_bytes)
		return SMBUS_ERROR;

	return ret;
}

/*
 * The caller is responsible of settings HOSTC I2C_EN bit prior to making this
 * call!
 */
int do_smbus_process_call(uintptr_t base, u8 device, u8 cmd, u16 data, u16 *buf)
{
	int ret;

	/* Set up for process call */
	ret = setup_command(base, I801_PROCESS_CALL, XMIT_WRITE(device));
	if (ret < 0)
		return ret;

	/* cmd will only be send if I2C_EN is zero */
	host_outb(base, SMBHSTCMD, cmd);

	host_outb(base, SMBHSTDAT0, data & 0x00ff);
	host_outb(base, SMBHSTDAT1, (data & 0xff00) >> 8);

	/* Start the command */
	ret = execute_command(base);
	if (ret < 0)
		return ret;

	/* Poll for transaction completion */
	ret = complete_command(base);
	if (ret < 0)
		return ret;

	/* Read results of transaction */
	*buf = host_inb(base, SMBHSTDAT0);
	*buf |= (host_inb(base, SMBHSTDAT1) << 8);

	return ret;
}

int do_smbus_block_write(uintptr_t base, u8 device, u8 cmd, const size_t bytes, const u8 *buf)
{
	int ret;

	if (bytes > SMBUS_BLOCK_MAXLEN)
		return SMBUS_ERROR;

	/* Set up for a block data write. */
	ret = setup_command(base, I801_BLOCK_DATA, XMIT_WRITE(device));
	if (ret < 0)
		return ret;

	/* Set the command/address... */
	host_outb(base, SMBHSTCMD, cmd);

	/* Execute block transaction. */
	ret = block_cmd_loop(base, (u8 *)buf, bytes, BLOCK_WRITE);
	if (ret < 0)
		return ret;

	if (ret < bytes)
		return SMBUS_ERROR;

	return ret;
}

/* Only since ICH5 */
static int has_i2c_read_command(void)
{
	if (CONFIG(SOUTHBRIDGE_INTEL_I82371EB))
		return 0;
	return 1;
}

int do_i2c_eeprom_read(uintptr_t base, u8 device, u8 offset, const size_t bytes, u8 *buf)
{
	int ret;

	if (!has_i2c_read_command())
		return SMBUS_ERROR;

	/* Set up for a i2c block data read.
	 *
	 * FIXME: Address parameter changes to XMIT_READ(device) with
	 * some revision of PCH. Presumably hardware revisions that
	 * do not have i2c block write support internally set LSB.
	 */
	ret = setup_command(base, I801_I2C_BLOCK_DATA,
			    XMIT_WRITE(device));
	if (ret < 0)
		return ret;

	/* device offset */
	host_outb(base, SMBHSTDAT1, offset);

	/* Execute block transaction. */
	ret = block_cmd_loop(base, buf, bytes, BLOCK_READ | BLOCK_I2C);
	if (ret < 0)
		return ret;

	/* Post-check we received complete message. */
	if (ret < bytes)
		return SMBUS_ERROR;

	return ret;
}

/*
 * The caller is responsible of settings HOSTC I2C_EN bit prior to making this
 * call!
 */
int do_i2c_block_write(uintptr_t base, u8 device, size_t bytes, u8 *buf)
{
	u8 cmd;
	int ret;

	if (!CONFIG(SOC_INTEL_BRASWELL))
		return SMBUS_ERROR;

	if (!bytes || (bytes > SMBUS_BLOCK_MAXLEN))
		return SMBUS_ERROR;

	/* Set up for a block data write. */
	ret = setup_command(base, I801_BLOCK_DATA, XMIT_WRITE(device));
	if (ret < 0)
		return ret;

	/*
	 * In i2c mode SMBus controller sequence on bus will be:
	 * <SMBXINTADD> <SMBHSTDAT1> <SMBBLKDAT> .. <SMBBLKDAT>
	 * The SMBHSTCMD must be written also to ensure the SMBUs controller
	 * will generate the i2c sequence.
	*/
	cmd = *buf++;
	bytes--;
	host_outb(base, SMBHSTCMD, cmd);
	host_outb(base, SMBHSTDAT1, cmd);

	/* Execute block transaction. */
	ret = block_cmd_loop(base, buf, bytes, BLOCK_WRITE);
	if (ret < 0)
		return ret;

	if (ret < bytes)
		return SMBUS_ERROR;

	ret++; /* 1st byte has been written using SMBHSTDAT1 */
	return ret;
}
