xref: /rk3399_ARM-atf/drivers/tpm/tpm2_slb9670/slb9670_gpio.c (revision 2d3b44e3073e8d6ec49dde45ec353d6f41290917)
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  */
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  */
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