// SPDX-License-Identifier: GPL-2.0
/*
 * driver for mmio TCG/TIS TPM (trusted platform module).
 *
 * Specifications at www.trustedcomputinggroup.org
 */

#include <dm.h>
#include <log.h>
#include <tpm-v2.h>
#include <linux/bitops.h>
#include <linux/compiler.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/io.h>
#include <linux/unaligned/be_byteshift.h>
#include "tpm_tis.h"
#include "tpm_internal.h"

/**
 * struct tpm_tis_chip_data - Information about an MMIO TPM
 * @pcr_count:          Number of PCR per bank
 * @pcr_select_min:	Minimum size in bytes of the pcrSelect array
 * @iobase:		Base address
 */
struct tpm_tis_chip_data {
	unsigned int pcr_count;
	unsigned int pcr_select_min;
	void __iomem *iobase;
};

static int mmio_read_bytes(struct udevice *dev, u32 addr, u16 len,
			   u8 *result)
{
	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);

	while (len--)
		*result++ = ioread8(drv_data->iobase + addr);

	return 0;
}

static int mmio_write_bytes(struct udevice *dev, u32 addr, u16 len,
			    const u8 *value)
{
	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);

	while (len--)
		iowrite8(*value++, drv_data->iobase + addr);

	return 0;
}

static int mmio_read32(struct udevice *dev, u32 addr, u32 *result)
{
	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);

	*result = ioread32(drv_data->iobase + addr);

	return 0;
}

static int mmio_write32(struct udevice *dev, u32 addr, u32 value)
{
	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);

	iowrite32(value, drv_data->iobase + addr);

	return 0;
}

static struct tpm_tis_phy_ops phy_ops = {
	.read_bytes = mmio_read_bytes,
	.write_bytes = mmio_write_bytes,
	.read32 = mmio_read32,
	.write32 = mmio_write32,
};

static int tpm_tis_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);
	int ret = 0;
	fdt_addr_t ioaddr;
	u64 sz;

	ioaddr = dev_read_addr(dev);
	if (ioaddr == FDT_ADDR_T_NONE)
		return log_msg_ret("ioaddr", -EINVAL);

	ret = dev_read_u64(dev, "reg", &sz);
	if (ret)
		return -EINVAL;

	drv_data->iobase = ioremap(ioaddr, sz);
	tpm_tis_ops_register(dev, &phy_ops);
	ret = tpm_tis_init(dev);
	if (ret)
		goto iounmap;

	priv->pcr_count = drv_data->pcr_count;
	priv->pcr_select_min = drv_data->pcr_select_min;
	/*
	 * Although the driver probably works with a TPMv1 our Kconfig
	 * limits the driver to TPMv2 only
	 */
	priv->version = TPM_V2;

	return ret;
iounmap:
	iounmap(drv_data->iobase);

	return -EINVAL;
}

static int tpm_tis_remove(struct udevice *dev)
{
	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev);
	int ret;

	ret = tpm_tis_cleanup(dev);

	iounmap(drv_data->iobase);

	return ret;
}

static const struct tpm_ops tpm_tis_ops = {
	.open		= tpm_tis_open,
	.close		= tpm_tis_close,
	.get_desc	= tpm_tis_get_desc,
	.send		= tpm_tis_send,
	.recv		= tpm_tis_recv,
	.cleanup	= tpm_tis_cleanup,
};

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

static const struct udevice_id tpm_tis_ids[] = {
	{
		.compatible = "tcg,tpm-tis-mmio",
		.data = (ulong)&tpm_tis_std_chip_data,
	},
	{ }
};

U_BOOT_DRIVER(tpm_tis_mmio) = {
	.name   = "tpm_tis_mmio",
	.id     = UCLASS_TPM,
	.of_match = tpm_tis_ids,
	.ops    = &tpm_tis_ops,
	.probe	= tpm_tis_probe,
	.remove	= tpm_tis_remove,
	.priv_auto	= sizeof(struct tpm_chip),
};
