feat(tpm): add Infineon SLB9670 GPIO SPI config

add the Infineon Optiga SLB9670 TPM2.0 GPIO SPI
configuration data, as well as chip reset and the
GPIO SPI bitbang driver initialization. This code
supports use with the rpi3 platform, with availibility
to add configuration parameters for other platforms

Change-Id: Ibdffb28fa0b3b5a18dff2ba5d4ea305633740763
Signed-off-by: Abhi Singh <abhi.singh@arm.com>
diff --git a/drivers/tpm/tpm2_slb9670/slb9670_gpio.c b/drivers/tpm/tpm2_slb9670/slb9670_gpio.c
new file mode 100644
index 0000000..993387d
--- /dev/null
+++ b/drivers/tpm/tpm2_slb9670/slb9670_gpio.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/delay_timer.h>
+#include <drivers/gpio.h>
+#include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h>
+
+/*
+ * Infineon SLB9670 Chip Reset Parameters
+ */
+#define t_WRST	2 /* Warm Reset Time (us) */
+#define t_RSTIN	60 /* Reset Inactive Time (ms) */
+
+/*
+ * RPi3 GPIO pin configuration for TPM via bit-bang SPI
+ * References: https://pinout.xyz/pinout/spi
+ * - docs/design_documents/measured_boot_dtpm_poc.rst
+ */
+const struct gpio_spi_data tpm_rpi3_gpio_data = {
+	.cs_gpio = 7,
+	.sclk_gpio = 11,
+	.mosi_gpio = 10,
+	.miso_gpio = 9,
+	.reset_gpio = 24,
+	.spi_delay_us = 0,
+	.spi_mode = 0
+};
+
+/*
+ * When RST is asserted at certain points in time, then this
+ * triggers the TPM's security functions, in the case where
+ * multiple resets need to be asserted, there must be a wait
+ * of at least t_RSTIN between the resets
+ *
+ * In most cases this is not needed since RST is only being asserted
+ * once, ie for TPM initialization at the beginning of TFA.
+ */
+void tpm2_slb9670_reset_chip(struct gpio_spi_data *tpm_gpio_data)
+{
+	/*
+	 * since we don't know the value of the pin before it was init to 1
+	 * it is best to assume the state was 0, and account for that by
+	 * adding an initial RST inactive delay
+	 */
+	mdelay(t_RSTIN);
+	/* pull #RST pin to active low for 2us */
+	gpio_set_value(tpm_gpio_data->reset_gpio, 0);
+	udelay(t_WRST);
+	/* wait 60ms after warm reset before sending TPM commands */
+	gpio_set_value(tpm_gpio_data->reset_gpio, 1);
+	mdelay(t_RSTIN);
+}
+
+/*
+ * init GPIO pins for the Infineon slb9670 TPM
+ */
+void tpm2_slb9670_gpio_init(struct gpio_spi_data *tpm_gpio_data)
+{
+	gpio_set_value(tpm_gpio_data->cs_gpio, 1);
+	gpio_set_direction(tpm_gpio_data->cs_gpio, GPIO_DIR_OUT);
+
+	gpio_set_value(tpm_gpio_data->sclk_gpio, 0);
+	gpio_set_direction(tpm_gpio_data->sclk_gpio, GPIO_DIR_OUT);
+
+	gpio_set_value(tpm_gpio_data->mosi_gpio, 1);
+	gpio_set_direction(tpm_gpio_data->mosi_gpio, GPIO_DIR_OUT);
+
+	gpio_set_direction(tpm_gpio_data->miso_gpio, GPIO_DIR_IN);
+
+	gpio_set_value(tpm_gpio_data->reset_gpio, 1);
+	gpio_set_direction(tpm_gpio_data->reset_gpio, GPIO_DIR_OUT);
+}
diff --git a/include/drivers/tpm/tpm2_slb9670/slb9670_gpio.h b/include/drivers/tpm/tpm2_slb9670/slb9670_gpio.h
new file mode 100644
index 0000000..59ae125
--- /dev/null
+++ b/include/drivers/tpm/tpm2_slb9670/slb9670_gpio.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "drivers/gpio_spi.h"
+
+#ifndef SLB9670_GPIO_H
+#define SLB9670_GPIO_H
+
+void tpm2_slb9670_reset_chip(struct gpio_spi_data *tpm_gpio_data);
+
+void tpm2_slb9670_gpio_init(struct gpio_spi_data *tpm_gpio_data);
+
+#endif /* SLB9670_GPIO_H */