diff options
author | Scott <scollyer@chromium.org> | 2016-07-21 11:08:11 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-03 19:40:55 -0700 |
commit | d67f3aa1f60ff9abd4f03c58a103ab4eecf99e7f (patch) | |
tree | 3269a2071be1819469005dacd61a96bf19b7c276 | |
parent | 96e05799536c264b63d11604429ed760a4e019d2 (diff) | |
download | chrome-ec-d67f3aa1f60ff9abd4f03c58a103ab4eecf99e7f.tar.gz |
Cr50: Sample slave configuration pins at POR
There is just one version of Cr50 firmware for all boards
that it's used on. However, on some boards the AP communicates
to the TPM via a SPI interface (i.e. Kevin) and on others, the
AP communicates via an I2C interface (i.e. Reef). In order to
dynamically discover which interface to configure, there are
strapping resistors added to the board which enables the Cr50
to detect which configuration to implement.
This CL is a first pass and is only looking at DIOA1 which is
pulled high for SPI and pulled low for I2C configurations.
The strapping resistor should be read when the AP is in reset
prior to it attempting to drive any of the lines used for
strapping. To ensure this condition is met, Cr50 will only
check the strapping options following a POR (power on reset).
Once the configuration type is discovered, a 'long_life'
register is used to hold the result so that the result can
always be available. The long_life register contents remain
unchanged until a subsequent power down event.
BRANCH=none
BUG=chrome-os-partner:50728
TEST=manual
Tested on Kevin and Reef. Verfifed by reading the stored value
that the SPI configuraiton is detected for Kevin and the I2C
interface is detected on Reef. In addition, verified on Kevin
that the Cr50 FW version is correctly reported to the AP which
means that TPM register reads via the slave SPI are functioning.
Change-Id: Ibd7624ad8e3b4126f6346dce0bc72f62a3cc6d18
Signed-off-by: Scott <scollyer@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/363014
Commit-Ready: Scott Collyer <scollyer@chromium.org>
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
-rw-r--r-- | board/cr50/board.c | 37 | ||||
-rw-r--r-- | board/cr50/gpio.inc | 4 | ||||
-rw-r--r-- | chip/g/sps.c | 8 | ||||
-rw-r--r-- | chip/g/system.c | 9 | ||||
-rw-r--r-- | include/system.h | 20 |
5 files changed, 78 insertions, 0 deletions
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 */ |