/*
 * 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 %d bytes of %d\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((u32)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),
};
