xref: /rk3399_ARM-atf/drivers/tpm/tpm2_slb9670/slb9670_gpio.c (revision 30a60389204f9ec44c890854e62ec1e0506cb9b9)
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_config tpm_rpi3_gpio_data = { .cs_gpio = 7,
23 						    .sclk_gpio = 11,
24 						    .mosi_gpio = 10,
25 						    .miso_gpio = 9,
26 						    .reset_gpio = 24,
27 						    .spi_mode = 0,
28 						    .spi_max_clock = 1000000 };
29 
30 /*
31  * When RST is asserted at certain points in time, then this
32  * triggers the TPM's security functions, in the case where
33  * multiple resets need to be asserted, there must be a wait
34  * of at least t_RSTIN between the resets
35  *
36  * In most cases this is not needed since RST is only being asserted
37  * once, ie for TPM initialization at the beginning of TFA.
38  */
39 void tpm2_slb9670_reset_chip(const struct gpio_spi_config *tpm_gpio_data)
40 {
41 	/*
42 	 * since we don't know the value of the pin before it was init to 1
43 	 * it is best to assume the state was 0, and account for that by
44 	 * adding an initial RST inactive delay
45 	 */
46 	mdelay(t_RSTIN);
47 	/* pull #RST pin to active low for 2us */
48 	gpio_set_value(tpm_gpio_data->reset_gpio, 0);
49 	udelay(t_WRST);
50 	/* wait 60ms after warm reset before sending TPM commands */
51 	gpio_set_value(tpm_gpio_data->reset_gpio, 1);
52 	mdelay(t_RSTIN);
53 }
54 
55 /*
56  * init GPIO pins for the Infineon slb9670 TPM
57  */
58 void tpm2_slb9670_gpio_init(const struct gpio_spi_config *tpm_gpio_data)
59 {
60 	gpio_set_value(tpm_gpio_data->reset_gpio, 1);
61 	gpio_set_direction(tpm_gpio_data->reset_gpio, GPIO_DIR_OUT);
62 }
63 
64 const struct gpio_spi_config *tpm2_slb9670_get_config(void)
65 {
66 	return &tpm_rpi3_gpio_data;
67 }
68