aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/imc.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/hw/imc.c b/hw/imc.c
index df29e6d..5bc59b5 100644
--- a/hw/imc.c
+++ b/hw/imc.c
@@ -20,6 +20,7 @@
#include <chip.h>
#include <libxz/xz.h>
#include <device.h>
+#include <p9_stop_api.H>
/*
* Nest IMC PMU names along with their bit values as represented in the
@@ -633,6 +634,9 @@ static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr, uint64_t cpu
{
struct cpu_thread *c = find_cpu_by_pir(cpu_pir);
int port_id, phys_core_id;
+ struct proc_chip *chip = get_chip(c->chip_id);
+ int ret;
+ uint32_t scoms;
switch (type) {
case OPAL_IMC_COUNTERS_NEST:
@@ -665,6 +669,8 @@ static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr, uint64_t cpu
*
* HTM Scom: scom to enable counter data movement to memory.
*/
+
+
if (xscom_write(c->chip_id,
XSCOM_ADDR_P9_EP(phys_core_id,
pdbar_scom_index[port_id]),
@@ -673,6 +679,40 @@ static int64_t opal_imc_counters_init(uint32_t type, uint64_t addr, uint64_t cpu
return OPAL_HARDWARE;
}
+ if (has_deep_states) {
+ if ((wakeup_engine_state == WAKEUP_ENGINE_PRESENT)) {
+ prlog(PR_INFO, "Configuring stopapi for IMC\n");
+ scoms = XSCOM_ADDR_P9_EP(phys_core_id,pdbar_scom_index[port_id]);
+ ret = p9_stop_save_scom(( void *)chip->homer_base,scoms,
+ (u64)(CORE_IMC_PDBAR_MASK & addr),
+ P9_STOP_SCOM_REPLACE,
+ P9_STOP_SECTION_EQ_SCOM);
+ if ( ret ) {
+ prerror("IMC pdbar stopapi ret = %d, scoms = %x (core id = %x)\n", ret, scoms, phys_core_id);
+ if ( ret != STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED )
+ wakeup_engine_state = WAKEUP_ENGINE_FAILED;
+ else
+ prerror("SCOM entries are full\n");
+ return OPAL_HARDWARE;
+ }
+ scoms = XSCOM_ADDR_P9_EC(phys_core_id,CORE_IMC_EVENT_MASK_ADDR);
+ ret = p9_stop_save_scom(( void *)chip->homer_base,scoms,
+ (u64)CORE_IMC_EVENT_MASK, P9_STOP_SCOM_REPLACE,
+ P9_STOP_SECTION_CORE_SCOM);
+ if ( ret ) {
+ prerror("IMC event_mask stopapi ret = %d, scoms = %x (core id = %x)\n", ret, scoms, phys_core_id);
+ if ( ret != STOP_SAVE_SCOM_ENTRY_UPDATE_FAILED )
+ wakeup_engine_state = WAKEUP_ENGINE_FAILED;
+ else
+ prerror("SCOM entries are full\n");
+ return OPAL_HARDWARE;
+ }
+ } else {
+ prerror("IMC: Wakeup engine in error state!");
+ return OPAL_HARDWARE;
+ }
+ }
+
if (xscom_write(c->chip_id,
XSCOM_ADDR_P9_EC(phys_core_id,
CORE_IMC_EVENT_MASK_ADDR),