[U-Boot] [PATCH 2/2] i2c: ST33ZP24 I2C TPM driver
Simon Glass
sjg at chromium.org
Sat Jul 19 06:13:46 CEST 2014
Hi Jean-Luc,
On 9 July 2014 01:40, Jean-Luc BLANC <stmicroelectronics.tpm at gmail.com> wrote:
> This driver add support for STMicroelectronics ST33ZP24 I2C TPM.
> ---
> README | 6 +
> drivers/tpm/Makefile | 1 +
> drivers/tpm/tpm_i2c_stm_st33.c | 633 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 640 insertions(+)
> create mode 100644 drivers/tpm/tpm_i2c_stm_st33.c
>
> diff --git a/README b/README
> index a4aa28a..c4463d8 100644
> --- a/README
> +++ b/README
> @@ -1426,6 +1426,12 @@ The following options need to be configured:
> TPM1_SPI_CS
> Define SPI Chip Select ID connected to TPM
>
> + CONFIG_TPM_ST_I2C
> + Support I2C STMicroelectronics TPM. Require I2C support
> +
> + CONFIG_TPM_I2C_BUS
> + Define the i2c bus number for the TPM device
> +
> - USB Support:
> At the moment only the UHCI host controller is
> supported (PIP405, MIP405, MPC5200); define
> diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
> index 1ee707e..29e1f80 100644
> --- a/drivers/tpm/Makefile
> +++ b/drivers/tpm/Makefile
> @@ -10,3 +10,4 @@ obj-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
> obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
> obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o
> obj-$(CONFIG_TPM_ST_SPI) += tpm_spi_stm_st33.o
> +obj-$(CONFIG_TPM_ST_I2C) += tpm_i2c_stm_st33.o
> diff --git a/drivers/tpm/tpm_i2c_stm_st33.c b/drivers/tpm/tpm_i2c_stm_st33.c
> new file mode 100644
> index 0000000..6e20f8c
> --- /dev/null
> +++ b/drivers/tpm/tpm_i2c_stm_st33.c
> @@ -0,0 +1,633 @@
> +/*
> + * STMicroelectronics TPM I2C UBOOT Linux driver for TPM ST33ZP24
> + * Copyright (C) 2014 STMicroelectronics
> + *
> + * Description: Device driver for ST33ZP24 I2C TPM TCG.
> + *
> + * This device driver implements the TPM interface as defined in
> + * the TCG TPM Interface Spec version 1.21, revision 1.0 and the
> + * STMicroelectronics I2C Protocol Stack Specification version 1.2.0.
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + *
> + * @Author: Jean-Luc BLANC <jean-luc.blanc at st.com>
> + *
> + * @File: tpm_i2c_stm_st33.c
> + */
> +
> +#include <common.h>
> +#include <i2c.h>
> +#include <linux/types.h>
> +#include <tpm.h>
> +#include <errno.h>
> +#include <asm/unaligned.h>
> +
> +#define MINOR_NUM_I2C 224
> +
> +#define TPM_ACCESS 0x0
> +#define TPM_STS 0x18
> +#define TPM_HASH_END 0x20
> +#define TPM_DATA_FIFO 0x24
> +#define TPM_HASH_DATA 0x24
> +#define TPM_HASH_START 0x28
> +#define TPM_INTF_CAPABILITY 0x14
> +#define TPM_INT_STATUS 0x10
> +#define TPM_INT_ENABLE 0x08
> +
> +#define TPM_DUMMY_BYTE 0xAA
> +#define TPM_WRITE_DIRECTION 0x80
> +#define TPM_HEADER_SIZE 10
> +#define TPM_BUFSIZE 2048
> +
> +#define LOCALITY0 0
> +#define LOCALITY4 4
> +#define LOCALITY0_I2C_ADDR 0x13
> +#define LOCALITY4_I2C_ADDR 0x1B
If the chips have a lot of common defines / functions, please put them
in a common header file/interface. Duplicated code creates problems
for refactoring later.
> +
> +/* Index of Count field in TPM response buffer */
> +#define TPM_RSP_SIZE_BYTE 2
> +
> +/* Maximum command duration */
> +#define TPM_MAX_COMMAND_DURATION_MS 120000
> +
> +enum stm33zp24_access {
> + TPM_ACCESS_VALID = 0x80,
> + TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
> + TPM_ACCESS_REQUEST_PENDING = 0x04,
> + TPM_ACCESS_REQUEST_USE = 0x02,
> +};
> +
> +enum stm33zp24_status {
> + TPM_STS_VALID = 0x80,
> + TPM_STS_COMMAND_READY = 0x40,
> + TPM_STS_GO = 0x20,
> + TPM_STS_DATA_AVAIL = 0x10,
> + TPM_STS_DATA_EXPECT = 0x08,
> +};
> +
> +enum stm33zp24_int_flags {
> + TPM_GLOBAL_INT_ENABLE = 0x80,
> + TPM_INTF_CMD_READY_INT = 0x080,
> + TPM_INTF_FIFO_AVALAIBLE_INT = 0x040,
> + TPM_INTF_WAKE_UP_READY_INT = 0x020,
> + TPM_INTF_LOCTPM_BUFSIZE4SOFTRELEASE_INT = 0x008,
> + TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
> + TPM_INTF_STS_VALID_INT = 0x002,
> + TPM_INTF_DATA_AVAIL_INT = 0x001,
> +};
> +
> +enum tis_defaults {
> + TIS_SHORT_TIMEOUT_MS = 750, /* ms */
> + TIS_LONG_TIMEOUT_MS = 2000, /* 2 sec */
> +};
> +
> +/**
> + * @addr: TPM I2C address
> + * @i2c_bus: I2C bus ID the TPM is connected to
> + * @is_open: TPM connection establishment information
> + * @locality: active locality of the TPM (0 OR 4)
> + * @buf: command/response buffer
> + * @timeout_*: timeouts for TPM states changes
> + * @duration: maximum time for a TPM command processing
> + */
> +struct tpm_chip {
> + uint addr;
> + uint i2c_bus;
> + int is_open;
> + u8 buf[TPM_BUFSIZE];
> + int locality;
> + unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
> + unsigned long duration; /* msec */
> +};
> +
> +static struct tpm_chip tpm_dev;
> +
> +/*
> + * write8_reg(): Send byte to the TIS register according to I2C TPM protocol.
> + * @tpm_register, the tpm tis register where the data should be written
> + * @tpm_data, the tpm_data to write inside the tpm_register
> + * @tpm_size, The length of the data
> + * @return: Returns zero in case of success else the negative error code.
> + */
> +static int write8_reg(u8 addr, u8 tpm_register,
> + const u8 *tpm_data, u16 tpm_size)
> +{
> + u8 data;
> +
> + data = tpm_register;
> + memcpy(&(tpm_dev.buf[0]), &data, sizeof(data));
> + memcpy(&(tpm_dev.buf[0])+1, tpm_data, tpm_size);
> + return i2c_write(addr, 0, 0, &tpm_dev.buf[0], tpm_size + 1);
> +}
I'm wondering whether the I2C/SPI size should go in a separate
lower-level routine which understands how to communicate with either?
What do you think? Or perhaps that will just make things complicated?
Regards,
Simonn
More information about the U-Boot
mailing list