// SPDX-License-Identifier: GPL-2.0
/*
 * Author:
 * Miquel Raynal <miquel.raynal@bootlin.com>
 *
 * Description:
 * SPI-level driver for TCG/TIS TPM (trusted platform module).
 * Specifications at www.trustedcomputinggroup.org
 *
 * This device driver implements the TPM interface as defined in
 * the TCG SPI protocol stack version 2.0.
 *
 * It is based on the U-Boot driver tpm_tis_infineon_i2c.c.
 */

#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <log.h>
#include <spi.h>
#include <tpm-v2.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/compiler.h>
#include <linux/types.h>
#include <linux/unaligned/be_byteshift.h>
#include <asm-generic/gpio.h>

#include "tpm_tis.h"
#include "tpm_internal.h"

DECLARE_GLOBAL_DATA_PTR;

#define TPM_ACCESS(l)			(0x0000 | ((l) << 12))
#define TPM_INT_ENABLE(l)               (0x0008 | ((l) << 12))
#define TPM_STS(l)			(0x0018 | ((l) << 12))
#define TPM_DATA_FIFO(l)		(0x0024 | ((l) << 12))
#define TPM_DID_VID(l)			(0x0F00 | ((l) << 12))
#define TPM_RID(l)			(0x0F04 | ((l) << 12))

#define MAX_SPI_FRAMESIZE 64

/* Number of wait states to wait for */
#define TPM_WAIT_STATES 100

/**
 * struct tpm_tis_chip_data - Non-discoverable TPM information
 *
 * @pcr_count:		Number of PCR per bank
 * @pcr_select_min:	Size in octets of the pcrSelect array
 */
struct tpm_tis_chip_data {
	unsigned int pcr_count;
	unsigned int pcr_select_min;
	unsigned int time_before_first_cmd_ms;
};

/**
 * tpm_tis_spi_read() - Read from TPM register
 *
 * @addr: register address to read from
 * @buffer: provided by caller
 * @len: number of bytes to read
 *
 * Read len bytes from TPM register and put them into
 * buffer (little-endian format, i.e. first byte is put into buffer[0]).
 *
 * NOTE: TPM is big-endian for multi-byte values. Multi-byte
 * values have to be swapped.
 *
 * @return -EIO on error, 0 on success.
 */
static int tpm_tis_spi_xfer(struct udevice *dev, u32 addr, const u8 *out,
			    u8 *in, u16 len)
{
	struct spi_slave *slave = dev_get_parent_priv(dev);
	int transfer_len, ret;
	u8 tx_buf[MAX_SPI_FRAMESIZE];
	u8 rx_buf[MAX_SPI_FRAMESIZE];

	if (in && out) {
		log(LOGC_NONE, LOGL_ERR, "%s: can't do full duplex\n",
		    __func__);
		return -EINVAL;
	}

	ret = spi_claim_bus(slave);
	if (ret < 0) {
		log(LOGC_NONE, LOGL_ERR, "%s: could not claim bus\n", __func__);
		return ret;
	}

	while (len) {
		/* Request */
		transfer_len = min_t(u16, len, MAX_SPI_FRAMESIZE);
		tx_buf[0] = (in ? BIT(7) : 0) | (transfer_len - 1);
		tx_buf[1] = 0xD4;
		tx_buf[2] = addr >> 8;
		tx_buf[3] = addr;

		ret = spi_xfer(slave, 4 * 8, tx_buf, rx_buf, SPI_XFER_BEGIN);
		if (ret < 0) {
			log(LOGC_NONE, LOGL_ERR,
			    "%s: spi request transfer failed (err: %d)\n",
			    __func__, ret);
			goto release_bus;
		}

		/* Wait state */
		if (!(rx_buf[3] & 0x1)) {
			int i;

			for (i = 0; i < TPM_WAIT_STATES; i++) {
				ret = spi_xfer(slave, 1 * 8, NULL, rx_buf, 0);
				if (ret) {
					log(LOGC_NONE, LOGL_ERR,
					    "%s: wait state failed: %d\n",
					    __func__, ret);
					goto release_bus;
				}

				if (rx_buf[0] & 0x1)
					break;
			}

			if (i == TPM_WAIT_STATES) {
				log(LOGC_NONE, LOGL_ERR,
				    "%s: timeout on wait state\n", __func__);
				ret = -ETIMEDOUT;
				goto release_bus;
			}
		}

		/* Read/Write */
		if (out) {
			memcpy(tx_buf, out, transfer_len);
			out += transfer_len;
		}

		ret = spi_xfer(slave, transfer_len * 8,
			       out ? tx_buf : NULL,
			       in ? rx_buf : NULL,
			       SPI_XFER_END);
		if (ret) {
			log(LOGC_NONE, LOGL_ERR,
			    "%s: spi read transfer failed (err: %d)\n",
			    __func__, ret);
			goto release_bus;
		}

		if (in) {
			memcpy(in, rx_buf, transfer_len);
			in += transfer_len;
		}

		len -= transfer_len;
	}

release_bus:
	/* If an error occurred, release the chip by deasserting the CS */
	if (ret < 0)
		spi_xfer(slave, 0, NULL, NULL, SPI_XFER_END);

	spi_release_bus(slave);

	return ret;
}

static int tpm_tis_spi_read(struct udevice *dev, u16 addr, u8 *in, u16 len)
{
	return tpm_tis_spi_xfer(dev, addr, NULL, in, len);
}

static int tpm_tis_spi_read32(struct udevice *dev, u32 addr, u32 *result)
{
	__le32 result_le;
	int ret;

	ret = tpm_tis_spi_read(dev, addr, (u8 *)&result_le, sizeof(u32));
	if (!ret)
		*result = le32_to_cpu(result_le);

	return ret;
}

static int tpm_tis_spi_write(struct udevice *dev, u16 addr, const u8 *out,
			     u16 len)
{
	return tpm_tis_spi_xfer(dev, addr, out, NULL, len);
}

static int tpm_tis_spi_check_locality(struct udevice *dev, int loc)
{
	const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
	struct tpm_chip *chip = dev_get_priv(dev);
	u8 buf;
	int ret;

	ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1);
	if (ret)
		return ret;

	if ((buf & mask) == mask) {
		chip->locality = loc;
		return 0;
	}

	return -ENOENT;
}

static void tpm_tis_spi_release_locality(struct udevice *dev, int loc,
					 bool force)
{
	const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
	u8 buf;

	if (tpm_tis_spi_read(dev, TPM_ACCESS(loc), &buf, 1) < 0)
		return;

	if (force || (buf & mask) == mask) {
		buf = TPM_ACCESS_ACTIVE_LOCALITY;
		tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1);
	}
}

static int tpm_tis_spi_request_locality(struct udevice *dev, int loc)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	unsigned long start, stop;
	u8 buf = TPM_ACCESS_REQUEST_USE;
	int ret;

	ret = tpm_tis_spi_check_locality(dev, loc);
	if (!ret)
		return 0;

	if (ret != -ENOENT) {
		log(LOGC_NONE, LOGL_ERR, "%s: Failed to get locality: %d\n",
		    __func__, ret);
		return ret;
	}

	ret = tpm_tis_spi_write(dev, TPM_ACCESS(loc), &buf, 1);
	if (ret) {
		log(LOGC_NONE, LOGL_ERR, "%s: Failed to write to TPM: %d\n",
		    __func__, ret);
		return ret;
	}

	start = get_timer(0);
	stop = chip->timeout_a;
	do {
		ret = tpm_tis_spi_check_locality(dev, loc);
		if (!ret)
			return 0;

		if (ret != -ENOENT) {
			log(LOGC_NONE, LOGL_ERR,
			    "%s: Failed to get locality: %d\n", __func__, ret);
			return ret;
		}

		mdelay(TPM_TIMEOUT_MS);
	} while (get_timer(start) < stop);

	log(LOGC_NONE, LOGL_ERR, "%s: Timeout getting locality: %d\n", __func__,
	    ret);

	return ret;
}

static u8 tpm_tis_spi_status(struct udevice *dev, u8 *status)
{
	struct tpm_chip *chip = dev_get_priv(dev);

	return tpm_tis_spi_read(dev, TPM_STS(chip->locality), status, 1);
}

static int tpm_tis_spi_wait_for_stat(struct udevice *dev, u8 mask,
				     unsigned long timeout, u8 *status)
{
	unsigned long start = get_timer(0);
	unsigned long stop = timeout;
	int ret;

	do {
		mdelay(TPM_TIMEOUT_MS);
		ret = tpm_tis_spi_status(dev, status);
		if (ret)
			return ret;

		if ((*status & mask) == mask)
			return 0;
	} while (get_timer(start) < stop);

	return -ETIMEDOUT;
}

static u8 tpm_tis_spi_valid_status(struct udevice *dev, u8 *status)
{
	struct tpm_chip *chip = dev_get_priv(dev);

	return tpm_tis_spi_wait_for_stat(dev, TPM_STS_VALID,
		chip->timeout_c, status);
}

static int tpm_tis_spi_get_burstcount(struct udevice *dev)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	unsigned long start, stop;
	u32 burstcount, ret;

	/* wait for burstcount */
	start = get_timer(0);
	stop = chip->timeout_d;
	do {
		ret = tpm_tis_spi_read32(dev, TPM_STS(chip->locality),
					 &burstcount);
		if (ret)
			return -EBUSY;

		burstcount = (burstcount >> 8) & 0xFFFF;
		if (burstcount)
			return burstcount;

		mdelay(TPM_TIMEOUT_MS);
	} while (get_timer(start) < stop);

	return -EBUSY;
}

static int tpm_tis_spi_cancel(struct udevice *dev)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	u8 data = TPM_STS_COMMAND_READY;

	return tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1);
}

static int tpm_tis_spi_recv_data(struct udevice *dev, u8 *buf, size_t count)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	int size = 0, burstcnt, len, ret;
	u8 status;

	while (size < count &&
	       tpm_tis_spi_wait_for_stat(dev,
					 TPM_STS_DATA_AVAIL | TPM_STS_VALID,
					 chip->timeout_c, &status) == 0) {
		burstcnt = tpm_tis_spi_get_burstcount(dev);
		if (burstcnt < 0)
			return burstcnt;

		len = min_t(int, burstcnt, count - size);
		ret = tpm_tis_spi_read(dev, TPM_DATA_FIFO(chip->locality),
				       buf + size, len);
		if (ret < 0)
			return ret;

		size += len;
	}

	return size;
}

static int tpm_tis_spi_recv(struct udevice *dev, u8 *buf, size_t count)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	int size, expected;

	if (!chip)
		return -ENODEV;

	if (count < TPM_HEADER_SIZE) {
		size = -EIO;
		goto out;
	}

	size = tpm_tis_spi_recv_data(dev, buf, TPM_HEADER_SIZE);
	if (size < TPM_HEADER_SIZE) {
		log(LOGC_NONE, LOGL_ERR, "TPM error, unable to read header\n");
		goto out;
	}

	expected = get_unaligned_be32(buf + 2);
	if (expected > count) {
		size = -EIO;
		goto out;
	}

	size += tpm_tis_spi_recv_data(dev, &buf[TPM_HEADER_SIZE],
				   expected - TPM_HEADER_SIZE);
	if (size < expected) {
		log(LOGC_NONE, LOGL_ERR,
		    "TPM error, unable to read remaining bytes of result\n");
		size = -EIO;
		goto out;
	}

out:
	tpm_tis_spi_cancel(dev);
	tpm_tis_spi_release_locality(dev, chip->locality, false);

	return size;
}

static int tpm_tis_spi_send(struct udevice *dev, const u8 *buf, size_t len)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	u32 i, size;
	u8 status;
	int burstcnt, ret;
	u8 data;

	if (!chip)
		return -ENODEV;

	if (len > TPM_DEV_BUFSIZE)
		return -E2BIG;  /* Command is too long for our tpm, sorry */

	ret = tpm_tis_spi_request_locality(dev, 0);
	if (ret < 0)
		return -EBUSY;

	/*
	 * Check if the TPM is ready. If not, if not, cancel the pending command
	 * and poll on the status to be finally ready.
	 */
	ret = tpm_tis_spi_status(dev, &status);
	if (ret)
		return ret;

	if (!(status & TPM_STS_COMMAND_READY)) {
		/* Force the transition, usually this will be done at startup */
		ret = tpm_tis_spi_cancel(dev);
		if (ret) {
			log(LOGC_NONE, LOGL_ERR,
			    "%s: Could not cancel previous operation\n",
			    __func__);
			goto out_err;
		}

		ret = tpm_tis_spi_wait_for_stat(dev, TPM_STS_COMMAND_READY,
						chip->timeout_b, &status);
		if (ret < 0 || !(status & TPM_STS_COMMAND_READY)) {
			log(LOGC_NONE, LOGL_ERR,
			    "status %d after wait for stat returned %d\n",
			    status, ret);
			goto out_err;
		}
	}

	for (i = 0; i < len - 1;) {
		burstcnt = tpm_tis_spi_get_burstcount(dev);
		if (burstcnt < 0)
			return burstcnt;

		size = min_t(int, len - i - 1, burstcnt);
		ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality),
					buf + i, size);
		if (ret < 0)
			goto out_err;

		i += size;
	}

	ret = tpm_tis_spi_valid_status(dev, &status);
	if (ret)
		goto out_err;

	if ((status & TPM_STS_DATA_EXPECT) == 0) {
		ret = -EIO;
		goto out_err;
	}

	ret = tpm_tis_spi_write(dev, TPM_DATA_FIFO(chip->locality),
				buf + len - 1, 1);
	if (ret)
		goto out_err;

	ret = tpm_tis_spi_valid_status(dev, &status);
	if (ret)
		goto out_err;

	if ((status & TPM_STS_DATA_EXPECT) != 0) {
		ret = -EIO;
		goto out_err;
	}

	data = TPM_STS_GO;
	ret = tpm_tis_spi_write(dev, TPM_STS(chip->locality), &data, 1);
	if (ret)
		goto out_err;

	return len;

out_err:
	tpm_tis_spi_cancel(dev);
	tpm_tis_spi_release_locality(dev, chip->locality, false);

	return ret;
}

static int tpm_tis_spi_cleanup(struct udevice *dev)
{
	struct tpm_chip *chip = dev_get_priv(dev);

	tpm_tis_spi_cancel(dev);
	/*
	 * The TPM needs some time to clean up here,
	 * so we sleep rather than keeping the bus busy
	 */
	mdelay(2);
	tpm_tis_spi_release_locality(dev, chip->locality, false);

	return 0;
}

static int tpm_tis_spi_open(struct udevice *dev)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);

	if (chip->is_open)
		return -EBUSY;

	chip->is_open = 1;

	return 0;
}

static int tpm_tis_spi_close(struct udevice *dev)
{
	struct tpm_chip *chip = dev_get_priv(dev);

	if (chip->is_open) {
		tpm_tis_spi_release_locality(dev, chip->locality, true);
		chip->is_open = 0;
	}

	return 0;
}

static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
{
	struct tpm_chip *chip = dev_get_priv(dev);

	if (size < 80)
		return -ENOSPC;

	return snprintf(buf, size,
			"%s v2.0: VendorID 0x%04x, DeviceID 0x%04x, RevisionID 0x%02x [%s]",
			dev->name, chip->vend_dev & 0xFFFF,
			chip->vend_dev >> 16, chip->rid,
			(chip->is_open ? "open" : "closed"));
}

static int tpm_tis_wait_init(struct udevice *dev, int loc)
{
	struct tpm_chip *chip = dev_get_priv(dev);
	unsigned long start, stop;
	u8 status;
	int ret;

	start = get_timer(0);
	stop = chip->timeout_b;
	do {
		mdelay(TPM_TIMEOUT_MS);

		ret = tpm_tis_spi_read(dev, TPM_ACCESS(loc), &status, 1);
		if (ret)
			break;

		if (status & TPM_ACCESS_VALID)
			return 0;
	} while (get_timer(start) < stop);

	return -EIO;
}

static int tpm_tis_spi_probe(struct udevice *dev)
{
	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);
	struct tpm_chip_priv *priv = dev_get_uclass_priv(dev);
	struct tpm_chip *chip = dev_get_priv(dev);
	int ret;

	/* Use the TPM v2 stack */
	priv->version = TPM_V2;

	if (CONFIG_IS_ENABLED(DM_GPIO)) {
		struct gpio_desc reset_gpio;

		ret = gpio_request_by_name(dev, "gpio-reset", 0,
					   &reset_gpio, GPIOD_IS_OUT);
		if (ret) {
			log(LOGC_NONE, LOGL_NOTICE, "%s: missing reset GPIO\n",
			    __func__);
		} else {
			dm_gpio_set_value(&reset_gpio, 1);
			mdelay(1);
			dm_gpio_set_value(&reset_gpio, 0);
		}
	}

	/* Ensure a minimum amount of time elapsed since reset of the TPM */
	mdelay(drv_data->time_before_first_cmd_ms);

	chip->locality = 0;
	chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
	chip->timeout_b = TIS_LONG_TIMEOUT_MS;
	chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
	chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
	priv->pcr_count = drv_data->pcr_count;
	priv->pcr_select_min = drv_data->pcr_select_min;

	ret = tpm_tis_wait_init(dev, chip->locality);
	if (ret) {
		log(LOGC_DM, LOGL_ERR, "%s: no device found\n", __func__);
		return ret;
	}

	ret = tpm_tis_spi_request_locality(dev, chip->locality);
	if (ret) {
		log(LOGC_NONE, LOGL_ERR, "%s: could not request locality %d\n",
		    __func__, chip->locality);
		return ret;
	}

	ret = tpm_tis_spi_read32(dev, TPM_DID_VID(chip->locality),
				 &chip->vend_dev);
	if (ret) {
		log(LOGC_NONE, LOGL_ERR,
		    "%s: could not retrieve VendorID/DeviceID\n", __func__);
		return ret;
	}

	ret = tpm_tis_spi_read(dev, TPM_RID(chip->locality), &chip->rid, 1);
	if (ret) {
		log(LOGC_NONE, LOGL_ERR, "%s: could not retrieve RevisionID\n",
		    __func__);
		return ret;
	}

	log(LOGC_NONE, LOGL_ERR,
	    "SPI TPMv2.0 found (vid:%04x, did:%04x, rid:%02x)\n",
	    chip->vend_dev & 0xFFFF, chip->vend_dev >> 16, chip->rid);

	return 0;
}

static int tpm_tis_spi_remove(struct udevice *dev)
{
	struct tpm_chip *chip = dev_get_priv(dev);

	tpm_tis_spi_release_locality(dev, chip->locality, true);

	return 0;
}

static const struct tpm_ops tpm_tis_spi_ops = {
	.open		= tpm_tis_spi_open,
	.close		= tpm_tis_spi_close,
	.get_desc	= tpm_tis_get_desc,
	.send		= tpm_tis_spi_send,
	.recv		= tpm_tis_spi_recv,
	.cleanup	= tpm_tis_spi_cleanup,
};

static const struct tpm_tis_chip_data tpm_tis_std_chip_data = {
	.pcr_count = 24,
	.pcr_select_min = 3,
	.time_before_first_cmd_ms = 30,
};

static const struct udevice_id tpm_tis_spi_ids[] = {
	{
		.compatible = "tis,tpm2-spi",
		.data = (ulong)&tpm_tis_std_chip_data,
	},
	{ }
};

U_BOOT_DRIVER(tpm_tis_spi) = {
	.name   = "tpm_tis_spi",
	.id     = UCLASS_TPM,
	.of_match = tpm_tis_spi_ids,
	.ops    = &tpm_tis_spi_ops,
	.probe	= tpm_tis_spi_probe,
	.remove	= tpm_tis_spi_remove,
	.priv_auto_alloc_size = sizeof(struct tpm_chip),
};
