Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41a5e1cf authored by Christophe Ricard's avatar Christophe Ricard Committed by Jarkko Sakkinen
Browse files

tpm/tpm_tis: Split tpm_tis driver into a core and TCG TIS compliant phy



To avoid code duplication between the old tpm_tis and the new and future
native tcg tis driver(ie: spi, i2c...), the tpm_tis driver was reworked,
so that all common logic is extracted and can be reused from all drivers.

The core methods can also be used from other TIS like drivers.

itpm workaround is now managed with a specific tis flag
TPM_TIS_ITPM_POSSIBLE.

This commit is based on the initial work by Peter Huewe.

Signed-off-by: default avatarPeter Huewe <peter.huewe@infineon.com>
Signed-off-by: default avatarChristophe Ricard <christophe-h.ricard@st.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: default avatarStefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: default avatarStefan Berger <stefanb@linux.vnet.ibm.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
parent 92eb0f73
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -24,9 +24,16 @@ menuconfig TCG_TPM

if TCG_TPM

config TCG_TIS_CORE
	tristate
	---help---
	TCG TIS TPM core driver. It implements the TPM TCG TIS logic and hooks
	into the TPM kernel APIs. Physical layers will register against it.

config TCG_TIS
	tristate "TPM Interface Specification 1.2 Interface / TPM 2.0 FIFO Interface"
	depends on X86
	select TCG_TIS_CORE
	---help---
	  If you have a TPM security chip that is compliant with the
	  TCG TIS 1.2 TPM specification (TPM1.2) or the TCG PTP FIFO
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ ifdef CONFIG_TCG_IBMVTPM
	tpm-y += tpm_eventlog.o tpm_of.o
endif
endif
obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
obj-$(CONFIG_TCG_TIS) += tpm_tis.o
obj-$(CONFIG_TCG_TIS_I2C_ATMEL) += tpm_i2c_atmel.o
obj-$(CONFIG_TCG_TIS_I2C_INFINEON) += tpm_i2c_infineon.o
+20 −882

File changed.

Preview size limit exceeded, changes collapsed.

+862 −0

File added.

Preview size limit exceeded, changes collapsed.

+68 −0
Original line number Diff line number Diff line
@@ -25,11 +25,70 @@

#include "tpm.h"

enum tis_access {
	TPM_ACCESS_VALID = 0x80,
	TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
	TPM_ACCESS_REQUEST_PENDING = 0x04,
	TPM_ACCESS_REQUEST_USE = 0x02,
};

enum tis_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 tis_int_flags {
	TPM_GLOBAL_INT_ENABLE = 0x80000000,
	TPM_INTF_BURST_COUNT_STATIC = 0x100,
	TPM_INTF_CMD_READY_INT = 0x080,
	TPM_INTF_INT_EDGE_FALLING = 0x040,
	TPM_INTF_INT_EDGE_RISING = 0x020,
	TPM_INTF_INT_LEVEL_LOW = 0x010,
	TPM_INTF_INT_LEVEL_HIGH = 0x008,
	TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
	TPM_INTF_STS_VALID_INT = 0x002,
	TPM_INTF_DATA_AVAIL_INT = 0x001,
};

enum tis_defaults {
	TIS_MEM_LEN = 0x5000,
	TIS_SHORT_TIMEOUT = 750,	/* ms */
	TIS_LONG_TIMEOUT = 2000,	/* 2 sec */
};

/* Some timeout values are needed before it is known whether the chip is
 * TPM 1.0 or TPM 2.0.
 */
#define TIS_TIMEOUT_A_MAX	max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_A)
#define TIS_TIMEOUT_B_MAX	max(TIS_LONG_TIMEOUT, TPM2_TIMEOUT_B)
#define TIS_TIMEOUT_C_MAX	max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_C)
#define TIS_TIMEOUT_D_MAX	max(TIS_SHORT_TIMEOUT, TPM2_TIMEOUT_D)

#define	TPM_ACCESS(l)			(0x0000 | ((l) << 12))
#define	TPM_INT_ENABLE(l)		(0x0008 | ((l) << 12))
#define	TPM_INT_VECTOR(l)		(0x000C | ((l) << 12))
#define	TPM_INT_STATUS(l)		(0x0010 | ((l) << 12))
#define	TPM_INTF_CAPS(l)		(0x0014 | ((l) << 12))
#define	TPM_STS(l)			(0x0018 | ((l) << 12))
#define	TPM_STS3(l)			(0x001b | ((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))

enum tpm_tis_flags {
	TPM_TIS_ITPM_POSSIBLE		= BIT(0),
};

struct tpm_tis_data {
	u16 manufacturer_id;
	int locality;
	int irq;
	bool irq_tested;
	unsigned int flags;
	wait_queue_head_t int_queue;
	wait_queue_head_t read_queue;
	const struct tpm_tis_phy_ops *phy_ops;
@@ -85,4 +144,13 @@ static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr,
	return data->phy_ops->write32(data, addr, value);
}

void tpm_tis_remove(struct tpm_chip *chip);
int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
		      const struct tpm_tis_phy_ops *phy_ops,
		      acpi_handle acpi_dev_handle);

#ifdef CONFIG_PM_SLEEP
int tpm_tis_resume(struct device *dev);
#endif

#endif