diff --git a/board/cr50/board.c b/board/cr50/board.c index ba8862119b..bcb5c6dae7 100644 --- a/board/cr50/board.c +++ b/board/cr50/board.c @@ -48,6 +48,9 @@ uint32_t nvmem_user_sizes[NVMEM_NUM_USERS] = { NVMEM_CR50_SIZE }; +/* Board specific configuration settings */ +static uint32_t board_properties; + /* * There's no way to trigger on both rising and falling edges, so force a * compiler error if we try. The workaround is to use the pinmux to connect @@ -499,3 +502,37 @@ void board_update_device_state(enum device_type device) hook_call_deferred(device_states[device].deferred, 50); } } + +static void detect_slave_config(void) +{ + uint32_t properties = 0; + + /* Check for power on reset */ + if (system_get_reset_flags() & RESET_FLAG_POWER_ON) { + /* Read DIOA1 strap pin */ + if (gpio_get_level(GPIO_STRAP0)) + /* Strap is pulled high -> Kevin SPI TPM option */ + properties |= BOARD_SLAVE_CONFIG_SPI; + else + /* Strap is low -> Reef I2C TPM option */ + properties |= BOARD_SLAVE_CONFIG_I2C; + /* Write enable bit for LONG_LIFE_SCRATCH1 register */ + GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG1, 1); + /* Save type in LONG_LIFE register */ + GREG32(PMU, LONG_LIFE_SCRATCH1) = properties; + /* Clear enable bit of LONG_LIFE_SCRATCH1 register */ + GWRITE_FIELD(PMU, LONG_LIFE_SCRATCH_WR_EN, REG1, 0); + } else { + /* Not a power on reset, so can read what was discovered */ + properties = GREG32(PMU, LONG_LIFE_SCRATCH1); + } + /* Save this configuration setting */ + board_properties = properties; +} +/* Need this hook to run before the default hook level */ +DECLARE_HOOK(HOOK_INIT, detect_slave_config, HOOK_PRIO_DEFAULT - 1); + +uint32_t system_board_properties_callback(void) +{ + return board_properties; +} diff --git a/board/cr50/gpio.inc b/board/cr50/gpio.inc index a6dafa8e94..8234e80017 100644 --- a/board/cr50/gpio.inc +++ b/board/cr50/gpio.inc @@ -58,6 +58,9 @@ GPIO(SPI_CS_L, PIN(0, 9), GPIO_INPUT) /* Control the load switch powering the INA 3.3V rail */ GPIO(EN_PP3300_INA_L, PIN(1, 9), GPIO_ODR_HIGH) +/* GPIOs used for Cr50 strapping options */ +GPIO(STRAP0, PIN(0, 10), GPIO_INPUT) + /* Unimplemented signals which we need to emulate for now */ /* TODO(wfrichar): Half the boards don't use this signal. Take it out. */ UNIMPLEMENTED(ENTERING_RW) @@ -82,6 +85,7 @@ PINMUX(GPIO(SYS_RST_L_IN), M0, DIO_WAKE_FALLING) PINMUX(GPIO(SYS_RST_L_OUT), M0, DIO_INPUT) PINMUX(GPIO(CCD_MODE_L), M1, DIO_INPUT) PINMUX(GPIO(BATT_PRES), M2, 0) +PINMUX(GPIO(STRAP0), A1, DIO_INPUT) /* UARTs */ PINMUX(FUNC(UART0_TX), A0, DIO_OUTPUT) /* Cr50 console */ diff --git a/chip/g/sps.c b/chip/g/sps.c index 6d21b06358..0ce1d6be41 100644 --- a/chip/g/sps.c +++ b/chip/g/sps.c @@ -9,6 +9,7 @@ #include "pmu.h" #include "registers.h" #include "sps.h" +#include "system.h" #include "task.h" #include "timer.h" #include "watchdog.h" @@ -238,6 +239,13 @@ int sps_unregister_rx_handler(void) static void sps_init(void) { + /* + * Check to see if slave SPI interface is required by the board before + * initializing it. If SPI option is not set, then just return. + */ + if (!(system_get_board_properties() & BOARD_SLAVE_CONFIG_SPI)) + return; + pmu_clock_en(PERIPH_SPS); /* The pinmux connections are preset, but we have to set IN/OUT */ diff --git a/chip/g/system.c b/chip/g/system.c index 80b55601d9..7071e2680b 100644 --- a/chip/g/system.c +++ b/chip/g/system.c @@ -352,3 +352,12 @@ int system_process_retry_counter(void) } #endif +uint32_t system_get_board_properties(void) +{ + uint32_t properties = 0; + +#ifdef BOARD_CR50 + properties = system_board_properties_callback(); +#endif + return properties; +} diff --git a/include/system.h b/include/system.h index 8d792123ff..60ec6b1072 100644 --- a/include/system.h +++ b/include/system.h @@ -466,4 +466,24 @@ int system_is_reboot_warm(void); */ int system_process_retry_counter(void); +/* Board properties options */ +#define BOARD_SLAVE_CONFIG_SPI (1 << 0) /* Slave SPI interface */ +#define BOARD_SLAVE_CONFIG_I2C (1 << 1) /* Slave I2C interface */ +/** + * Get board properites + * + * + * @return uint32_t bit field where a set bit indicates option exists + */ +uint32_t system_get_board_properties(void); + +/** + * API for board specific version of system_get_board_properties + * + * This function must be in the board's board.c file + * + * @return uint32_t bit field where a set bit indicates option exists + */ +uint32_t system_board_properties_callback(void); + #endif /* __CROS_EC_SYSTEM_H */