Re: [U-Boot] [PATCH v2 03/19] tpm: add support for TPMv2 SPI modules

2018-04-24 Thread Miquel Raynal
Hi Simon,

On Fri, 30 Mar 2018 06:41:52 +0800, Simon Glass 
wrote:

> Hi Miquel,
> 
> On 29 March 2018 at 15:43, Miquel Raynal  wrote:
> > Add the tpm_tis_spi driver that should support any TPMv2 compliant (SPI)
> > module.
> >
> > Signed-off-by: Miquel Raynal 
> > ---
> >  drivers/tpm/Kconfig   |   9 +
> >  drivers/tpm/Makefile  |   1 +
> >  drivers/tpm/tpm_tis.h |   3 +
> >  drivers/tpm/tpm_tis_spi.c | 656 
> > ++
> >  4 files changed, 669 insertions(+)
> >  create mode 100644 drivers/tpm/tpm_tis_spi.c  
> 
> I think this came up in another context. Would it make sense to create
> a common interface to i2c and SPI and then have a common driver?

I hesitated to do it (even started to write down some common code), and
finally there was not so much of it, I was not sure if it would bring
something more than obfuscation so I chose not to add an extra layer as
I had currently only one SPI chip and no I2C chip to check the
architecture. Maybe the question should be asked again when someone
will want I2C support.

Regards,
Miquèl

___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


Re: [U-Boot] [PATCH v2 03/19] tpm: add support for TPMv2 SPI modules

2018-03-29 Thread Simon Glass
Hi Miquel,

On 29 March 2018 at 15:43, Miquel Raynal  wrote:
> Add the tpm_tis_spi driver that should support any TPMv2 compliant (SPI)
> module.
>
> Signed-off-by: Miquel Raynal 
> ---
>  drivers/tpm/Kconfig   |   9 +
>  drivers/tpm/Makefile  |   1 +
>  drivers/tpm/tpm_tis.h |   3 +
>  drivers/tpm/tpm_tis_spi.c | 656 
> ++
>  4 files changed, 669 insertions(+)
>  create mode 100644 drivers/tpm/tpm_tis_spi.c

I think this came up in another context. Would it make sense to create
a common interface to i2c and SPI and then have a common driver?

Regards,
Simon
___
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot


[U-Boot] [PATCH v2 03/19] tpm: add support for TPMv2 SPI modules

2018-03-29 Thread Miquel Raynal
Add the tpm_tis_spi driver that should support any TPMv2 compliant (SPI)
module.

Signed-off-by: Miquel Raynal 
---
 drivers/tpm/Kconfig   |   9 +
 drivers/tpm/Makefile  |   1 +
 drivers/tpm/tpm_tis.h |   3 +
 drivers/tpm/tpm_tis_spi.c | 656 ++
 4 files changed, 669 insertions(+)
 create mode 100644 drivers/tpm/tpm_tis_spi.c

diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig
index a98570ee77..cc57008b6a 100644
--- a/drivers/tpm/Kconfig
+++ b/drivers/tpm/Kconfig
@@ -46,6 +46,15 @@ config TPM_TIS_I2C_BURST_LIMITATION_LEN
help
  Use this to set the burst limitation length
 
+config TPM_TIS_SPI
+   bool "Enable support for TPMv2 SPI chips"
+   depends on TPM && DM_SPI
+   help
+ This driver supports TPMv2 devices connected on the SPI bus.
+ The usual TPM operations and the 'tpm' command can be used to talk
+ to the device using the standard TPM Interface Specification (TIS)
+ protocol
+
 config TPM_TIS_LPC
bool "Enable support for Infineon SLB9635/45 TPMs on LPC"
depends on TPM && X86
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index 5a19a58f43..a753b24230 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_TPM) += tpm-uclass.o
 
 obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o
 obj-$(CONFIG_TPM_TIS_INFINEON_I2C) += tpm_tis_infineon_i2c.o
+obj-$(CONFIG_TPM_TIS_SPI) += tpm_tis_spi.o
 obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
 obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o
 obj-$(CONFIG_TPM_ST33ZP24_I2C) += tpm_tis_st33zp24_i2c.o
diff --git a/drivers/tpm/tpm_tis.h b/drivers/tpm/tpm_tis.h
index 2b81f3be50..1f4b0c24bd 100644
--- a/drivers/tpm/tpm_tis.h
+++ b/drivers/tpm/tpm_tis.h
@@ -37,6 +37,9 @@ enum tpm_timeout {
 #define TPM_RSP_SIZE_BYTE  2
 #define TPM_RSP_RC_BYTE6
 
+/* Number of xfer retries */
+#define TPM_XFER_RETRY 10
+
 struct tpm_chip {
int is_open;
int locality;
diff --git a/drivers/tpm/tpm_tis_spi.c b/drivers/tpm/tpm_tis_spi.c
new file mode 100644
index 00..17f6cfa85c
--- /dev/null
+++ b/drivers/tpm/tpm_tis_spi.c
@@ -0,0 +1,656 @@
+/*
+ * Author:
+ * Miquel Raynal 
+ *
+ * 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.
+ *
+ * SPDX-License-Identifier:GPL-2.0
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "tpm_tis.h"
+#include "tpm_internal.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TPM_ACCESS(l)  (0x | ((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
+
+/*
+ * 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) {
+   debug("%s: cannot do full duplex\n", __func__);
+   return -EINVAL;
+   }
+
+   ret = spi_claim_bus(slave);
+   if (ret < 0) {
+   debug("%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) {
+   debug("%s: spi request transfer failed (err: %d)\n",
+ __func__, ret);
+   goto release_bus;
+   }
+
+   /* Wait state */
+   if (!(rx_buf[3] & 0x1)) {
+   int i;
+
+