183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0 */ 21259dcd7SChristophe Ricard /* 31259dcd7SChristophe Ricard * Copyright (C) 2011 Infineon Technologies 41259dcd7SChristophe Ricard * 51259dcd7SChristophe Ricard * Authors: 61259dcd7SChristophe Ricard * Peter Huewe <huewe.external@infineon.com> 71259dcd7SChristophe Ricard * 81259dcd7SChristophe Ricard * Version: 2.1.1 91259dcd7SChristophe Ricard * 101259dcd7SChristophe Ricard * Description: 111259dcd7SChristophe Ricard * Device driver for TCG/TCPA TPM (trusted platform module). 121259dcd7SChristophe Ricard * Specifications at www.trustedcomputinggroup.org 131259dcd7SChristophe Ricard * 141259dcd7SChristophe Ricard * It is based on the Linux kernel driver tpm.c from Leendert van 151259dcd7SChristophe Ricard * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall. 161259dcd7SChristophe Ricard */ 171259dcd7SChristophe Ricard 181259dcd7SChristophe Ricard #ifndef _TPM_TIS_I2C_H 191259dcd7SChristophe Ricard #define _TPM_TIS_I2C_H 201259dcd7SChristophe Ricard 211259dcd7SChristophe Ricard #include <linux/compiler.h> 221259dcd7SChristophe Ricard #include <linux/types.h> 231259dcd7SChristophe Ricard 24*cea4033dSIlias Apalodimas /** 25*cea4033dSIlias Apalodimas * struct tpm_tis_phy_ops - low-level TPM bus operations 26*cea4033dSIlias Apalodimas */ 27*cea4033dSIlias Apalodimas struct tpm_tis_phy_ops { 28*cea4033dSIlias Apalodimas /* read_bytes() - Read a number of bytes from the device 29*cea4033dSIlias Apalodimas * 30*cea4033dSIlias Apalodimas * @udev: TPM device 31*cea4033dSIlias Apalodimas * @addr: offset from device base 32*cea4033dSIlias Apalodimas * @len: len to read 33*cea4033dSIlias Apalodimas * @result: data read 34*cea4033dSIlias Apalodimas * 35*cea4033dSIlias Apalodimas * @return: 0 on success, negative on failure 36*cea4033dSIlias Apalodimas */ 37*cea4033dSIlias Apalodimas int (*read_bytes)(struct udevice *udev, u32 addr, u16 len, 38*cea4033dSIlias Apalodimas u8 *result); 39*cea4033dSIlias Apalodimas /* write_bytes() - Read a number of bytes from the device 40*cea4033dSIlias Apalodimas * 41*cea4033dSIlias Apalodimas * @udev: TPM device 42*cea4033dSIlias Apalodimas * @addr: offset from device base 43*cea4033dSIlias Apalodimas * @len: len to read 44*cea4033dSIlias Apalodimas * @value: data to write 45*cea4033dSIlias Apalodimas * 46*cea4033dSIlias Apalodimas * @return: 0 on success, negative on failure 47*cea4033dSIlias Apalodimas */ 48*cea4033dSIlias Apalodimas int (*write_bytes)(struct udevice *udev, u32 addr, u16 len, 49*cea4033dSIlias Apalodimas const u8 *value); 50*cea4033dSIlias Apalodimas /* read32() - Read a 32bit value of the device 51*cea4033dSIlias Apalodimas * 52*cea4033dSIlias Apalodimas * @udev: TPM device 53*cea4033dSIlias Apalodimas * @addr: offset from device base 54*cea4033dSIlias Apalodimas * @result: data read 55*cea4033dSIlias Apalodimas * 56*cea4033dSIlias Apalodimas * @return: 0 on success, negative on failure 57*cea4033dSIlias Apalodimas */ 58*cea4033dSIlias Apalodimas int (*read32)(struct udevice *udev, u32 addr, u32 *result); 59*cea4033dSIlias Apalodimas /* write32() - write a 32bit value to the device 60*cea4033dSIlias Apalodimas * 61*cea4033dSIlias Apalodimas * @udev: TPM device 62*cea4033dSIlias Apalodimas * @addr: offset from device base 63*cea4033dSIlias Apalodimas * @src: data to write 64*cea4033dSIlias Apalodimas * 65*cea4033dSIlias Apalodimas * @return: 0 on success, negative on failure 66*cea4033dSIlias Apalodimas */ 67*cea4033dSIlias Apalodimas int (*write32)(struct udevice *udev, u32 addr, u32 src); 68*cea4033dSIlias Apalodimas }; 69*cea4033dSIlias Apalodimas 70*cea4033dSIlias Apalodimas enum tis_int_flags { 71*cea4033dSIlias Apalodimas TPM_GLOBAL_INT_ENABLE = 0x80000000, 72*cea4033dSIlias Apalodimas TPM_INTF_BURST_COUNT_STATIC = 0x100, 73*cea4033dSIlias Apalodimas TPM_INTF_CMD_READY_INT = 0x080, 74*cea4033dSIlias Apalodimas TPM_INTF_INT_EDGE_FALLING = 0x040, 75*cea4033dSIlias Apalodimas TPM_INTF_INT_EDGE_RISING = 0x020, 76*cea4033dSIlias Apalodimas TPM_INTF_INT_LEVEL_LOW = 0x010, 77*cea4033dSIlias Apalodimas TPM_INTF_INT_LEVEL_HIGH = 0x008, 78*cea4033dSIlias Apalodimas TPM_INTF_LOCALITY_CHANGE_INT = 0x004, 79*cea4033dSIlias Apalodimas TPM_INTF_STS_VALID_INT = 0x002, 80*cea4033dSIlias Apalodimas TPM_INTF_DATA_AVAIL_INT = 0x001, 81*cea4033dSIlias Apalodimas }; 82*cea4033dSIlias Apalodimas 83*cea4033dSIlias Apalodimas #define TPM_ACCESS(l) (0x0000 | ((l) << 12)) 84*cea4033dSIlias Apalodimas #define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12)) 85*cea4033dSIlias Apalodimas #define TPM_STS(l) (0x0018 | ((l) << 12)) 86*cea4033dSIlias Apalodimas #define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12)) 87*cea4033dSIlias Apalodimas #define TPM_DID_VID(l) (0x0f00 | ((l) << 12)) 88*cea4033dSIlias Apalodimas #define TPM_RID(l) (0x0f04 | ((l) << 12)) 89*cea4033dSIlias Apalodimas #define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12)) 90*cea4033dSIlias Apalodimas 911259dcd7SChristophe Ricard enum tpm_timeout { 921259dcd7SChristophe Ricard TPM_TIMEOUT_MS = 5, 931259dcd7SChristophe Ricard TIS_SHORT_TIMEOUT_MS = 750, 941259dcd7SChristophe Ricard TIS_LONG_TIMEOUT_MS = 2000, 951259dcd7SChristophe Ricard SLEEP_DURATION_US = 60, 961259dcd7SChristophe Ricard SLEEP_DURATION_LONG_US = 210, 971259dcd7SChristophe Ricard }; 981259dcd7SChristophe Ricard 991259dcd7SChristophe Ricard /* Size of external transmit buffer (used in tpm_transmit)*/ 1001259dcd7SChristophe Ricard #define TPM_BUFSIZE 4096 1011259dcd7SChristophe Ricard 1021259dcd7SChristophe Ricard /* Index of Count field in TPM response buffer */ 1031259dcd7SChristophe Ricard #define TPM_RSP_SIZE_BYTE 2 1041259dcd7SChristophe Ricard #define TPM_RSP_RC_BYTE 6 1051259dcd7SChristophe Ricard 1061259dcd7SChristophe Ricard struct tpm_chip { 1071259dcd7SChristophe Ricard int is_open; 1081259dcd7SChristophe Ricard int locality; 1091259dcd7SChristophe Ricard u32 vend_dev; 11006425aa0SMiquel Raynal u8 rid; 1111259dcd7SChristophe Ricard unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */ 1121259dcd7SChristophe Ricard ulong chip_type; 113*cea4033dSIlias Apalodimas struct tpm_tis_phy_ops *phy_ops; 1141259dcd7SChristophe Ricard }; 1151259dcd7SChristophe Ricard 1161259dcd7SChristophe Ricard struct tpm_input_header { 1171259dcd7SChristophe Ricard __be16 tag; 1181259dcd7SChristophe Ricard __be32 length; 1191259dcd7SChristophe Ricard __be32 ordinal; 1201259dcd7SChristophe Ricard } __packed; 1211259dcd7SChristophe Ricard 1221259dcd7SChristophe Ricard struct tpm_output_header { 1231259dcd7SChristophe Ricard __be16 tag; 1241259dcd7SChristophe Ricard __be32 length; 1251259dcd7SChristophe Ricard __be32 return_code; 1261259dcd7SChristophe Ricard } __packed; 1271259dcd7SChristophe Ricard 1281259dcd7SChristophe Ricard struct timeout_t { 1291259dcd7SChristophe Ricard __be32 a; 1301259dcd7SChristophe Ricard __be32 b; 1311259dcd7SChristophe Ricard __be32 c; 1321259dcd7SChristophe Ricard __be32 d; 1331259dcd7SChristophe Ricard } __packed; 1341259dcd7SChristophe Ricard 1351259dcd7SChristophe Ricard struct duration_t { 1361259dcd7SChristophe Ricard __be32 tpm_short; 1371259dcd7SChristophe Ricard __be32 tpm_medium; 1381259dcd7SChristophe Ricard __be32 tpm_long; 1391259dcd7SChristophe Ricard } __packed; 1401259dcd7SChristophe Ricard 1411259dcd7SChristophe Ricard union cap_t { 1421259dcd7SChristophe Ricard struct timeout_t timeout; 1431259dcd7SChristophe Ricard struct duration_t duration; 1441259dcd7SChristophe Ricard }; 1451259dcd7SChristophe Ricard 1461259dcd7SChristophe Ricard struct tpm_getcap_params_in { 1471259dcd7SChristophe Ricard __be32 cap; 1481259dcd7SChristophe Ricard __be32 subcap_size; 1491259dcd7SChristophe Ricard __be32 subcap; 1501259dcd7SChristophe Ricard } __packed; 1511259dcd7SChristophe Ricard 1521259dcd7SChristophe Ricard struct tpm_getcap_params_out { 1531259dcd7SChristophe Ricard __be32 cap_size; 1541259dcd7SChristophe Ricard union cap_t cap; 1551259dcd7SChristophe Ricard } __packed; 1561259dcd7SChristophe Ricard 1571259dcd7SChristophe Ricard union tpm_cmd_header { 1581259dcd7SChristophe Ricard struct tpm_input_header in; 1591259dcd7SChristophe Ricard struct tpm_output_header out; 1601259dcd7SChristophe Ricard }; 1611259dcd7SChristophe Ricard 1621259dcd7SChristophe Ricard union tpm_cmd_params { 1631259dcd7SChristophe Ricard struct tpm_getcap_params_out getcap_out; 1641259dcd7SChristophe Ricard struct tpm_getcap_params_in getcap_in; 1651259dcd7SChristophe Ricard }; 1661259dcd7SChristophe Ricard 1671259dcd7SChristophe Ricard struct tpm_cmd_t { 1681259dcd7SChristophe Ricard union tpm_cmd_header header; 1691259dcd7SChristophe Ricard union tpm_cmd_params params; 1701259dcd7SChristophe Ricard } __packed; 1711259dcd7SChristophe Ricard 1721259dcd7SChristophe Ricard /* Max number of iterations after i2c NAK */ 1731259dcd7SChristophe Ricard #define MAX_COUNT 3 1741259dcd7SChristophe Ricard 1753982c49dSJohannes Holland #ifndef __TPM_V2_H 1761259dcd7SChristophe Ricard /* 1771259dcd7SChristophe Ricard * Max number of iterations after i2c NAK for 'long' commands 1781259dcd7SChristophe Ricard * 1791259dcd7SChristophe Ricard * We need this especially for sending TPM_READY, since the cleanup after the 1801259dcd7SChristophe Ricard * transtion to the ready state may take some time, but it is unpredictable 1811259dcd7SChristophe Ricard * how long it will take. 1821259dcd7SChristophe Ricard */ 1831259dcd7SChristophe Ricard #define MAX_COUNT_LONG 50 1841259dcd7SChristophe Ricard 1851259dcd7SChristophe Ricard enum tis_access { 1861259dcd7SChristophe Ricard TPM_ACCESS_VALID = 0x80, 1871259dcd7SChristophe Ricard TPM_ACCESS_ACTIVE_LOCALITY = 0x20, 1881259dcd7SChristophe Ricard TPM_ACCESS_REQUEST_PENDING = 0x04, 1891259dcd7SChristophe Ricard TPM_ACCESS_REQUEST_USE = 0x02, 1901259dcd7SChristophe Ricard }; 1911259dcd7SChristophe Ricard 1921259dcd7SChristophe Ricard enum tis_status { 1931259dcd7SChristophe Ricard TPM_STS_VALID = 0x80, 1941259dcd7SChristophe Ricard TPM_STS_COMMAND_READY = 0x40, 1951259dcd7SChristophe Ricard TPM_STS_GO = 0x20, 1961259dcd7SChristophe Ricard TPM_STS_DATA_AVAIL = 0x10, 1971259dcd7SChristophe Ricard TPM_STS_DATA_EXPECT = 0x08, 1981259dcd7SChristophe Ricard }; 1993982c49dSJohannes Holland #endif 2001259dcd7SChristophe Ricard 201*cea4033dSIlias Apalodimas /** 202*cea4033dSIlias Apalodimas * tpm_tis_open - Open the device and request locality 0 203*cea4033dSIlias Apalodimas * 204*cea4033dSIlias Apalodimas * @dev: TPM device 205*cea4033dSIlias Apalodimas * 206*cea4033dSIlias Apalodimas * @return: 0 on success, negative on failure 207*cea4033dSIlias Apalodimas */ 208*cea4033dSIlias Apalodimas int tpm_tis_open(struct udevice *udev); 209*cea4033dSIlias Apalodimas /** 210*cea4033dSIlias Apalodimas * tpm_tis_close - Close the device and release locality 211*cea4033dSIlias Apalodimas * 212*cea4033dSIlias Apalodimas * @dev: TPM device 213*cea4033dSIlias Apalodimas * 214*cea4033dSIlias Apalodimas * @return: 0 on success, negative on failure 215*cea4033dSIlias Apalodimas */ 216*cea4033dSIlias Apalodimas int tpm_tis_close(struct udevice *udev); 217*cea4033dSIlias Apalodimas /** tpm_tis_cleanup - Get the device in ready state and release locality 218*cea4033dSIlias Apalodimas * 219*cea4033dSIlias Apalodimas * @dev: TPM device 220*cea4033dSIlias Apalodimas * 221*cea4033dSIlias Apalodimas * @return: always 0 222*cea4033dSIlias Apalodimas */ 223*cea4033dSIlias Apalodimas int tpm_tis_cleanup(struct udevice *udev); 224*cea4033dSIlias Apalodimas /** 225*cea4033dSIlias Apalodimas * tpm_tis_send - send data to the device 226*cea4033dSIlias Apalodimas * 227*cea4033dSIlias Apalodimas * @dev: TPM device 228*cea4033dSIlias Apalodimas * @buf: buffer to send 229*cea4033dSIlias Apalodimas * @len: size of the buffer 230*cea4033dSIlias Apalodimas * 231*cea4033dSIlias Apalodimas * @return: number of bytes sent or negative on failure 232*cea4033dSIlias Apalodimas */ 233*cea4033dSIlias Apalodimas int tpm_tis_send(struct udevice *udev, const u8 *buf, size_t len); 234*cea4033dSIlias Apalodimas /** 235*cea4033dSIlias Apalodimas * tpm_tis_recv_data - Receive data from a device. Wrapper for tpm_tis_recv 236*cea4033dSIlias Apalodimas * 237*cea4033dSIlias Apalodimas * @dev: TPM device 238*cea4033dSIlias Apalodimas * @buf: buffer to copy data 239*cea4033dSIlias Apalodimas * @size: buffer size 240*cea4033dSIlias Apalodimas * 241*cea4033dSIlias Apalodimas * @return: bytes read or negative on failure 242*cea4033dSIlias Apalodimas */ 243*cea4033dSIlias Apalodimas int tpm_tis_recv(struct udevice *udev, u8 *buf, size_t count); 244*cea4033dSIlias Apalodimas /** 245*cea4033dSIlias Apalodimas * tpm_tis_get_desc - Get the TPM description 246*cea4033dSIlias Apalodimas * 247*cea4033dSIlias Apalodimas * @dev: TPM device 248*cea4033dSIlias Apalodimas * @buf: buffer to fill data 249*cea4033dSIlias Apalodimas * @size: buffer size 250*cea4033dSIlias Apalodimas * 251*cea4033dSIlias Apalodimas * @return: Number of characters written (or would have been written) in buffer 252*cea4033dSIlias Apalodimas */ 253*cea4033dSIlias Apalodimas int tpm_tis_get_desc(struct udevice *udev, char *buf, int size); 254*cea4033dSIlias Apalodimas /** 255*cea4033dSIlias Apalodimas * tpm_tis_init - inititalize the device 256*cea4033dSIlias Apalodimas * 257*cea4033dSIlias Apalodimas * @dev: TPM device 258*cea4033dSIlias Apalodimas * 259*cea4033dSIlias Apalodimas * @return: 0 on success, negative on failure 260*cea4033dSIlias Apalodimas */ 261*cea4033dSIlias Apalodimas int tpm_tis_init(struct udevice *udev); 262*cea4033dSIlias Apalodimas /** 263*cea4033dSIlias Apalodimas * tpm_tis_ops_register - register the PHY ops for the device 264*cea4033dSIlias Apalodimas * 265*cea4033dSIlias Apalodimas * @dev: TPM device 266*cea4033dSIlias Apalodimas * @ops: tpm_tis_phy_ops ops for the device 267*cea4033dSIlias Apalodimas */ 268*cea4033dSIlias Apalodimas void tpm_tis_ops_register(struct udevice *udev, struct tpm_tis_phy_ops *ops); 2691259dcd7SChristophe Ricard #endif 270