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