diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 2df3dad553245a9e0698e470b8e9404817fbd480..2b6980e441d62292aab51e1650a079c9c1f0821b 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -690,4 +690,20 @@ u32 tpm2_report_state(struct udevice *dev, uint vendor_cmd, uint vendor_subcmd,
 u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
 			  uint vendor_subcmd);
 
+/**
+ * tpm2_auto_start() - start up the TPM and perform selftests.
+ *                     If a testable function has not been tested and is
+ *                     requested the TPM2  will return TPM_RC_NEEDS_TEST.
+ *
+ * @param dev		TPM device
+ * Return: TPM2_RC_TESTING, if TPM2 self-test is in progress.
+ *         TPM2_RC_SUCCESS, if testing of all functions is complete without
+ *         functional failures.
+ *         TPM2_RC_FAILURE, if any test failed.
+ *         TPM2_RC_INITIALIZE, if the TPM has not gone through the Startup
+ *         sequence
+
+ */
+u32 tpm2_auto_start(struct udevice *dev);
+
 #endif /* __TPM_V2_H */
diff --git a/include/tpm_api.h b/include/tpm_api.h
index 8979d9d6df7ef8caec8b9dd6287c7b23c1d805f7..022a8bbaeca606cc88715401dcfd05f5067e628f 100644
--- a/include/tpm_api.h
+++ b/include/tpm_api.h
@@ -331,4 +331,12 @@ static inline bool tpm_is_v2(struct udevice *dev)
 	return IS_ENABLED(CONFIG_TPM_V2) && tpm_get_version(dev) == TPM_V2;
 }
 
+/**
+ * tpm_auto_start() - start up the TPM and perform selftests
+ *
+ * @param dev		TPM device
+ * Return: return code of the operation (0 = success)
+ */
+u32 tpm_auto_start(struct udevice *dev);
+
 #endif /* __TPM_API_H */
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 697b982e079fbdc4f4ebf1ed8daa953ef9647f5f..895b093bcb1a5df38fea36792dd673f090335042 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -44,6 +44,31 @@ u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test)
 	return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
 }
 
+u32 tpm2_auto_start(struct udevice *dev)
+{
+	u32 rc;
+
+	/*
+	 * the tpm_init() will return -EBUSY if the init has already happened
+	 * The selftest and startup code can run multiple times with no side
+	 * effects
+	 */
+	rc = tpm_init(dev);
+	if (rc && rc != -EBUSY)
+		return rc;
+	rc = tpm2_self_test(dev, TPMI_YES);
+
+	if (rc == TPM2_RC_INITIALIZE) {
+		rc = tpm2_startup(dev, TPM2_SU_CLEAR);
+		if (rc)
+			return rc;
+
+		rc = tpm2_self_test(dev, TPMI_YES);
+	}
+
+	return rc;
+}
+
 u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw,
 	       const ssize_t pw_sz)
 {
diff --git a/lib/tpm_api.c b/lib/tpm_api.c
index 7e8df8795ef3e74973e30e940d3db19f3035e723..5b2c11a277cc9c4610d1f546f34d56b10dbd2128 100644
--- a/lib/tpm_api.c
+++ b/lib/tpm_api.c
@@ -35,6 +35,14 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
 	}
 }
 
+u32 tpm_auto_start(struct udevice *dev)
+{
+	if (tpm_is_v2(dev))
+		return tpm2_auto_start(dev);
+
+	return -ENOSYS;
+}
+
 u32 tpm_resume(struct udevice *dev)
 {
 	if (tpm_is_v1(dev))