1 /*
2 * Copyright (c) 2025, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <drivers/delay_timer.h>
8 #include <drivers/gpio.h>
9 #include <drivers/tpm/tpm2_slb9670/slb9670_gpio.h>
10
11 /*
12 * Infineon SLB9670 Chip Reset Parameters
13 */
14 #define t_WRST 2 /* Warm Reset Time (us) */
15 #define t_RSTIN 60 /* Reset Inactive Time (ms) */
16
17 /*
18 * RPi3 GPIO pin configuration for TPM via bit-bang SPI
19 * References: https://pinout.xyz/pinout/spi
20 * - docs/design_documents/measured_boot_dtpm_poc.rst
21 */
22 const struct gpio_spi_data tpm_rpi3_gpio_data = {
23 .cs_gpio = 7,
24 .sclk_gpio = 11,
25 .mosi_gpio = 10,
26 .miso_gpio = 9,
27 .reset_gpio = 24,
28 .spi_delay_us = 0,
29 .spi_mode = 0
30 };
31
32 /*
33 * When RST is asserted at certain points in time, then this
34 * triggers the TPM's security functions, in the case where
35 * multiple resets need to be asserted, there must be a wait
36 * of at least t_RSTIN between the resets
37 *
38 * In most cases this is not needed since RST is only being asserted
39 * once, ie for TPM initialization at the beginning of TFA.
40 */
tpm2_slb9670_reset_chip(struct gpio_spi_data * tpm_gpio_data)41 void tpm2_slb9670_reset_chip(struct gpio_spi_data *tpm_gpio_data)
42 {
43 /*
44 * since we don't know the value of the pin before it was init to 1
45 * it is best to assume the state was 0, and account for that by
46 * adding an initial RST inactive delay
47 */
48 mdelay(t_RSTIN);
49 /* pull #RST pin to active low for 2us */
50 gpio_set_value(tpm_gpio_data->reset_gpio, 0);
51 udelay(t_WRST);
52 /* wait 60ms after warm reset before sending TPM commands */
53 gpio_set_value(tpm_gpio_data->reset_gpio, 1);
54 mdelay(t_RSTIN);
55 }
56
57 /*
58 * init GPIO pins for the Infineon slb9670 TPM
59 */
tpm2_slb9670_gpio_init(struct gpio_spi_data * tpm_gpio_data)60 void tpm2_slb9670_gpio_init(struct gpio_spi_data *tpm_gpio_data)
61 {
62 gpio_set_value(tpm_gpio_data->cs_gpio, 1);
63 gpio_set_direction(tpm_gpio_data->cs_gpio, GPIO_DIR_OUT);
64
65 gpio_set_value(tpm_gpio_data->sclk_gpio, 0);
66 gpio_set_direction(tpm_gpio_data->sclk_gpio, GPIO_DIR_OUT);
67
68 gpio_set_value(tpm_gpio_data->mosi_gpio, 1);
69 gpio_set_direction(tpm_gpio_data->mosi_gpio, GPIO_DIR_OUT);
70
71 gpio_set_direction(tpm_gpio_data->miso_gpio, GPIO_DIR_IN);
72
73 gpio_set_value(tpm_gpio_data->reset_gpio, 1);
74 gpio_set_direction(tpm_gpio_data->reset_gpio, GPIO_DIR_OUT);
75 }
76