/*
 * Copyright (c) 2011 The Chromium OS Authors.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * The code in this file is based on the article "Writing a TPM Device Driver"
 * published on http://ptgmedia.pearsoncmg.com.
 *
 * One principal difference is that in the simplest config the other than 0
 * TPM localities do not get mapped by some devices (for instance, by Infineon
 * slb9635), so this driver provides access to locality 0 only.
 */

#include <common.h>
#include <dm.h>
#include <mapmem.h>
#include <tpm.h>
#include <asm/io.h>

#define PREFIX "lpc_tpm: "

struct tpm_locality {
	u32 access;
	u8 padding0[4];
	u32 int_enable;
	u8 vector;
	u8 padding1[3];
	u32 int_status;
	u32 int_capability;
	u32 tpm_status;
	u8 padding2[8];
	u8 data;
	u8 padding3[3803];
	u32 did_vid;
	u8 rid;
	u8 padding4[251];
};

struct tpm_tis_lpc_priv {
	struct tpm_locality *regs;
};

/*
 * This pointer refers to the TPM chip, 5 of its localities are mapped as an
 * array.
 */
#define TPM_TOTAL_LOCALITIES	5

/* Some registers' bit field definitions */
#define TIS_STS_VALID                  (1 << 7) /* 0x80 */
#define TIS_STS_COMMAND_READY          (1 << 6) /* 0x40 */
#define TIS_STS_TPM_GO                 (1 << 5) /* 0x20 */
#define TIS_STS_DATA_AVAILABLE         (1 << 4) /* 0x10 */
#define TIS_STS_EXPECT                 (1 << 3) /* 0x08 */
#define TIS_STS_RESPONSE_RETRY         (1 << 1) /* 0x02 */

#define TIS_ACCESS_TPM_REG_VALID_STS   (1 << 7) /* 0x80 */
#define TIS_ACCESS_ACTIVE_LOCALITY     (1 << 5) /* 0x20 */
#define TIS_ACCESS_BEEN_SEIZED         (1 << 4) /* 0x10 */
#define TIS_ACCESS_SEIZE               (1 << 3) /* 0x08 */
#define TIS_ACCESS_PENDING_REQUEST     (1 << 2) /* 0x04 */
#define TIS_ACCESS_REQUEST_USE         (1 << 1) /* 0x02 */
#define TIS_ACCESS_TPM_ESTABLISHMENT   (1 << 0) /* 0x01 */

#define TIS_STS_BURST_COUNT_MASK       (0xffff)
#define TIS_STS_BURST_COUNT_SHIFT      (8)

 /* 1 second is plenty for anything TPM does. */
#define MAX_DELAY_US	(1000 * 1000)

/* Retrieve burst count value out of the status register contents. */
static u16 burst_count(u32 status)
{
	return (status >> TIS_STS_BURST_COUNT_SHIFT) &
			TIS_STS_BURST_COUNT_MASK;
}

/* TPM access wrappers to support tracing */
static u8 tpm_read_byte(struct tpm_tis_lpc_priv *priv, const u8 *ptr)
{
	u8  ret = readb(ptr);
	debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n",
	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
	return ret;
}

static u32 tpm_read_word(struct tpm_tis_lpc_priv *priv, const u32 *ptr)
{
	u32  ret = readl(ptr);
	debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n",
	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
	return ret;
}

static void tpm_write_byte(struct tpm_tis_lpc_priv *priv, u8 value, u8 *ptr)
{
	debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n",
	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
	writeb(value, ptr);
}

static void tpm_write_word(struct tpm_tis_lpc_priv *priv, u32 value,
			   u32 *ptr)
{
	debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n",
	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
	writel(value, ptr);
}

/*
 * tis_wait_reg()
 *
 * Wait for at least a second for a register to change its state to match the
 * expected state. Normally the transition happens within microseconds.
 *
 * @reg - pointer to the TPM register
 * @mask - bitmask for the bitfield(s) to watch
 * @expected - value the field(s) are supposed to be set to
 *
 * Returns the register contents in case the expected value was found in the
 * appropriate register bits, or -ETIMEDOUT on timeout.
 */
static int tis_wait_reg(struct tpm_tis_lpc_priv *priv, u32 *reg, u8 mask,
			u8 expected)
{
	u32 time_us = MAX_DELAY_US;

	while (time_us > 0) {
		u32 value = tpm_read_word(priv, reg);
		if ((value & mask) == expected)
			return value;
		udelay(1); /* 1 us */
		time_us--;
	}

	return -ETIMEDOUT;
}

/*
 * Probe the TPM device and try determining its manufacturer/device name.
 *
 * Returns 0 on success, -ve on error
 */
static int tpm_tis_lpc_probe(struct udevice *dev)
{
	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
	u32 vid, did;
	fdt_addr_t addr;
	u32 didvid;

	addr = dev_get_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;
	priv->regs = map_sysmem(addr, 0);
	didvid = tpm_read_word(priv, &priv->regs[0].did_vid);

	vid = didvid & 0xffff;
	did = (didvid >> 16) & 0xffff;
	if (vid != 0x15d1 || did != 0xb) {
		debug("Invalid vendor/device ID %04x/%04x\n", vid, did);
		return -ENOSYS;
	}

	debug("Found TPM %s by %s\n", "SLB9635 TT 1.2", "Infineon");

	return 0;
}

/*
 * tis_senddata()
 *
 * send the passed in data to the TPM device.
 *
 * @data - address of the data to send, byte by byte
 * @len - length of the data to send
 *
 * Returns 0 on success, -ve on error (in case the device does not accept
 * the entire command).
 */
static int tis_senddata(struct udevice *dev, const u8 *data, size_t len)
{
	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
	struct tpm_locality *regs = priv->regs;
	u32 offset = 0;
	u16 burst = 0;
	u32 max_cycles = 0;
	u8 locality = 0;
	u32 value;

	value = tis_wait_reg(priv, &regs[locality].tpm_status,
			     TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY);
	if (value == -ETIMEDOUT) {
		printf("%s:%d - failed to get 'command_ready' status\n",
		       __FILE__, __LINE__);
		return value;
	}
	burst = burst_count(value);

	while (1) {
		unsigned count;

		/* Wait till the device is ready to accept more data. */
		while (!burst) {
			if (max_cycles++ == MAX_DELAY_US) {
				printf("%s:%d failed to feed %zd bytes of %zd\n",
				       __FILE__, __LINE__, len - offset, len);
				return -ETIMEDOUT;
			}
			udelay(1);
			burst = burst_count(tpm_read_word(priv,
					&regs[locality].tpm_status));
		}

		max_cycles = 0;

		/*
		 * Calculate number of bytes the TPM is ready to accept in one
		 * shot.
		 *
		 * We want to send the last byte outside of the loop (hence
		 * the -1 below) to make sure that the 'expected' status bit
		 * changes to zero exactly after the last byte is fed into the
		 * FIFO.
		 */
		count = min((size_t)burst, len - offset - 1);
		while (count--)
			tpm_write_byte(priv, data[offset++],
				       &regs[locality].data);

		value = tis_wait_reg(priv, &regs[locality].tpm_status,
				     TIS_STS_VALID, TIS_STS_VALID);

		if ((value == -ETIMEDOUT) || !(value & TIS_STS_EXPECT)) {
			printf("%s:%d TPM command feed overflow\n",
			       __FILE__, __LINE__);
			return value == -ETIMEDOUT ? value : -EIO;
		}

		burst = burst_count(value);
		if ((offset == (len - 1)) && burst) {
			/*
			 * We need to be able to send the last byte to the
			 * device, so burst size must be nonzero before we
			 * break out.
			 */
			break;
		}
	}

	/* Send the last byte. */
	tpm_write_byte(priv, data[offset++], &regs[locality].data);
	/*
	 * Verify that TPM does not expect any more data as part of this
	 * command.
	 */
	value = tis_wait_reg(priv, &regs[locality].tpm_status,
			     TIS_STS_VALID, TIS_STS_VALID);
	if ((value == -ETIMEDOUT) || (value & TIS_STS_EXPECT)) {
		printf("%s:%d unexpected TPM status 0x%x\n",
		       __FILE__, __LINE__, value);
		return value == -ETIMEDOUT ? value : -EIO;
	}

	/* OK, sitting pretty, let's start the command execution. */
	tpm_write_word(priv, TIS_STS_TPM_GO, &regs[locality].tpm_status);
	return 0;
}

/*
 * tis_readresponse()
 *
 * read the TPM device response after a command was issued.
 *
 * @buffer - address where to read the response, byte by byte.
 * @len - pointer to the size of buffer
 *
 * On success stores the number of received bytes to len and returns 0. On
 * errors (misformatted TPM data or synchronization problems) returns
 * -ve value.
 */
static int tis_readresponse(struct udevice *dev, u8 *buffer, size_t len)
{
	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
	struct tpm_locality *regs = priv->regs;
	u16 burst;
	u32 value;
	u32 offset = 0;
	u8 locality = 0;
	const u32 has_data = TIS_STS_DATA_AVAILABLE | TIS_STS_VALID;
	u32 expected_count = len;
	int max_cycles = 0;

	/* Wait for the TPM to process the command. */
	value = tis_wait_reg(priv, &regs[locality].tpm_status,
			      has_data, has_data);
	if (value == -ETIMEDOUT) {
		printf("%s:%d failed processing command\n",
		       __FILE__, __LINE__);
		return value;
	}

	do {
		while ((burst = burst_count(value)) == 0) {
			if (max_cycles++ == MAX_DELAY_US) {
				printf("%s:%d TPM stuck on read\n",
				       __FILE__, __LINE__);
				return -EIO;
			}
			udelay(1);
			value = tpm_read_word(priv, &regs[locality].tpm_status);
		}

		max_cycles = 0;

		while (burst-- && (offset < expected_count)) {
			buffer[offset++] = tpm_read_byte(priv,
						&regs[locality].data);

			if (offset == 6) {
				/*
				 * We got the first six bytes of the reply,
				 * let's figure out how many bytes to expect
				 * total - it is stored as a 4 byte number in
				 * network order, starting with offset 2 into
				 * the body of the reply.
				 */
				u32 real_length;
				memcpy(&real_length,
				       buffer + 2,
				       sizeof(real_length));
				expected_count = be32_to_cpu(real_length);

				if ((expected_count < offset) ||
				    (expected_count > len)) {
					printf("%s:%d bad response size %d\n",
					       __FILE__, __LINE__,
					       expected_count);
					return -ENOSPC;
				}
			}
		}

		/* Wait for the next portion. */
		value = tis_wait_reg(priv, &regs[locality].tpm_status,
				     TIS_STS_VALID, TIS_STS_VALID);
		if (value == -ETIMEDOUT) {
			printf("%s:%d failed to read response\n",
			       __FILE__, __LINE__);
			return value;
		}

		if (offset == expected_count)
			break;	/* We got all we needed. */

	} while ((value & has_data) == has_data);

	/*
	 * Make sure we indeed read all there was. The TIS_STS_VALID bit is
	 * known to be set.
	 */
	if (value & TIS_STS_DATA_AVAILABLE) {
		printf("%s:%d wrong receive status %x\n",
		       __FILE__, __LINE__, value);
		return -EBADMSG;
	}

	/* Tell the TPM that we are done. */
	tpm_write_word(priv, TIS_STS_COMMAND_READY,
		       &regs[locality].tpm_status);

	return offset;
}

static int tpm_tis_lpc_open(struct udevice *dev)
{
	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
	struct tpm_locality *regs = priv->regs;
	u8 locality = 0; /* we use locality zero for everything. */
	int ret;

	/* now request access to locality. */
	tpm_write_word(priv, TIS_ACCESS_REQUEST_USE, &regs[locality].access);

	/* did we get a lock? */
	ret = tis_wait_reg(priv, &regs[locality].access,
			 TIS_ACCESS_ACTIVE_LOCALITY,
			 TIS_ACCESS_ACTIVE_LOCALITY);
	if (ret == -ETIMEDOUT) {
		printf("%s:%d - failed to lock locality %d\n",
		       __FILE__, __LINE__, locality);
		return ret;
	}

	tpm_write_word(priv, TIS_STS_COMMAND_READY,
		       &regs[locality].tpm_status);
	return 0;
}

static int tpm_tis_lpc_close(struct udevice *dev)
{
	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
	struct tpm_locality *regs = priv->regs;
	u8 locality = 0;

	if (tpm_read_word(priv, &regs[locality].access) &
	    TIS_ACCESS_ACTIVE_LOCALITY) {
		tpm_write_word(priv, TIS_ACCESS_ACTIVE_LOCALITY,
			       &regs[locality].access);

		if (tis_wait_reg(priv, &regs[locality].access,
				 TIS_ACCESS_ACTIVE_LOCALITY, 0) == -ETIMEDOUT) {
			printf("%s:%d - failed to release locality %d\n",
			       __FILE__, __LINE__, locality);
			return -ETIMEDOUT;
		}
	}
	return 0;
}

static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
{
	if (size < 50)
		return -ENOSPC;

	return snprintf(buf, size, "1.2 TPM (vendor %s, chip %s)",
			"Infineon", "SLB9635 TT 1.2");
}


static const struct tpm_ops tpm_tis_lpc_ops = {
	.open		= tpm_tis_lpc_open,
	.close		= tpm_tis_lpc_close,
	.get_desc	= tpm_tis_get_desc,
	.send		= tis_senddata,
	.recv		= tis_readresponse,
};

static const struct udevice_id tpm_tis_lpc_ids[] = {
	{ .compatible = "infineon,slb9635lpc" },
	{ }
};

U_BOOT_DRIVER(tpm_tis_lpc) = {
	.name   = "tpm_tis_lpc",
	.id     = UCLASS_TPM,
	.of_match = tpm_tis_lpc_ids,
	.ops    = &tpm_tis_lpc_ops,
	.probe	= tpm_tis_lpc_probe,
	.priv_auto_alloc_size = sizeof(struct tpm_tis_lpc_priv),
};
