uboot/drivers/tpm/tpm_tis_st33zp24_i2c.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * STMicroelectronics TPM ST33ZP24 I2C UBOOT driver
   4 *
   5 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
   6 * Author(s): Christophe Ricard <christophe-h.ricard@st.com> for STMicroelectronics.
   7 *
   8 * Description: Device driver for ST33ZP24 I2C TPM TCG.
   9 *
  10 * This device driver implements the TPM interface as defined in
  11 * the TCG TPM Interface Spec version 1.21, revision 1.0 and the
  12 * STMicroelectronics Protocol Stack Specification version 1.2.0.
  13 */
  14
  15#include <common.h>
  16#include <dm.h>
  17#include <fdtdec.h>
  18#include <i2c.h>
  19#include <log.h>
  20#include <tpm-v1.h>
  21#include <errno.h>
  22#include <linux/delay.h>
  23#include <linux/types.h>
  24#include <asm/unaligned.h>
  25
  26#include "tpm_tis.h"
  27#include "tpm_internal.h"
  28
  29#define TPM_ACCESS                      0x0
  30#define TPM_STS                         0x18
  31#define TPM_DATA_FIFO                   0x24
  32
  33#define LOCALITY0                       0
  34
  35#define TPM_DUMMY_BYTE                  0xAA
  36#define TPM_ST33ZP24_I2C_SLAVE_ADDR     0x13
  37
  38#define TPM_WRITE_DIRECTION             0x80
  39
  40/*
  41 * st33zp24_i2c_write8_reg
  42 * Send byte to the TIS register according to the ST33ZP24 I2C protocol.
  43 * @param: tpm_register, the tpm tis register where the data should be written
  44 * @param: tpm_data, the tpm_data to write inside the tpm_register
  45 * @param: tpm_size, The length of the data
  46 * @return: Number of byte written successfully else an error code.
  47 */
  48static int st33zp24_i2c_write8_reg(struct udevice *dev, u8 tpm_register,
  49                                   const u8 *tpm_data, size_t tpm_size)
  50{
  51        struct tpm_chip_priv *chip_priv = dev_get_uclass_priv(dev);
  52
  53        chip_priv->buf[0] = tpm_register;
  54        memcpy(chip_priv->buf + 1, tpm_data, tpm_size);
  55
  56        return dm_i2c_write(dev, 0, chip_priv->buf, tpm_size + 1);
  57}
  58
  59/*
  60* st33zp24_i2c_read8_reg
  61* Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
  62* @param: tpm_register, the tpm tis register where the data should be read
  63* @param: tpm_data, the TPM response
  64* @param: tpm_size, tpm TPM response size to read.
  65* @return: Number of byte read successfully else an error code.
  66*/
  67static int st33zp24_i2c_read8_reg(struct udevice *dev, u8 tpm_register,
  68                                  u8 *tpm_data, size_t tpm_size)
  69{
  70        int status;
  71        u8 data;
  72
  73        data = TPM_DUMMY_BYTE;
  74        status = st33zp24_i2c_write8_reg(dev, tpm_register, &data, 1);
  75        if (status < 0)
  76                return status;
  77
  78        return dm_i2c_read(dev, 0, tpm_data, tpm_size);
  79}
  80
  81/*
  82 * st33zp24_i2c_write
  83 * Send byte to the TIS register according to the ST33ZP24 I2C protocol.
  84 * @param: phy_id, the phy description
  85 * @param: tpm_register, the tpm tis register where the data should be written
  86 * @param: tpm_data, the tpm_data to write inside the tpm_register
  87 * @param: tpm_size, the length of the data
  88 * @return: number of byte written successfully: should be one if success.
  89 */
  90static int st33zp24_i2c_write(struct udevice *dev, u8 tpm_register,
  91                              const u8 *tpm_data, size_t tpm_size)
  92{
  93        return st33zp24_i2c_write8_reg(dev, tpm_register | TPM_WRITE_DIRECTION,
  94                                       tpm_data, tpm_size);
  95}
  96
  97/*
  98 * st33zp24_i2c_read
  99 * Recv byte from the TIS register according to the ST33ZP24 I2C protocol.
 100 * @param: phy_id, the phy description
 101 * @param: tpm_register, the tpm tis register where the data should be read
 102 * @param: tpm_data, the TPM response
 103 * @param: tpm_size, tpm TPM response size to read.
 104 * @return: number of byte read successfully: should be one if success.
 105 */
 106static int st33zp24_i2c_read(struct udevice *dev, u8 tpm_register,
 107                             u8 *tpm_data, size_t tpm_size)
 108{
 109        return st33zp24_i2c_read8_reg(dev, tpm_register, tpm_data, tpm_size);
 110}
 111
 112/*
 113 * st33zp24_i2c_release_locality release the active locality
 114 * @param: chip, the tpm chip description.
 115 */
 116static void st33zp24_i2c_release_locality(struct udevice *dev)
 117{
 118        u8 data = TPM_ACCESS_ACTIVE_LOCALITY;
 119
 120        st33zp24_i2c_write(dev, TPM_ACCESS, &data, 1);
 121}
 122
 123/*
 124 * st33zp24_i2c_check_locality if the locality is active
 125 * @param: chip, the tpm chip description
 126 * @return: the active locality or -EACCES.
 127 */
 128static int st33zp24_i2c_check_locality(struct udevice *dev)
 129{
 130        struct tpm_chip *chip = dev_get_priv(dev);
 131        u8 data;
 132        u8 status;
 133
 134        status = st33zp24_i2c_read(dev, TPM_ACCESS, &data, 1);
 135        if (!status && (data &
 136                (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
 137                (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
 138                return chip->locality;
 139
 140        return -EACCES;
 141}
 142
 143/*
 144 * st33zp24_i2c_request_locality request the TPM locality
 145 * @param: chip, the chip description
 146 * @return: the active locality or negative value.
 147 */
 148static int st33zp24_i2c_request_locality(struct udevice *dev)
 149{
 150        struct tpm_chip *chip = dev_get_priv(dev);
 151        unsigned long start, stop;
 152        long ret;
 153        u8 data;
 154
 155        if (st33zp24_i2c_check_locality(dev) == chip->locality)
 156                return chip->locality;
 157
 158        data = TPM_ACCESS_REQUEST_USE;
 159        ret = st33zp24_i2c_write(dev, TPM_ACCESS, &data, 1);
 160        if (ret < 0)
 161                return ret;
 162
 163        /* wait for locality activated */
 164        start = get_timer(0);
 165        stop = chip->timeout_a;
 166        do {
 167                if (st33zp24_i2c_check_locality(dev) >= 0)
 168                        return chip->locality;
 169                udelay(TPM_TIMEOUT_MS * 1000);
 170        } while  (get_timer(start) < stop);
 171
 172        return -EACCES;
 173}
 174
 175/*
 176 * st33zp24_i2c_status return the TPM_STS register
 177 * @param: chip, the tpm chip description
 178 * @return: the TPM_STS register value.
 179 */
 180static u8 st33zp24_i2c_status(struct udevice *dev)
 181{
 182        u8 data;
 183
 184        st33zp24_i2c_read(dev, TPM_STS, &data, 1);
 185
 186        return data;
 187}
 188
 189/*
 190 * st33zp24_i2c_get_burstcount return the burstcount address 0x19 0x1A
 191 * @param: chip, the chip description
 192 * return: the burstcount or -TPM_DRIVER_ERR in case of error.
 193 */
 194static int st33zp24_i2c_get_burstcount(struct udevice *dev)
 195{
 196        struct tpm_chip *chip = dev_get_priv(dev);
 197        unsigned long start, stop;
 198        int burstcnt, status;
 199        u8 tpm_reg, temp;
 200
 201        /* wait for burstcount */
 202        start = get_timer(0);
 203        stop = chip->timeout_d;
 204        do {
 205                tpm_reg = TPM_STS + 1;
 206                status = st33zp24_i2c_read(dev, tpm_reg, &temp, 1);
 207                if (status < 0)
 208                        return -EBUSY;
 209
 210                tpm_reg = TPM_STS + 2;
 211                burstcnt = temp;
 212                status = st33zp24_i2c_read(dev, tpm_reg, &temp, 1);
 213                if (status < 0)
 214                        return -EBUSY;
 215
 216                burstcnt |= temp << 8;
 217                if (burstcnt)
 218                        return burstcnt;
 219                udelay(TIS_SHORT_TIMEOUT_MS * 1000);
 220        } while (get_timer(start) < stop);
 221
 222        return -EBUSY;
 223}
 224
 225/*
 226 * st33zp24_i2c_cancel, cancel the current command execution or
 227 * set STS to COMMAND READY.
 228 * @param: chip, tpm_chip description.
 229 */
 230static void st33zp24_i2c_cancel(struct udevice *dev)
 231{
 232        u8 data;
 233
 234        data = TPM_STS_COMMAND_READY;
 235        st33zp24_i2c_write(dev, TPM_STS, &data, 1);
 236}
 237
 238/*
 239 * st33zp24_i2c_wait_for_stat wait for a TPM_STS value
 240 * @param: chip, the tpm chip description
 241 * @param: mask, the value mask to wait
 242 * @param: timeout, the timeout
 243 * @param: status,
 244 * @return: the tpm status, 0 if success, -ETIME if timeout is reached.
 245 */
 246static int st33zp24_i2c_wait_for_stat(struct udevice *dev, u8 mask,
 247                                      unsigned long timeout, int *status)
 248{
 249        unsigned long start, stop;
 250
 251        /* Check current status */
 252        *status = st33zp24_i2c_status(dev);
 253        if ((*status & mask) == mask)
 254                return 0;
 255
 256        start = get_timer(0);
 257        stop = timeout;
 258        do {
 259                udelay(TPM_TIMEOUT_MS * 1000);
 260                *status = st33zp24_i2c_status(dev);
 261                if ((*status & mask) == mask)
 262                        return 0;
 263        } while (get_timer(start) < stop);
 264
 265        return -ETIME;
 266}
 267
 268/*
 269 * st33zp24_i2c_recv_data receive data
 270 * @param: chip, the tpm chip description
 271 * @param: buf, the buffer where the data are received
 272 * @param: count, the number of data to receive
 273 * @return: the number of bytes read from TPM FIFO.
 274 */
 275static int st33zp24_i2c_recv_data(struct udevice *dev, u8 *buf, size_t count)
 276{
 277        struct tpm_chip *chip = dev_get_priv(dev);
 278        int size = 0, burstcnt, len, ret, status;
 279
 280        while (size < count &&
 281               st33zp24_i2c_wait_for_stat(dev, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 282                                chip->timeout_c, &status) == 0) {
 283                burstcnt = st33zp24_i2c_get_burstcount(dev);
 284                if (burstcnt < 0)
 285                        return burstcnt;
 286                len = min_t(int, burstcnt, count - size);
 287                ret = st33zp24_i2c_read(dev, TPM_DATA_FIFO, buf + size, len);
 288                if (ret < 0)
 289                        return ret;
 290
 291                size += len;
 292        }
 293
 294        return size;
 295}
 296
 297/*
 298 * st33zp24_i2c_recv received TPM response through TPM phy.
 299 * @param: chip, tpm_chip description.
 300 * @param: buf, the buffer to store data.
 301 * @param: count, the number of bytes that can received (sizeof buf).
 302 * @return: Returns zero in case of success else -EIO.
 303 */
 304static int st33zp24_i2c_recv(struct udevice *dev, u8 *buf, size_t count)
 305{
 306        struct tpm_chip *chip = dev_get_priv(dev);
 307        int size;
 308        unsigned int expected;
 309
 310        if (!chip)
 311                return -ENODEV;
 312
 313        if (count < TPM_HEADER_SIZE) {
 314                size = -EIO;
 315                goto out;
 316        }
 317
 318        size = st33zp24_i2c_recv_data(dev, buf, TPM_HEADER_SIZE);
 319        if (size < TPM_HEADER_SIZE) {
 320                debug("TPM error, unable to read header\n");
 321                goto out;
 322        }
 323
 324        expected = get_unaligned_be32(buf + 2);
 325        if (expected > count || expected < TPM_HEADER_SIZE) {
 326                size = -EIO;
 327                goto out;
 328        }
 329
 330        size += st33zp24_i2c_recv_data(dev, &buf[TPM_HEADER_SIZE],
 331                                   expected - TPM_HEADER_SIZE);
 332        if (size < expected) {
 333                debug("TPM error, unable to read remaining bytes of result\n");
 334                size = -EIO;
 335                goto out;
 336        }
 337
 338out:
 339        st33zp24_i2c_cancel(dev);
 340        st33zp24_i2c_release_locality(dev);
 341
 342        return size;
 343}
 344
 345/*
 346 * st33zp24_i2c_send send TPM commands through TPM phy.
 347 * @param: chip, tpm_chip description.
 348 * @param: buf, the buffer to send.
 349 * @param: len, the number of bytes to send.
 350 * @return: Returns zero in case of success else the negative error code.
 351 */
 352static int st33zp24_i2c_send(struct udevice *dev, const u8 *buf, size_t len)
 353{
 354        struct tpm_chip *chip = dev_get_priv(dev);
 355        u32 i, size;
 356        int burstcnt, ret, status;
 357        u8 data, tpm_stat;
 358
 359        if (!chip)
 360                return -ENODEV;
 361        if (len < TPM_HEADER_SIZE)
 362                return -EIO;
 363
 364        ret = st33zp24_i2c_request_locality(dev);
 365        if (ret < 0)
 366                return ret;
 367
 368        tpm_stat = st33zp24_i2c_status(dev);
 369        if ((tpm_stat & TPM_STS_COMMAND_READY) == 0) {
 370                st33zp24_i2c_cancel(dev);
 371                if (st33zp24_i2c_wait_for_stat(dev, TPM_STS_COMMAND_READY,
 372                                               chip->timeout_b, &status) < 0) {
 373                        ret = -ETIME;
 374                        goto out_err;
 375                }
 376        }
 377
 378        for (i = 0; i < len - 1;) {
 379                burstcnt = st33zp24_i2c_get_burstcount(dev);
 380                if (burstcnt < 0)
 381                        return burstcnt;
 382
 383                size = min_t(int, len - i - 1, burstcnt);
 384                ret = st33zp24_i2c_write(dev, TPM_DATA_FIFO, buf + i, size);
 385                if (ret < 0)
 386                        goto out_err;
 387
 388                i += size;
 389        }
 390
 391        tpm_stat = st33zp24_i2c_status(dev);
 392        if ((tpm_stat & TPM_STS_DATA_EXPECT) == 0) {
 393                ret = -EIO;
 394                goto out_err;
 395        }
 396
 397        ret = st33zp24_i2c_write(dev, TPM_DATA_FIFO, buf + len - 1, 1);
 398        if (ret < 0)
 399                goto out_err;
 400
 401        tpm_stat = st33zp24_i2c_status(dev);
 402        if ((tpm_stat & TPM_STS_DATA_EXPECT) != 0) {
 403                ret = -EIO;
 404                goto out_err;
 405        }
 406
 407        data = TPM_STS_GO;
 408        ret = st33zp24_i2c_write(dev, TPM_STS, &data, 1);
 409        if (ret < 0)
 410                goto out_err;
 411
 412        return len;
 413
 414out_err:
 415        st33zp24_i2c_cancel(dev);
 416        st33zp24_i2c_release_locality(dev);
 417
 418        return ret;
 419}
 420
 421static int st33zp24_i2c_cleanup(struct udevice *dev)
 422{
 423        st33zp24_i2c_cancel(dev);
 424        /*
 425         * The TPM needs some time to clean up here,
 426         * so we sleep rather than keeping the bus busy
 427         */
 428        mdelay(2);
 429        st33zp24_i2c_release_locality(dev);
 430
 431        return 0;
 432}
 433
 434static int st33zp24_i2c_init(struct udevice *dev)
 435{
 436        struct tpm_chip *chip = dev_get_priv(dev);
 437
 438        chip->is_open = 1;
 439
 440        /* Default timeouts - these could move to the device tree */
 441        chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
 442        chip->timeout_b = TIS_LONG_TIMEOUT_MS;
 443        chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
 444        chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
 445
 446        chip->locality = LOCALITY0;
 447
 448        /*
 449         * A timeout query to TPM can be placed here.
 450         * Standard timeout values are used so far
 451         */
 452
 453        return 0;
 454}
 455
 456static int st33zp24_i2c_open(struct udevice *dev)
 457{
 458        struct tpm_chip *chip = dev_get_priv(dev);
 459        int rc;
 460
 461        debug("%s: start\n", __func__);
 462        if (chip->is_open)
 463                return -EBUSY;
 464
 465        rc = st33zp24_i2c_init(dev);
 466        if (rc < 0)
 467                chip->is_open = 0;
 468
 469        return rc;
 470}
 471
 472static int st33zp24_i2c_close(struct udevice *dev)
 473{
 474        struct tpm_chip *chip = dev_get_priv(dev);
 475
 476        if (chip->is_open) {
 477                st33zp24_i2c_release_locality(dev);
 478                chip->is_open = 0;
 479                chip->vend_dev = 0;
 480        }
 481
 482        return 0;
 483}
 484
 485static int st33zp24_i2c_get_desc(struct udevice *dev, char *buf, int size)
 486{
 487        struct tpm_chip *chip = dev_get_priv(dev);
 488
 489        if (size < 50)
 490                return -ENOSPC;
 491
 492        return snprintf(buf, size, "1.2 TPM (%s, chip type %s device-id 0x%x)",
 493                        chip->is_open ? "open" : "closed",
 494                        dev->name,
 495                        chip->vend_dev >> 16);
 496}
 497
 498static const struct tpm_ops st33zp24_i2c_tpm_ops = {
 499        .open = st33zp24_i2c_open,
 500        .close = st33zp24_i2c_close,
 501        .recv = st33zp24_i2c_recv,
 502        .send = st33zp24_i2c_send,
 503        .cleanup = st33zp24_i2c_cleanup,
 504        .get_desc = st33zp24_i2c_get_desc,
 505};
 506
 507static int st33zp24_i2c_probe(struct udevice *dev)
 508{
 509        struct tpm_chip *chip = dev_get_priv(dev);
 510
 511        /* Default timeouts */
 512        chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
 513        chip->timeout_b = TIS_LONG_TIMEOUT_MS;
 514        chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
 515        chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
 516
 517        chip->locality = LOCALITY0;
 518
 519        i2c_set_chip_offset_len(dev, 0);
 520
 521        debug("ST33ZP24 I2C TPM from STMicroelectronics found\n");
 522
 523        return 0;
 524}
 525
 526static int st33zp24_i2c_remove(struct udevice *dev)
 527{
 528        st33zp24_i2c_release_locality(dev);
 529
 530        return 0;
 531}
 532
 533static const struct udevice_id st33zp24_i2c_ids[] = {
 534        { .compatible = "st,st33zp24-i2c" },
 535        { }
 536};
 537
 538U_BOOT_DRIVER(st33zp24_i2c) = {
 539        .name   = "st33zp24-i2c",
 540        .id     = UCLASS_TPM,
 541        .of_match = of_match_ptr(st33zp24_i2c_ids),
 542        .probe  = st33zp24_i2c_probe,
 543        .remove = st33zp24_i2c_remove,
 544        .ops = &st33zp24_i2c_tpm_ops,
 545        .priv_auto      = sizeof(struct tpm_chip),
 546};
 547