soc/intel/common/../cse: Create APIs for CSE device state transition

This patch ensures APIs that are responsible for CSE device state
transition between active to idle and vice-versa are available
publically for other modules/boot stages to consume.

BUG=b:200644229
TEST=Able to build and boot ADLRVP-P.

Change-Id: Ia480877822d343f2b4c9bf87b246812186d49ea3
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/57804
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Reviewed-by: Maulik V Vaghela <maulik.v.vaghela@intel.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
Subrata Banik 2021-09-25 15:02:37 +05:30
parent f72349d832
commit a219edb409
2 changed files with 83 additions and 0 deletions

View File

@ -27,6 +27,8 @@
#define HECI_SEND_TIMEOUT (5 * 1000)
/* Wait up to 5 sec for CSE to blurp a reply */
#define HECI_READ_TIMEOUT (5 * 1000)
/* Wait up to 1 ms for CSE CIP */
#define HECI_CIP_TIMEOUT 1000
#define SLOT_SIZE sizeof(uint32_t)
@ -34,6 +36,9 @@
#define MMIO_HOST_CSR 0x04
#define MMIO_CSE_CB_RW 0x08
#define MMIO_CSE_CSR 0x0c
#define MMIO_CSE_DEVIDLE 0x800
#define CSE_DEV_IDLE (1 << 2)
#define CSE_DEV_CIP (1 << 0)
#define CSR_IE (1 << 0)
#define CSR_IS (1 << 1)
@ -895,6 +900,73 @@ failure:
die("cse: Failed to trigger recovery mode(recovery subcode:%d)\n", reason);
}
static bool disable_cse_idle(void)
{
struct stopwatch sw;
uint32_t dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
dev_idle_ctrl &= ~CSE_DEV_IDLE;
write_bar(MMIO_CSE_DEVIDLE, dev_idle_ctrl);
stopwatch_init_usecs_expire(&sw, HECI_CIP_TIMEOUT);
do {
dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
if ((dev_idle_ctrl & CSE_DEV_CIP) == CSE_DEV_CIP)
return true;
udelay(HECI_DELAY);
} while (!stopwatch_expired(&sw));
return false;
}
static void enable_cse_idle(void)
{
uint32_t dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
dev_idle_ctrl |= CSE_DEV_IDLE;
write_bar(MMIO_CSE_DEVIDLE, dev_idle_ctrl);
}
enum cse_device_state get_cse_device_state(void)
{
uint32_t dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
if ((dev_idle_ctrl & CSE_DEV_IDLE) == CSE_DEV_IDLE)
return DEV_IDLE;
return DEV_ACTIVE;
}
static enum cse_device_state ensure_cse_active(void)
{
if (!disable_cse_idle())
return DEV_IDLE;
pci_or_config32(PCH_DEV_CSE, PCI_COMMAND, PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER);
return DEV_ACTIVE;
}
static void ensure_cse_idle(void)
{
enable_cse_idle();
pci_and_config32(PCH_DEV_CSE, PCI_COMMAND, ~(PCI_COMMAND_MEMORY |
PCI_COMMAND_MASTER));
}
bool set_cse_device_state(enum cse_device_state requested_state)
{
enum cse_device_state current_state = get_cse_device_state();
if (current_state == requested_state)
return true;
if (requested_state == DEV_ACTIVE)
return ensure_cse_active() == requested_state;
else
ensure_cse_idle();
return true;
}
#if ENV_RAMSTAGE
static void update_sec_bar(struct device *dev)

View File

@ -281,4 +281,15 @@ void cse_board_reset(void);
/* Trigger vboot recovery mode on a CSE error */
void cse_trigger_vboot_recovery(enum csme_failure_reason reason);
enum cse_device_state {
DEV_IDLE,
DEV_ACTIVE,
};
/* Function to get the current CSE device state as per `cse_device_state` */
enum cse_device_state get_cse_device_state(void);
/* Function that put the CSE into desired state based on `requested_state` */
bool set_cse_device_state(enum cse_device_state requested_state);
#endif // SOC_INTEL_COMMON_CSE_H