1b75fdc11SChristophe Ricard /* 2b75fdc11SChristophe Ricard * STMicroelectronics TPM ST33ZP24 SPI UBOOT driver 3b75fdc11SChristophe Ricard * 4*05cd1194SPatrice Chotard * Copyright (C) 2016, STMicroelectronics - All Rights Reserved 5*05cd1194SPatrice Chotard * Author(s): Christophe Ricard <christophe-h.ricard@st.com> for STMicroelectronics. 6b75fdc11SChristophe Ricard * 7b75fdc11SChristophe Ricard * Description: Device driver for ST33ZP24 SPI TPM TCG. 8b75fdc11SChristophe Ricard * 9b75fdc11SChristophe Ricard * This device driver implements the TPM interface as defined in 10b75fdc11SChristophe Ricard * the TCG TPM Interface Spec version 1.21, revision 1.0 and the 11b75fdc11SChristophe Ricard * STMicroelectronics Protocol Stack Specification version 1.2.0. 12b75fdc11SChristophe Ricard * 13b75fdc11SChristophe Ricard * SPDX-License-Identifier: GPL-2.0+ 14b75fdc11SChristophe Ricard */ 15b75fdc11SChristophe Ricard 16b75fdc11SChristophe Ricard #include <common.h> 17b75fdc11SChristophe Ricard #include <dm.h> 18b75fdc11SChristophe Ricard #include <fdtdec.h> 19b75fdc11SChristophe Ricard #include <spi.h> 20b75fdc11SChristophe Ricard #include <tpm.h> 21b75fdc11SChristophe Ricard #include <errno.h> 22b75fdc11SChristophe Ricard #include <linux/types.h> 23b75fdc11SChristophe Ricard #include <asm/unaligned.h> 24b75fdc11SChristophe Ricard #include <linux/compat.h> 25b75fdc11SChristophe Ricard 26b75fdc11SChristophe Ricard #include "tpm_tis.h" 27b75fdc11SChristophe Ricard #include "tpm_internal.h" 28b75fdc11SChristophe Ricard 29b75fdc11SChristophe Ricard #define TPM_ACCESS 0x0 30b75fdc11SChristophe Ricard #define TPM_STS 0x18 31b75fdc11SChristophe Ricard #define TPM_DATA_FIFO 0x24 32b75fdc11SChristophe Ricard 33b75fdc11SChristophe Ricard #define LOCALITY0 0 34b75fdc11SChristophe Ricard 35b75fdc11SChristophe Ricard #define TPM_DATA_FIFO 0x24 36b75fdc11SChristophe Ricard #define TPM_INTF_CAPABILITY 0x14 37b75fdc11SChristophe Ricard 38b75fdc11SChristophe Ricard #define TPM_DUMMY_BYTE 0x00 39b75fdc11SChristophe Ricard #define TPM_WRITE_DIRECTION 0x80 40b75fdc11SChristophe Ricard 41b75fdc11SChristophe Ricard #define MAX_SPI_LATENCY 15 42b75fdc11SChristophe Ricard #define LOCALITY0 0 43b75fdc11SChristophe Ricard 44b75fdc11SChristophe Ricard #define ST33ZP24_OK 0x5A 45b75fdc11SChristophe Ricard #define ST33ZP24_UNDEFINED_ERR 0x80 46b75fdc11SChristophe Ricard #define ST33ZP24_BADLOCALITY 0x81 47b75fdc11SChristophe Ricard #define ST33ZP24_TISREGISTER_UKNOWN 0x82 48b75fdc11SChristophe Ricard #define ST33ZP24_LOCALITY_NOT_ACTIVATED 0x83 49b75fdc11SChristophe Ricard #define ST33ZP24_HASH_END_BEFORE_HASH_START 0x84 50b75fdc11SChristophe Ricard #define ST33ZP24_BAD_COMMAND_ORDER 0x85 51b75fdc11SChristophe Ricard #define ST33ZP24_INCORECT_RECEIVED_LENGTH 0x86 52b75fdc11SChristophe Ricard #define ST33ZP24_TPM_FIFO_OVERFLOW 0x89 53b75fdc11SChristophe Ricard #define ST33ZP24_UNEXPECTED_READ_FIFO 0x8A 54b75fdc11SChristophe Ricard #define ST33ZP24_UNEXPECTED_WRITE_FIFO 0x8B 55b75fdc11SChristophe Ricard #define ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END 0x90 56b75fdc11SChristophe Ricard #define ST33ZP24_DUMMY_BYTES 0x00 57b75fdc11SChristophe Ricard 58b75fdc11SChristophe Ricard /* 59b75fdc11SChristophe Ricard * TPM command can be up to 2048 byte, A TPM response can be up to 60b75fdc11SChristophe Ricard * 1024 byte. 61b75fdc11SChristophe Ricard * Between command and response, there are latency byte (up to 15 62b75fdc11SChristophe Ricard * usually on st33zp24 2 are enough). 63b75fdc11SChristophe Ricard * 64b75fdc11SChristophe Ricard * Overall when sending a command and expecting an answer we need if 65b75fdc11SChristophe Ricard * worst case: 66b75fdc11SChristophe Ricard * 2048 (for the TPM command) + 1024 (for the TPM answer). We need 67b75fdc11SChristophe Ricard * some latency byte before the answer is available (max 15). 68b75fdc11SChristophe Ricard * We have 2048 + 1024 + 15. 69b75fdc11SChristophe Ricard */ 70b75fdc11SChristophe Ricard #define ST33ZP24_SPI_BUFFER_SIZE (TPM_BUFSIZE + (TPM_BUFSIZE / 2) +\ 71b75fdc11SChristophe Ricard MAX_SPI_LATENCY) 72b75fdc11SChristophe Ricard 73b75fdc11SChristophe Ricard struct st33zp24_spi_phy { 74b75fdc11SChristophe Ricard int latency; 75b75fdc11SChristophe Ricard 76b75fdc11SChristophe Ricard u8 tx_buf[ST33ZP24_SPI_BUFFER_SIZE]; 77b75fdc11SChristophe Ricard u8 rx_buf[ST33ZP24_SPI_BUFFER_SIZE]; 78b75fdc11SChristophe Ricard }; 79b75fdc11SChristophe Ricard 80b75fdc11SChristophe Ricard static int st33zp24_spi_status_to_errno(u8 code) 81b75fdc11SChristophe Ricard { 82b75fdc11SChristophe Ricard switch (code) { 83b75fdc11SChristophe Ricard case ST33ZP24_OK: 84b75fdc11SChristophe Ricard return 0; 85b75fdc11SChristophe Ricard case ST33ZP24_UNDEFINED_ERR: 86b75fdc11SChristophe Ricard case ST33ZP24_BADLOCALITY: 87b75fdc11SChristophe Ricard case ST33ZP24_TISREGISTER_UKNOWN: 88b75fdc11SChristophe Ricard case ST33ZP24_LOCALITY_NOT_ACTIVATED: 89b75fdc11SChristophe Ricard case ST33ZP24_HASH_END_BEFORE_HASH_START: 90b75fdc11SChristophe Ricard case ST33ZP24_BAD_COMMAND_ORDER: 91b75fdc11SChristophe Ricard case ST33ZP24_UNEXPECTED_READ_FIFO: 92b75fdc11SChristophe Ricard case ST33ZP24_UNEXPECTED_WRITE_FIFO: 93b75fdc11SChristophe Ricard case ST33ZP24_CMDRDY_SET_WHEN_PROCESSING_HASH_END: 94b75fdc11SChristophe Ricard return -EPROTO; 95b75fdc11SChristophe Ricard case ST33ZP24_INCORECT_RECEIVED_LENGTH: 96b75fdc11SChristophe Ricard case ST33ZP24_TPM_FIFO_OVERFLOW: 97b75fdc11SChristophe Ricard return -EMSGSIZE; 98b75fdc11SChristophe Ricard case ST33ZP24_DUMMY_BYTES: 99b75fdc11SChristophe Ricard return -ENOSYS; 100b75fdc11SChristophe Ricard } 101b75fdc11SChristophe Ricard return code; 102b75fdc11SChristophe Ricard } 103b75fdc11SChristophe Ricard 104b75fdc11SChristophe Ricard /* 105b75fdc11SChristophe Ricard * st33zp24_spi_send 106b75fdc11SChristophe Ricard * Send byte to TPM register according to the ST33ZP24 SPI protocol. 107b75fdc11SChristophe Ricard * @param: tpm, the chip description 108b75fdc11SChristophe Ricard * @param: tpm_register, the tpm tis register where the data should be written 109b75fdc11SChristophe Ricard * @param: tpm_data, the tpm_data to write inside the tpm_register 110b75fdc11SChristophe Ricard * @param: tpm_size, The length of the data 111b75fdc11SChristophe Ricard * @return: should be zero if success else a negative error code. 112b75fdc11SChristophe Ricard */ 113b75fdc11SChristophe Ricard static int st33zp24_spi_write(struct udevice *dev, u8 tpm_register, 114b75fdc11SChristophe Ricard const u8 *tpm_data, size_t tpm_size) 115b75fdc11SChristophe Ricard { 116b75fdc11SChristophe Ricard int total_length = 0, ret; 117b75fdc11SChristophe Ricard struct spi_slave *slave = dev_get_parent_priv(dev); 118b75fdc11SChristophe Ricard struct st33zp24_spi_phy *phy = dev_get_platdata(dev); 119b75fdc11SChristophe Ricard 120b75fdc11SChristophe Ricard u8 *tx_buf = (u8 *)phy->tx_buf; 121b75fdc11SChristophe Ricard u8 *rx_buf = phy->rx_buf; 122b75fdc11SChristophe Ricard 123b75fdc11SChristophe Ricard tx_buf[total_length++] = TPM_WRITE_DIRECTION | LOCALITY0; 124b75fdc11SChristophe Ricard tx_buf[total_length++] = tpm_register; 125b75fdc11SChristophe Ricard 126b75fdc11SChristophe Ricard if (tpm_size > 0 && tpm_register == TPM_DATA_FIFO) { 127b75fdc11SChristophe Ricard tx_buf[total_length++] = tpm_size >> 8; 128b75fdc11SChristophe Ricard tx_buf[total_length++] = tpm_size; 129b75fdc11SChristophe Ricard } 130b75fdc11SChristophe Ricard memcpy(tx_buf + total_length, tpm_data, tpm_size); 131b75fdc11SChristophe Ricard total_length += tpm_size; 132b75fdc11SChristophe Ricard 133b75fdc11SChristophe Ricard memset(tx_buf + total_length, TPM_DUMMY_BYTE, phy->latency); 134b75fdc11SChristophe Ricard 135b75fdc11SChristophe Ricard total_length += phy->latency; 136b75fdc11SChristophe Ricard 137b75fdc11SChristophe Ricard ret = spi_claim_bus(slave); 138b75fdc11SChristophe Ricard if (ret < 0) 139b75fdc11SChristophe Ricard return ret; 140b75fdc11SChristophe Ricard 141b75fdc11SChristophe Ricard ret = spi_xfer(slave, total_length * 8, tx_buf, rx_buf, 142b75fdc11SChristophe Ricard SPI_XFER_BEGIN | SPI_XFER_END); 143b75fdc11SChristophe Ricard if (ret < 0) 144b75fdc11SChristophe Ricard return ret; 145b75fdc11SChristophe Ricard 146b75fdc11SChristophe Ricard spi_release_bus(slave); 147b75fdc11SChristophe Ricard 148b75fdc11SChristophe Ricard if (ret == 0) 149b75fdc11SChristophe Ricard ret = rx_buf[total_length - 1]; 150b75fdc11SChristophe Ricard 151b75fdc11SChristophe Ricard return st33zp24_spi_status_to_errno(ret); 152b75fdc11SChristophe Ricard } 153b75fdc11SChristophe Ricard 154b75fdc11SChristophe Ricard /* 155b75fdc11SChristophe Ricard * spi_st33zp24_spi_read8_reg 156b75fdc11SChristophe Ricard * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. 157b75fdc11SChristophe Ricard * @param: tpm, the chip description 158b75fdc11SChristophe Ricard * @param: tpm_loc, the locality to read register from 159b75fdc11SChristophe Ricard * @param: tpm_register, the tpm tis register where the data should be read 160b75fdc11SChristophe Ricard * @param: tpm_data, the TPM response 161b75fdc11SChristophe Ricard * @param: tpm_size, tpm TPM response size to read. 162b75fdc11SChristophe Ricard * @return: should be zero if success else a negative error code. 163b75fdc11SChristophe Ricard */ 164b75fdc11SChristophe Ricard static u8 st33zp24_spi_read8_reg(struct udevice *dev, u8 tpm_register, 165b75fdc11SChristophe Ricard u8 *tpm_data, size_t tpm_size) 166b75fdc11SChristophe Ricard { 167b75fdc11SChristophe Ricard int total_length = 0, ret; 168b75fdc11SChristophe Ricard struct spi_slave *slave = dev_get_parent_priv(dev); 169b75fdc11SChristophe Ricard struct st33zp24_spi_phy *phy = dev_get_platdata(dev); 170b75fdc11SChristophe Ricard 171b75fdc11SChristophe Ricard u8 *tx_buf = (u8 *)phy->tx_buf; 172b75fdc11SChristophe Ricard u8 *rx_buf = phy->rx_buf; 173b75fdc11SChristophe Ricard 174b75fdc11SChristophe Ricard /* Pre-Header */ 175b75fdc11SChristophe Ricard tx_buf[total_length++] = LOCALITY0; 176b75fdc11SChristophe Ricard tx_buf[total_length++] = tpm_register; 177b75fdc11SChristophe Ricard 178b75fdc11SChristophe Ricard memset(&tx_buf[total_length], TPM_DUMMY_BYTE, 179b75fdc11SChristophe Ricard phy->latency + tpm_size); 180b75fdc11SChristophe Ricard total_length += phy->latency + tpm_size; 181b75fdc11SChristophe Ricard 182b75fdc11SChristophe Ricard ret = spi_claim_bus(slave); 183b75fdc11SChristophe Ricard if (ret < 0) 184b75fdc11SChristophe Ricard return 0; 185b75fdc11SChristophe Ricard 186b75fdc11SChristophe Ricard ret = spi_xfer(slave, total_length * 8, tx_buf, rx_buf, 187b75fdc11SChristophe Ricard SPI_XFER_BEGIN | SPI_XFER_END); 188b75fdc11SChristophe Ricard if (ret < 0) 189b75fdc11SChristophe Ricard return 0; 190b75fdc11SChristophe Ricard 191b75fdc11SChristophe Ricard spi_release_bus(slave); 192b75fdc11SChristophe Ricard 193b75fdc11SChristophe Ricard if (tpm_size > 0 && ret == 0) { 194b75fdc11SChristophe Ricard ret = rx_buf[total_length - tpm_size - 1]; 195b75fdc11SChristophe Ricard memcpy(tpm_data, rx_buf + total_length - tpm_size, tpm_size); 196b75fdc11SChristophe Ricard } 197b75fdc11SChristophe Ricard return ret; 198b75fdc11SChristophe Ricard } 199b75fdc11SChristophe Ricard 200b75fdc11SChristophe Ricard /* 201b75fdc11SChristophe Ricard * st33zp24_spi_recv 202b75fdc11SChristophe Ricard * Recv byte from the TIS register according to the ST33ZP24 SPI protocol. 203b75fdc11SChristophe Ricard * @param: phy_id, the phy description 204b75fdc11SChristophe Ricard * @param: tpm_register, the tpm tis register where the data should be read 205b75fdc11SChristophe Ricard * @param: tpm_data, the TPM response 206b75fdc11SChristophe Ricard * @param: tpm_size, tpm TPM response size to read. 207b75fdc11SChristophe Ricard * @return: number of byte read successfully: should be one if success. 208b75fdc11SChristophe Ricard */ 209b75fdc11SChristophe Ricard static int st33zp24_spi_read(struct udevice *dev, u8 tpm_register, 210b75fdc11SChristophe Ricard u8 *tpm_data, size_t tpm_size) 211b75fdc11SChristophe Ricard { 212b75fdc11SChristophe Ricard int ret; 213b75fdc11SChristophe Ricard 214b75fdc11SChristophe Ricard ret = st33zp24_spi_read8_reg(dev, tpm_register, tpm_data, tpm_size); 215b75fdc11SChristophe Ricard if (!st33zp24_spi_status_to_errno(ret)) 216b75fdc11SChristophe Ricard return tpm_size; 217b75fdc11SChristophe Ricard 218b75fdc11SChristophe Ricard return ret; 219b75fdc11SChristophe Ricard } 220b75fdc11SChristophe Ricard 221b75fdc11SChristophe Ricard static int st33zp24_spi_evaluate_latency(struct udevice *dev) 222b75fdc11SChristophe Ricard { 223b75fdc11SChristophe Ricard int latency = 1, status = 0; 224b75fdc11SChristophe Ricard u8 data = 0; 225b75fdc11SChristophe Ricard struct st33zp24_spi_phy *phy = dev_get_platdata(dev); 226b75fdc11SChristophe Ricard 227b75fdc11SChristophe Ricard while (!status && latency < MAX_SPI_LATENCY) { 228b75fdc11SChristophe Ricard phy->latency = latency; 229b75fdc11SChristophe Ricard status = st33zp24_spi_read8_reg(dev, TPM_INTF_CAPABILITY, 230b75fdc11SChristophe Ricard &data, 1); 231b75fdc11SChristophe Ricard latency++; 232b75fdc11SChristophe Ricard } 233b75fdc11SChristophe Ricard if (status < 0) 234b75fdc11SChristophe Ricard return status; 235b75fdc11SChristophe Ricard if (latency == MAX_SPI_LATENCY) 236b75fdc11SChristophe Ricard return -ENODEV; 237b75fdc11SChristophe Ricard 238b75fdc11SChristophe Ricard return latency - 1; 239b75fdc11SChristophe Ricard } 240b75fdc11SChristophe Ricard 241b75fdc11SChristophe Ricard /* 242b75fdc11SChristophe Ricard * st33zp24_spi_release_locality release the active locality 243b75fdc11SChristophe Ricard * @param: chip, the tpm chip description. 244b75fdc11SChristophe Ricard */ 245b75fdc11SChristophe Ricard static void st33zp24_spi_release_locality(struct udevice *dev) 246b75fdc11SChristophe Ricard { 247b75fdc11SChristophe Ricard u8 data = TPM_ACCESS_ACTIVE_LOCALITY; 248b75fdc11SChristophe Ricard 249b75fdc11SChristophe Ricard st33zp24_spi_write(dev, TPM_ACCESS, &data, 1); 250b75fdc11SChristophe Ricard } 251b75fdc11SChristophe Ricard 252b75fdc11SChristophe Ricard /* 253b75fdc11SChristophe Ricard * st33zp24_spi_check_locality if the locality is active 254b75fdc11SChristophe Ricard * @param: chip, the tpm chip description 255b75fdc11SChristophe Ricard * @return: the active locality or -EACCES. 256b75fdc11SChristophe Ricard */ 257b75fdc11SChristophe Ricard static int st33zp24_spi_check_locality(struct udevice *dev) 258b75fdc11SChristophe Ricard { 259b75fdc11SChristophe Ricard u8 data; 260b75fdc11SChristophe Ricard u8 status; 261b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 262b75fdc11SChristophe Ricard 263b75fdc11SChristophe Ricard status = st33zp24_spi_read(dev, TPM_ACCESS, &data, 1); 264b75fdc11SChristophe Ricard if (status && (data & 265b75fdc11SChristophe Ricard (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == 266b75fdc11SChristophe Ricard (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) 267b75fdc11SChristophe Ricard return chip->locality; 268b75fdc11SChristophe Ricard 269b75fdc11SChristophe Ricard return -EACCES; 270b75fdc11SChristophe Ricard } 271b75fdc11SChristophe Ricard 272b75fdc11SChristophe Ricard /* 273b75fdc11SChristophe Ricard * st33zp24_spi_request_locality request the TPM locality 274b75fdc11SChristophe Ricard * @param: chip, the chip description 275b75fdc11SChristophe Ricard * @return: the active locality or negative value. 276b75fdc11SChristophe Ricard */ 277b75fdc11SChristophe Ricard static int st33zp24_spi_request_locality(struct udevice *dev) 278b75fdc11SChristophe Ricard { 279b75fdc11SChristophe Ricard unsigned long start, stop; 280b75fdc11SChristophe Ricard long ret; 281b75fdc11SChristophe Ricard u8 data; 282b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 283b75fdc11SChristophe Ricard 284b75fdc11SChristophe Ricard if (st33zp24_spi_check_locality(dev) == chip->locality) 285b75fdc11SChristophe Ricard return chip->locality; 286b75fdc11SChristophe Ricard 287b75fdc11SChristophe Ricard data = TPM_ACCESS_REQUEST_USE; 288b75fdc11SChristophe Ricard ret = st33zp24_spi_write(dev, TPM_ACCESS, &data, 1); 289b75fdc11SChristophe Ricard if (ret < 0) 290b75fdc11SChristophe Ricard return ret; 291b75fdc11SChristophe Ricard 292b75fdc11SChristophe Ricard /* wait for locality activated */ 293b75fdc11SChristophe Ricard start = get_timer(0); 294b75fdc11SChristophe Ricard stop = chip->timeout_a; 295b75fdc11SChristophe Ricard do { 296b75fdc11SChristophe Ricard if (st33zp24_spi_check_locality(dev) >= 0) 297b75fdc11SChristophe Ricard return chip->locality; 298b75fdc11SChristophe Ricard udelay(TPM_TIMEOUT_MS * 1000); 299b75fdc11SChristophe Ricard } while (get_timer(start) < stop); 300b75fdc11SChristophe Ricard 301b75fdc11SChristophe Ricard return -EACCES; 302b75fdc11SChristophe Ricard } 303b75fdc11SChristophe Ricard 304b75fdc11SChristophe Ricard /* 305b75fdc11SChristophe Ricard * st33zp24_spi_status return the TPM_STS register 306b75fdc11SChristophe Ricard * @param: chip, the tpm chip description 307b75fdc11SChristophe Ricard * @return: the TPM_STS register value. 308b75fdc11SChristophe Ricard */ 309b75fdc11SChristophe Ricard static u8 st33zp24_spi_status(struct udevice *dev) 310b75fdc11SChristophe Ricard { 311b75fdc11SChristophe Ricard u8 data; 312b75fdc11SChristophe Ricard 313b75fdc11SChristophe Ricard st33zp24_spi_read(dev, TPM_STS, &data, 1); 314b75fdc11SChristophe Ricard return data; 315b75fdc11SChristophe Ricard } 316b75fdc11SChristophe Ricard 317b75fdc11SChristophe Ricard /* 318b75fdc11SChristophe Ricard * st33zp24_spi_get_burstcount return the burstcount address 0x19 0x1A 319b75fdc11SChristophe Ricard * @param: chip, the chip description 320b75fdc11SChristophe Ricard * return: the burstcount or -TPM_DRIVER_ERR in case of error. 321b75fdc11SChristophe Ricard */ 322b75fdc11SChristophe Ricard static int st33zp24_spi_get_burstcount(struct udevice *dev) 323b75fdc11SChristophe Ricard { 324b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 325b75fdc11SChristophe Ricard unsigned long start, stop; 326b75fdc11SChristophe Ricard int burstcnt, status; 327b75fdc11SChristophe Ricard u8 tpm_reg, temp; 328b75fdc11SChristophe Ricard 329b75fdc11SChristophe Ricard /* wait for burstcount */ 330b75fdc11SChristophe Ricard start = get_timer(0); 331b75fdc11SChristophe Ricard stop = chip->timeout_d; 332b75fdc11SChristophe Ricard do { 333b75fdc11SChristophe Ricard tpm_reg = TPM_STS + 1; 334b75fdc11SChristophe Ricard status = st33zp24_spi_read(dev, tpm_reg, &temp, 1); 335b75fdc11SChristophe Ricard if (status < 0) 336b75fdc11SChristophe Ricard return -EBUSY; 337b75fdc11SChristophe Ricard 338b75fdc11SChristophe Ricard tpm_reg = TPM_STS + 2; 339b75fdc11SChristophe Ricard burstcnt = temp; 340b75fdc11SChristophe Ricard status = st33zp24_spi_read(dev, tpm_reg, &temp, 1); 341b75fdc11SChristophe Ricard if (status < 0) 342b75fdc11SChristophe Ricard return -EBUSY; 343b75fdc11SChristophe Ricard 344b75fdc11SChristophe Ricard burstcnt |= temp << 8; 345b75fdc11SChristophe Ricard if (burstcnt) 346b75fdc11SChristophe Ricard return burstcnt; 347b75fdc11SChristophe Ricard udelay(TIS_SHORT_TIMEOUT_MS * 1000); 348b75fdc11SChristophe Ricard } while (get_timer(start) < stop); 349b75fdc11SChristophe Ricard 350b75fdc11SChristophe Ricard return -EBUSY; 351b75fdc11SChristophe Ricard } 352b75fdc11SChristophe Ricard 353b75fdc11SChristophe Ricard /* 354b75fdc11SChristophe Ricard * st33zp24_spi_cancel, cancel the current command execution or 355b75fdc11SChristophe Ricard * set STS to COMMAND READY. 356b75fdc11SChristophe Ricard * @param: chip, tpm_chip description. 357b75fdc11SChristophe Ricard */ 358b75fdc11SChristophe Ricard static void st33zp24_spi_cancel(struct udevice *dev) 359b75fdc11SChristophe Ricard { 360b75fdc11SChristophe Ricard u8 data; 361b75fdc11SChristophe Ricard 362b75fdc11SChristophe Ricard data = TPM_STS_COMMAND_READY; 363b75fdc11SChristophe Ricard st33zp24_spi_write(dev, TPM_STS, &data, 1); 364b75fdc11SChristophe Ricard } 365b75fdc11SChristophe Ricard 366b75fdc11SChristophe Ricard /* 367b75fdc11SChristophe Ricard * st33zp24_spi_wait_for_stat wait for a TPM_STS value 368b75fdc11SChristophe Ricard * @param: chip, the tpm chip description 369b75fdc11SChristophe Ricard * @param: mask, the value mask to wait 370b75fdc11SChristophe Ricard * @param: timeout, the timeout 371b75fdc11SChristophe Ricard * @param: status, 372b75fdc11SChristophe Ricard * @return: the tpm status, 0 if success, -ETIME if timeout is reached. 373b75fdc11SChristophe Ricard */ 374b75fdc11SChristophe Ricard static int st33zp24_spi_wait_for_stat(struct udevice *dev, u8 mask, 375b75fdc11SChristophe Ricard unsigned long timeout, int *status) 376b75fdc11SChristophe Ricard { 377b75fdc11SChristophe Ricard unsigned long start, stop; 378b75fdc11SChristophe Ricard 379b75fdc11SChristophe Ricard /* Check current status */ 380b75fdc11SChristophe Ricard *status = st33zp24_spi_status(dev); 381b75fdc11SChristophe Ricard if ((*status & mask) == mask) 382b75fdc11SChristophe Ricard return 0; 383b75fdc11SChristophe Ricard 384b75fdc11SChristophe Ricard start = get_timer(0); 385b75fdc11SChristophe Ricard stop = timeout; 386b75fdc11SChristophe Ricard do { 387b75fdc11SChristophe Ricard udelay(TPM_TIMEOUT_MS * 1000); 388b75fdc11SChristophe Ricard *status = st33zp24_spi_status(dev); 389b75fdc11SChristophe Ricard if ((*status & mask) == mask) 390b75fdc11SChristophe Ricard return 0; 391b75fdc11SChristophe Ricard } while (get_timer(start) < stop); 392b75fdc11SChristophe Ricard 393b75fdc11SChristophe Ricard return -ETIME; 394b75fdc11SChristophe Ricard } 395b75fdc11SChristophe Ricard 396b75fdc11SChristophe Ricard /* 397b75fdc11SChristophe Ricard * st33zp24_spi_recv_data receive data 398b75fdc11SChristophe Ricard * @param: chip, the tpm chip description 399b75fdc11SChristophe Ricard * @param: buf, the buffer where the data are received 400b75fdc11SChristophe Ricard * @param: count, the number of data to receive 401b75fdc11SChristophe Ricard * @return: the number of bytes read from TPM FIFO. 402b75fdc11SChristophe Ricard */ 403b75fdc11SChristophe Ricard static int st33zp24_spi_recv_data(struct udevice *dev, u8 *buf, size_t count) 404b75fdc11SChristophe Ricard { 405b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 406b75fdc11SChristophe Ricard int size = 0, burstcnt, len, ret, status; 407b75fdc11SChristophe Ricard 408b75fdc11SChristophe Ricard while (size < count && 409b75fdc11SChristophe Ricard st33zp24_spi_wait_for_stat(dev, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 410b75fdc11SChristophe Ricard chip->timeout_c, &status) == 0) { 411b75fdc11SChristophe Ricard burstcnt = st33zp24_spi_get_burstcount(dev); 412b75fdc11SChristophe Ricard if (burstcnt < 0) 413b75fdc11SChristophe Ricard return burstcnt; 414b75fdc11SChristophe Ricard len = min_t(int, burstcnt, count - size); 415b75fdc11SChristophe Ricard ret = st33zp24_spi_read(dev, TPM_DATA_FIFO, buf + size, len); 416b75fdc11SChristophe Ricard if (ret < 0) 417b75fdc11SChristophe Ricard return ret; 418b75fdc11SChristophe Ricard 419b75fdc11SChristophe Ricard size += len; 420b75fdc11SChristophe Ricard } 421b75fdc11SChristophe Ricard return size; 422b75fdc11SChristophe Ricard } 423b75fdc11SChristophe Ricard 424b75fdc11SChristophe Ricard /* 425b75fdc11SChristophe Ricard * st33zp24_spi_recv received TPM response through TPM phy. 426b75fdc11SChristophe Ricard * @param: chip, tpm_chip description. 427b75fdc11SChristophe Ricard * @param: buf, the buffer to store data. 428b75fdc11SChristophe Ricard * @param: count, the number of bytes that can received (sizeof buf). 429b75fdc11SChristophe Ricard * @return: Returns zero in case of success else -EIO. 430b75fdc11SChristophe Ricard */ 431b75fdc11SChristophe Ricard static int st33zp24_spi_recv(struct udevice *dev, u8 *buf, size_t count) 432b75fdc11SChristophe Ricard { 433b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 434b75fdc11SChristophe Ricard int size, expected; 435b75fdc11SChristophe Ricard 436b75fdc11SChristophe Ricard if (!chip) 437b75fdc11SChristophe Ricard return -ENODEV; 438b75fdc11SChristophe Ricard 439b75fdc11SChristophe Ricard if (count < TPM_HEADER_SIZE) { 440b75fdc11SChristophe Ricard size = -EIO; 441b75fdc11SChristophe Ricard goto out; 442b75fdc11SChristophe Ricard } 443b75fdc11SChristophe Ricard 444b75fdc11SChristophe Ricard size = st33zp24_spi_recv_data(dev, buf, TPM_HEADER_SIZE); 445b75fdc11SChristophe Ricard if (size < TPM_HEADER_SIZE) { 446b75fdc11SChristophe Ricard debug("TPM error, unable to read header\n"); 447b75fdc11SChristophe Ricard goto out; 448b75fdc11SChristophe Ricard } 449b75fdc11SChristophe Ricard 450b75fdc11SChristophe Ricard expected = get_unaligned_be32(buf + 2); 451b75fdc11SChristophe Ricard if (expected > count) { 452b75fdc11SChristophe Ricard size = -EIO; 453b75fdc11SChristophe Ricard goto out; 454b75fdc11SChristophe Ricard } 455b75fdc11SChristophe Ricard 456b75fdc11SChristophe Ricard size += st33zp24_spi_recv_data(dev, &buf[TPM_HEADER_SIZE], 457b75fdc11SChristophe Ricard expected - TPM_HEADER_SIZE); 458b75fdc11SChristophe Ricard if (size < expected) { 459b75fdc11SChristophe Ricard debug("TPM error, unable to read remaining bytes of result\n"); 460b75fdc11SChristophe Ricard size = -EIO; 461b75fdc11SChristophe Ricard goto out; 462b75fdc11SChristophe Ricard } 463b75fdc11SChristophe Ricard 464b75fdc11SChristophe Ricard out: 465b75fdc11SChristophe Ricard st33zp24_spi_cancel(dev); 466b75fdc11SChristophe Ricard st33zp24_spi_release_locality(dev); 467b75fdc11SChristophe Ricard 468b75fdc11SChristophe Ricard return size; 469b75fdc11SChristophe Ricard } 470b75fdc11SChristophe Ricard 471b75fdc11SChristophe Ricard /* 472b75fdc11SChristophe Ricard * st33zp24_spi_send send TPM commands through TPM phy. 473b75fdc11SChristophe Ricard * @param: chip, tpm_chip description. 474b75fdc11SChristophe Ricard * @param: buf, the buffer to send. 475b75fdc11SChristophe Ricard * @param: len, the number of bytes to send. 476b75fdc11SChristophe Ricard * @return: Returns zero in case of success else the negative error code. 477b75fdc11SChristophe Ricard */ 478b75fdc11SChristophe Ricard static int st33zp24_spi_send(struct udevice *dev, const u8 *buf, size_t len) 479b75fdc11SChristophe Ricard { 480b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 481b75fdc11SChristophe Ricard u32 i, size; 482b75fdc11SChristophe Ricard int burstcnt, ret, status; 483b75fdc11SChristophe Ricard u8 data, tpm_stat; 484b75fdc11SChristophe Ricard 485b75fdc11SChristophe Ricard if (!chip) 486b75fdc11SChristophe Ricard return -ENODEV; 487b75fdc11SChristophe Ricard if (len < TPM_HEADER_SIZE) 488b75fdc11SChristophe Ricard return -EIO; 489b75fdc11SChristophe Ricard 490b75fdc11SChristophe Ricard ret = st33zp24_spi_request_locality(dev); 491b75fdc11SChristophe Ricard if (ret < 0) 492b75fdc11SChristophe Ricard return ret; 493b75fdc11SChristophe Ricard 494b75fdc11SChristophe Ricard tpm_stat = st33zp24_spi_status(dev); 495b75fdc11SChristophe Ricard if ((tpm_stat & TPM_STS_COMMAND_READY) == 0) { 496b75fdc11SChristophe Ricard st33zp24_spi_cancel(dev); 497b75fdc11SChristophe Ricard if (st33zp24_spi_wait_for_stat(dev, TPM_STS_COMMAND_READY, 498b75fdc11SChristophe Ricard chip->timeout_b, &status) < 0) { 499b75fdc11SChristophe Ricard ret = -ETIME; 500b75fdc11SChristophe Ricard goto out_err; 501b75fdc11SChristophe Ricard } 502b75fdc11SChristophe Ricard } 503b75fdc11SChristophe Ricard 504b75fdc11SChristophe Ricard for (i = 0; i < len - 1;) { 505b75fdc11SChristophe Ricard burstcnt = st33zp24_spi_get_burstcount(dev); 506b75fdc11SChristophe Ricard if (burstcnt < 0) 507b75fdc11SChristophe Ricard return burstcnt; 508b75fdc11SChristophe Ricard 509b75fdc11SChristophe Ricard size = min_t(int, len - i - 1, burstcnt); 510b75fdc11SChristophe Ricard ret = st33zp24_spi_write(dev, TPM_DATA_FIFO, buf + i, size); 511b75fdc11SChristophe Ricard if (ret < 0) 512b75fdc11SChristophe Ricard goto out_err; 513b75fdc11SChristophe Ricard 514b75fdc11SChristophe Ricard i += size; 515b75fdc11SChristophe Ricard } 516b75fdc11SChristophe Ricard 517b75fdc11SChristophe Ricard tpm_stat = st33zp24_spi_status(dev); 518b75fdc11SChristophe Ricard if ((tpm_stat & TPM_STS_DATA_EXPECT) == 0) { 519b75fdc11SChristophe Ricard ret = -EIO; 520b75fdc11SChristophe Ricard goto out_err; 521b75fdc11SChristophe Ricard } 522b75fdc11SChristophe Ricard 523b75fdc11SChristophe Ricard ret = st33zp24_spi_write(dev, TPM_DATA_FIFO, buf + len - 1, 1); 524b75fdc11SChristophe Ricard if (ret < 0) 525b75fdc11SChristophe Ricard goto out_err; 526b75fdc11SChristophe Ricard 527b75fdc11SChristophe Ricard tpm_stat = st33zp24_spi_status(dev); 528b75fdc11SChristophe Ricard if ((tpm_stat & TPM_STS_DATA_EXPECT) != 0) { 529b75fdc11SChristophe Ricard ret = -EIO; 530b75fdc11SChristophe Ricard goto out_err; 531b75fdc11SChristophe Ricard } 532b75fdc11SChristophe Ricard 533b75fdc11SChristophe Ricard data = TPM_STS_GO; 534b75fdc11SChristophe Ricard ret = st33zp24_spi_write(dev, TPM_STS, &data, 1); 535b75fdc11SChristophe Ricard if (ret < 0) 536b75fdc11SChristophe Ricard goto out_err; 537b75fdc11SChristophe Ricard 538b75fdc11SChristophe Ricard return len; 539b75fdc11SChristophe Ricard 540b75fdc11SChristophe Ricard out_err: 541b75fdc11SChristophe Ricard st33zp24_spi_cancel(dev); 542b75fdc11SChristophe Ricard st33zp24_spi_release_locality(dev); 543b75fdc11SChristophe Ricard 544b75fdc11SChristophe Ricard return ret; 545b75fdc11SChristophe Ricard } 546b75fdc11SChristophe Ricard 547b75fdc11SChristophe Ricard static int st33zp24_spi_cleanup(struct udevice *dev) 548b75fdc11SChristophe Ricard { 549b75fdc11SChristophe Ricard st33zp24_spi_cancel(dev); 550b75fdc11SChristophe Ricard /* 551b75fdc11SChristophe Ricard * The TPM needs some time to clean up here, 552b75fdc11SChristophe Ricard * so we sleep rather than keeping the bus busy 553b75fdc11SChristophe Ricard */ 554b75fdc11SChristophe Ricard mdelay(2); 555b75fdc11SChristophe Ricard st33zp24_spi_release_locality(dev); 556b75fdc11SChristophe Ricard 557b75fdc11SChristophe Ricard return 0; 558b75fdc11SChristophe Ricard } 559b75fdc11SChristophe Ricard 560b75fdc11SChristophe Ricard static int st33zp24_spi_init(struct udevice *dev) 561b75fdc11SChristophe Ricard { 562b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 563b75fdc11SChristophe Ricard struct st33zp24_spi_phy *phy = dev_get_platdata(dev); 564b75fdc11SChristophe Ricard 565b75fdc11SChristophe Ricard chip->is_open = 1; 566b75fdc11SChristophe Ricard 567b75fdc11SChristophe Ricard /* Default timeouts - these could move to the device tree */ 568b75fdc11SChristophe Ricard chip->timeout_a = TIS_SHORT_TIMEOUT_MS; 569b75fdc11SChristophe Ricard chip->timeout_b = TIS_LONG_TIMEOUT_MS; 570b75fdc11SChristophe Ricard chip->timeout_c = TIS_SHORT_TIMEOUT_MS; 571b75fdc11SChristophe Ricard chip->timeout_d = TIS_SHORT_TIMEOUT_MS; 572b75fdc11SChristophe Ricard 573b75fdc11SChristophe Ricard chip->locality = LOCALITY0; 574b75fdc11SChristophe Ricard 575b75fdc11SChristophe Ricard phy->latency = st33zp24_spi_evaluate_latency(dev); 576b75fdc11SChristophe Ricard if (phy->latency <= 0) 577b75fdc11SChristophe Ricard return -ENODEV; 578b75fdc11SChristophe Ricard 579b75fdc11SChristophe Ricard /* 580b75fdc11SChristophe Ricard * A timeout query to TPM can be placed here. 581b75fdc11SChristophe Ricard * Standard timeout values are used so far 582b75fdc11SChristophe Ricard */ 583b75fdc11SChristophe Ricard 584b75fdc11SChristophe Ricard return 0; 585b75fdc11SChristophe Ricard } 586b75fdc11SChristophe Ricard 587b75fdc11SChristophe Ricard static int st33zp24_spi_open(struct udevice *dev) 588b75fdc11SChristophe Ricard { 589b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 590b75fdc11SChristophe Ricard int rc; 591b75fdc11SChristophe Ricard 592b75fdc11SChristophe Ricard debug("%s: start\n", __func__); 593b75fdc11SChristophe Ricard if (chip->is_open) 594b75fdc11SChristophe Ricard return -EBUSY; 595b75fdc11SChristophe Ricard 596b75fdc11SChristophe Ricard rc = st33zp24_spi_init(dev); 597b75fdc11SChristophe Ricard if (rc < 0) 598b75fdc11SChristophe Ricard chip->is_open = 0; 599b75fdc11SChristophe Ricard 600b75fdc11SChristophe Ricard return rc; 601b75fdc11SChristophe Ricard } 602b75fdc11SChristophe Ricard 603b75fdc11SChristophe Ricard static int st33zp24_spi_close(struct udevice *dev) 604b75fdc11SChristophe Ricard { 605b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 606b75fdc11SChristophe Ricard 607b75fdc11SChristophe Ricard if (chip->is_open) { 608b75fdc11SChristophe Ricard st33zp24_spi_release_locality(dev); 609b75fdc11SChristophe Ricard chip->is_open = 0; 610b75fdc11SChristophe Ricard chip->vend_dev = 0; 611b75fdc11SChristophe Ricard } 612b75fdc11SChristophe Ricard 613b75fdc11SChristophe Ricard return 0; 614b75fdc11SChristophe Ricard } 615b75fdc11SChristophe Ricard 616b75fdc11SChristophe Ricard static int st33zp24_spi_get_desc(struct udevice *dev, char *buf, int size) 617b75fdc11SChristophe Ricard { 618b75fdc11SChristophe Ricard struct tpm_chip *chip = dev_get_priv(dev); 619b75fdc11SChristophe Ricard 620b75fdc11SChristophe Ricard if (size < 50) 621b75fdc11SChristophe Ricard return -ENOSPC; 622b75fdc11SChristophe Ricard 623b75fdc11SChristophe Ricard return snprintf(buf, size, "1.2 TPM (%s, chip type %s device-id 0x%x)", 624b75fdc11SChristophe Ricard chip->is_open ? "open" : "closed", 625b75fdc11SChristophe Ricard dev->name, 626b75fdc11SChristophe Ricard chip->vend_dev >> 16); 627b75fdc11SChristophe Ricard } 628b75fdc11SChristophe Ricard 629b75fdc11SChristophe Ricard const struct tpm_ops st33zp24_spi_tpm_ops = { 630b75fdc11SChristophe Ricard .open = st33zp24_spi_open, 631b75fdc11SChristophe Ricard .close = st33zp24_spi_close, 632b75fdc11SChristophe Ricard .recv = st33zp24_spi_recv, 633b75fdc11SChristophe Ricard .send = st33zp24_spi_send, 634b75fdc11SChristophe Ricard .cleanup = st33zp24_spi_cleanup, 635b75fdc11SChristophe Ricard .get_desc = st33zp24_spi_get_desc, 636b75fdc11SChristophe Ricard }; 637b75fdc11SChristophe Ricard 638b75fdc11SChristophe Ricard static int st33zp24_spi_probe(struct udevice *dev) 639b75fdc11SChristophe Ricard { 640b75fdc11SChristophe Ricard struct tpm_chip_priv *uc_priv = dev_get_uclass_priv(dev); 641b75fdc11SChristophe Ricard 642b75fdc11SChristophe Ricard uc_priv->duration_ms[TPM_SHORT] = TIS_SHORT_TIMEOUT_MS; 643b75fdc11SChristophe Ricard uc_priv->duration_ms[TPM_MEDIUM] = TIS_LONG_TIMEOUT_MS; 644b75fdc11SChristophe Ricard uc_priv->duration_ms[TPM_LONG] = TIS_LONG_TIMEOUT_MS; 645b75fdc11SChristophe Ricard uc_priv->retry_time_ms = TPM_TIMEOUT_MS; 646b75fdc11SChristophe Ricard 647b75fdc11SChristophe Ricard debug("ST33ZP24 SPI TPM from STMicroelectronics found\n"); 648b75fdc11SChristophe Ricard 649b75fdc11SChristophe Ricard return 0; 650b75fdc11SChristophe Ricard } 651b75fdc11SChristophe Ricard 652b75fdc11SChristophe Ricard static int st33zp24_spi_remove(struct udevice *dev) 653b75fdc11SChristophe Ricard { 654b75fdc11SChristophe Ricard st33zp24_spi_release_locality(dev); 655b75fdc11SChristophe Ricard 656b75fdc11SChristophe Ricard return 0; 657b75fdc11SChristophe Ricard } 658b75fdc11SChristophe Ricard 659b75fdc11SChristophe Ricard static const struct udevice_id st33zp24_spi_ids[] = { 660b75fdc11SChristophe Ricard { .compatible = "st,st33zp24-spi" }, 661b75fdc11SChristophe Ricard { } 662b75fdc11SChristophe Ricard }; 663b75fdc11SChristophe Ricard 664b75fdc11SChristophe Ricard U_BOOT_DRIVER(st33zp24_spi_spi) = { 665b75fdc11SChristophe Ricard .name = "st33zp24-spi", 666b75fdc11SChristophe Ricard .id = UCLASS_TPM, 667b75fdc11SChristophe Ricard .of_match = of_match_ptr(st33zp24_spi_ids), 668b75fdc11SChristophe Ricard .probe = st33zp24_spi_probe, 669b75fdc11SChristophe Ricard .remove = st33zp24_spi_remove, 670b75fdc11SChristophe Ricard .ops = &st33zp24_spi_tpm_ops, 671b75fdc11SChristophe Ricard .priv_auto_alloc_size = sizeof(struct tpm_chip), 672b75fdc11SChristophe Ricard .platdata_auto_alloc_size = sizeof(struct st33zp24_spi_phy), 673b75fdc11SChristophe Ricard }; 674