mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-07 16:11:43 +00:00
Cr50: I2CS TPM: Prevent sleep when I2CS is active
Similar to the TPM SPI interface, added code to disable sleep an I2CS interrupt is received. Enabling sleep follwoing a 1 second delay when the TPM fifo register has been read by the host. The I2CS TPM layer doesn't know when a command has finished, but the one second delay is more than enough delay since sleep will be disabled again when the next I2CS interrupt is received. BRANCH=none BUG=chrome-os-partner:40397 TEST=manual Tested without these changes first. Shortened sleep delay to 30 seconds, and disconnected suzyq. Waited 30 seconds then issued the command on the AP console: tpmc read 0x1007 0xa [ 59.796813] tpm tpm0: tpm_transmit: tpm_send: error -16 ERROR: write failure to TPM device: Device or resource busy In addition, using logic analyzer verifed that there was activity on SDA/SCL but no response from Cr50. With this CL in place, ran the test and got the following: tpmc read 0x1007 0xa 2 0 1 0 1 0 0 0 0 4f With the logic analyzer I was able to confirm that there was no activity from the host on the I2CS bus until the command was issued. Change-Id: If07573ae8f72b983bca57979d53c22660b91b95e Signed-off-by: Scott <scollyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/387910 Commit-Ready: Scott Collyer <scollyer@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Mary Ruthven <mruthven@chromium.org>
This commit is contained in:
@@ -765,6 +765,14 @@ void i2cs_set_pinmux(void)
|
||||
*/
|
||||
GWRITE_FIELD(PINMUX, DIOA1_CTL, PU, 1);
|
||||
GWRITE_FIELD(PINMUX, DIOA9_CTL, PU, 1);
|
||||
/* TODO(scollyer): Do we need to add wake on SCL activity here? */
|
||||
|
||||
/* Allow I2CS_SCL to wake from sleep */
|
||||
GWRITE_FIELD(PINMUX, EXITEDGE0, DIOA9, 1); /* edge sensitive */
|
||||
GWRITE_FIELD(PINMUX, EXITINV0, DIOA9, 1); /* wake on low */
|
||||
GWRITE_FIELD(PINMUX, EXITEN0, DIOA9, 1); /* enable powerdown exit */
|
||||
|
||||
/* Allow I2CS_SDA to wake from sleep */
|
||||
GWRITE_FIELD(PINMUX, EXITEDGE0, DIOA1, 1); /* edge sensitive */
|
||||
GWRITE_FIELD(PINMUX, EXITINV0, DIOA1, 1); /* wake on low */
|
||||
GWRITE_FIELD(PINMUX, EXITEN0, DIOA1, 1); /* enable powerdown exit */
|
||||
}
|
||||
|
||||
@@ -122,6 +122,9 @@ static void _i2cs_write_complete_int(void)
|
||||
/* Reset the IRQ condition. */
|
||||
GWRITE_FIELD(I2CS, INT_STATE, INTR_WRITE_COMPLETE, 1);
|
||||
|
||||
/* We're receiving some bytes, so don't sleep */
|
||||
disable_sleep(SLEEP_MASK_I2C_SLAVE);
|
||||
|
||||
if (write_complete_handler_) {
|
||||
uint16_t bytes_written;
|
||||
uint16_t bytes_processed;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "hooks.h"
|
||||
#include "i2cs.h"
|
||||
#include "registers.h"
|
||||
#include "system.h"
|
||||
#include "tpm_registers.h"
|
||||
|
||||
/*
|
||||
@@ -129,6 +130,14 @@ static void process_read_access(uint16_t reg_size,
|
||||
tpm_register_get(tpm_reg, data, reg_size);
|
||||
/* Transfer TPM fifo data to the I2CS HW fifo */
|
||||
i2cs_post_read_fill_fifo(data, reg_size);
|
||||
|
||||
/*
|
||||
* Could be the end of a TPM trasaction. Set sleep to be reenabled in 1
|
||||
* second. If this is not the end of a TPM response, then sleep will be
|
||||
* disabled again in the next I2CS interrupt.
|
||||
*/
|
||||
delay_sleep_by(1 * SECOND);
|
||||
enable_sleep(SLEEP_MASK_I2C_SLAVE);
|
||||
}
|
||||
|
||||
static void process_write_access(uint16_t reg_size, uint16_t tpm_reg,
|
||||
|
||||
Reference in New Issue
Block a user