soc/intel/common/../cse: Allow D0i3 enable/disable for all CSE devices
This patch ensures to pass cse device function number as argument for `set_cse_device_state()` to allow coreboot to perform enable/disable of D0i3 bit for all CSE devices to put the CSE device to Idle state or Active state. BUG=b:200644229 TEST= Able to build and boot ADLRVP where `set_cse_device_state()` is able to put the CSE device toidle state or active state based on `devfn` as argument. Change-Id: Ibe819e690c47453eaee02e435525a25b576232b5 Signed-off-by: Subrata Banik <subrata.banik@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/58039 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
This commit is contained in:
parent
db16ac9578
commit
c6e2552ce6
3 changed files with 41 additions and 41 deletions
|
@ -1,5 +1,7 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#define __SIMPLE_DEVICE__
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <commonlib/helpers.h>
|
#include <commonlib/helpers.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
@ -65,11 +67,11 @@
|
||||||
#define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START)
|
#define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START)
|
||||||
|
|
||||||
/* Get HECI BAR 0 from PCI configuration space */
|
/* Get HECI BAR 0 from PCI configuration space */
|
||||||
static uintptr_t get_cse_bar(void)
|
static uintptr_t get_cse_bar(pci_devfn_t dev)
|
||||||
{
|
{
|
||||||
uintptr_t bar;
|
uintptr_t bar;
|
||||||
|
|
||||||
bar = pci_read_config32(PCH_DEV_CSE, PCI_BASE_ADDRESS_0);
|
bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
|
||||||
assert(bar != 0);
|
assert(bar != 0);
|
||||||
/*
|
/*
|
||||||
* Bits 31-12 are the base address as per EDS for SPI,
|
* Bits 31-12 are the base address as per EDS for SPI,
|
||||||
|
@ -85,15 +87,12 @@ static uintptr_t get_cse_bar(void)
|
||||||
*/
|
*/
|
||||||
void heci_init(uintptr_t tempbar)
|
void heci_init(uintptr_t tempbar)
|
||||||
{
|
{
|
||||||
#if defined(__SIMPLE_DEVICE__)
|
|
||||||
pci_devfn_t dev = PCH_DEV_CSE;
|
pci_devfn_t dev = PCH_DEV_CSE;
|
||||||
#else
|
|
||||||
struct device *dev = PCH_DEV_CSE;
|
|
||||||
#endif
|
|
||||||
u16 pcireg;
|
u16 pcireg;
|
||||||
|
|
||||||
/* Assume it is already initialized, nothing else to do */
|
/* Assume it is already initialized, nothing else to do */
|
||||||
if (get_cse_bar())
|
if (get_cse_bar(dev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Use default pre-ram bar */
|
/* Use default pre-ram bar */
|
||||||
|
@ -114,29 +113,29 @@ void heci_init(uintptr_t tempbar)
|
||||||
pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
|
pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t read_bar(uint32_t offset)
|
static uint32_t read_bar(pci_devfn_t dev, uint32_t offset)
|
||||||
{
|
{
|
||||||
return read32p(get_cse_bar() + offset);
|
return read32p(get_cse_bar(dev) + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_bar(uint32_t offset, uint32_t val)
|
static void write_bar(pci_devfn_t dev, uint32_t offset, uint32_t val)
|
||||||
{
|
{
|
||||||
return write32p(get_cse_bar() + offset, val);
|
return write32p(get_cse_bar(dev) + offset, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t read_cse_csr(void)
|
static uint32_t read_cse_csr(void)
|
||||||
{
|
{
|
||||||
return read_bar(MMIO_CSE_CSR);
|
return read_bar(PCH_DEV_CSE, MMIO_CSE_CSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t read_host_csr(void)
|
static uint32_t read_host_csr(void)
|
||||||
{
|
{
|
||||||
return read_bar(MMIO_HOST_CSR);
|
return read_bar(PCH_DEV_CSE, MMIO_HOST_CSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_host_csr(uint32_t data)
|
static void write_host_csr(uint32_t data)
|
||||||
{
|
{
|
||||||
write_bar(MMIO_HOST_CSR, data);
|
write_bar(PCH_DEV_CSE, MMIO_HOST_CSR, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t filled_slots(uint32_t data)
|
static size_t filled_slots(uint32_t data)
|
||||||
|
@ -170,12 +169,12 @@ static void clear_int(void)
|
||||||
|
|
||||||
static uint32_t read_slot(void)
|
static uint32_t read_slot(void)
|
||||||
{
|
{
|
||||||
return read_bar(MMIO_CSE_CB_RW);
|
return read_bar(PCH_DEV_CSE, MMIO_CSE_CB_RW);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_slot(uint32_t val)
|
static void write_slot(uint32_t val)
|
||||||
{
|
{
|
||||||
write_bar(MMIO_CSE_CB_WW, val);
|
write_bar(PCH_DEV_CSE, MMIO_CSE_CB_WW, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wait_write_slots(size_t cnt)
|
static int wait_write_slots(size_t cnt)
|
||||||
|
@ -887,16 +886,16 @@ failure:
|
||||||
die("cse: Failed to trigger recovery mode(recovery subcode:%d)\n", reason);
|
die("cse: Failed to trigger recovery mode(recovery subcode:%d)\n", reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool disable_cse_idle(void)
|
static bool disable_cse_idle(pci_devfn_t dev)
|
||||||
{
|
{
|
||||||
struct stopwatch sw;
|
struct stopwatch sw;
|
||||||
uint32_t dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
|
uint32_t dev_idle_ctrl = read_bar(dev, MMIO_CSE_DEVIDLE);
|
||||||
dev_idle_ctrl &= ~CSE_DEV_IDLE;
|
dev_idle_ctrl &= ~CSE_DEV_IDLE;
|
||||||
write_bar(MMIO_CSE_DEVIDLE, dev_idle_ctrl);
|
write_bar(dev, MMIO_CSE_DEVIDLE, dev_idle_ctrl);
|
||||||
|
|
||||||
stopwatch_init_usecs_expire(&sw, HECI_CIP_TIMEOUT_US);
|
stopwatch_init_usecs_expire(&sw, HECI_CIP_TIMEOUT_US);
|
||||||
do {
|
do {
|
||||||
dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
|
dev_idle_ctrl = read_bar(dev, MMIO_CSE_DEVIDLE);
|
||||||
if ((dev_idle_ctrl & CSE_DEV_CIP) == CSE_DEV_CIP)
|
if ((dev_idle_ctrl & CSE_DEV_CIP) == CSE_DEV_CIP)
|
||||||
return true;
|
return true;
|
||||||
udelay(HECI_DELAY_US);
|
udelay(HECI_DELAY_US);
|
||||||
|
@ -905,51 +904,51 @@ static bool disable_cse_idle(void)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enable_cse_idle(void)
|
static void enable_cse_idle(pci_devfn_t dev)
|
||||||
{
|
{
|
||||||
uint32_t dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
|
uint32_t dev_idle_ctrl = read_bar(dev, MMIO_CSE_DEVIDLE);
|
||||||
dev_idle_ctrl |= CSE_DEV_IDLE;
|
dev_idle_ctrl |= CSE_DEV_IDLE;
|
||||||
write_bar(MMIO_CSE_DEVIDLE, dev_idle_ctrl);
|
write_bar(dev, MMIO_CSE_DEVIDLE, dev_idle_ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum cse_device_state get_cse_device_state(void)
|
enum cse_device_state get_cse_device_state(unsigned int devfn)
|
||||||
{
|
{
|
||||||
uint32_t dev_idle_ctrl = read_bar(MMIO_CSE_DEVIDLE);
|
pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
|
||||||
|
uint32_t dev_idle_ctrl = read_bar(dev, MMIO_CSE_DEVIDLE);
|
||||||
if ((dev_idle_ctrl & CSE_DEV_IDLE) == CSE_DEV_IDLE)
|
if ((dev_idle_ctrl & CSE_DEV_IDLE) == CSE_DEV_IDLE)
|
||||||
return DEV_IDLE;
|
return DEV_IDLE;
|
||||||
|
|
||||||
return DEV_ACTIVE;
|
return DEV_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum cse_device_state ensure_cse_active(void)
|
static enum cse_device_state ensure_cse_active(pci_devfn_t dev)
|
||||||
{
|
{
|
||||||
if (!disable_cse_idle())
|
if (!disable_cse_idle(dev))
|
||||||
return DEV_IDLE;
|
return DEV_IDLE;
|
||||||
pci_or_config32(PCH_DEV_CSE, PCI_COMMAND, PCI_COMMAND_MEMORY |
|
pci_or_config32(dev, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
|
||||||
PCI_COMMAND_MASTER);
|
|
||||||
|
|
||||||
return DEV_ACTIVE;
|
return DEV_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ensure_cse_idle(void)
|
static void ensure_cse_idle(pci_devfn_t dev)
|
||||||
{
|
{
|
||||||
enable_cse_idle();
|
enable_cse_idle(dev);
|
||||||
|
|
||||||
pci_and_config32(PCH_DEV_CSE, PCI_COMMAND, ~(PCI_COMMAND_MEMORY |
|
pci_and_config32(dev, PCI_COMMAND, ~(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER));
|
||||||
PCI_COMMAND_MASTER));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set_cse_device_state(enum cse_device_state requested_state)
|
bool set_cse_device_state(unsigned int devfn, enum cse_device_state requested_state)
|
||||||
{
|
{
|
||||||
enum cse_device_state current_state = get_cse_device_state();
|
enum cse_device_state current_state = get_cse_device_state(devfn);
|
||||||
|
pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
|
||||||
|
|
||||||
if (current_state == requested_state)
|
if (current_state == requested_state)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (requested_state == DEV_ACTIVE)
|
if (requested_state == DEV_ACTIVE)
|
||||||
return ensure_cse_active() == requested_state;
|
return ensure_cse_active(dev) == requested_state;
|
||||||
else
|
else
|
||||||
ensure_cse_idle();
|
ensure_cse_idle(dev);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <intelblocks/pmc_ipc.h>
|
#include <intelblocks/pmc_ipc.h>
|
||||||
#include <security/vboot/vboot_common.h>
|
#include <security/vboot/vboot_common.h>
|
||||||
#include <soc/intel/common/reset.h>
|
#include <soc/intel/common/reset.h>
|
||||||
|
#include <soc/pci_devs.h>
|
||||||
#include <timestamp.h>
|
#include <timestamp.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
|
|
||||||
|
@ -174,13 +175,13 @@ static void handle_cse_eop_result(enum cse_eop_result result)
|
||||||
|
|
||||||
static void set_cse_end_of_post(void *unused)
|
static void set_cse_end_of_post(void *unused)
|
||||||
{
|
{
|
||||||
set_cse_device_state(DEV_ACTIVE);
|
set_cse_device_state(PCH_DEVFN_CSE, DEV_ACTIVE);
|
||||||
|
|
||||||
timestamp_add_now(TS_ME_BEFORE_END_OF_POST);
|
timestamp_add_now(TS_ME_BEFORE_END_OF_POST);
|
||||||
handle_cse_eop_result(cse_send_eop());
|
handle_cse_eop_result(cse_send_eop());
|
||||||
timestamp_add_now(TS_ME_AFTER_END_OF_POST);
|
timestamp_add_now(TS_ME_AFTER_END_OF_POST);
|
||||||
|
|
||||||
set_cse_device_state(DEV_IDLE);
|
set_cse_device_state(PCH_DEVFN_CSE, DEV_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -287,9 +287,9 @@ enum cse_device_state {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function to get the current CSE device state as per `cse_device_state` */
|
/* Function to get the current CSE device state as per `cse_device_state` */
|
||||||
enum cse_device_state get_cse_device_state(void);
|
enum cse_device_state get_cse_device_state(unsigned int devfn);
|
||||||
|
|
||||||
/* Function that put the CSE into desired state based on `requested_state` */
|
/* Function that put the CSE into desired state based on `requested_state` */
|
||||||
bool set_cse_device_state(enum cse_device_state requested_state);
|
bool set_cse_device_state(unsigned int devfn, enum cse_device_state requested_state);
|
||||||
|
|
||||||
#endif // SOC_INTEL_COMMON_CSE_H
|
#endif // SOC_INTEL_COMMON_CSE_H
|
||||||
|
|
Loading…
Reference in a new issue