aboutsummaryrefslogtreecommitdiff
path: root/hw/imc.c
diff options
context:
space:
mode:
authorAkshay Adiga <akshay.adiga@linux.vnet.ibm.com>2018-01-04 16:58:06 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2018-01-14 21:05:51 -0600
commit7def6cdac27f407bbcb15e83699abdb33078447e (patch)
tree235129c6b701b335beb945456c243932d6f956ac /hw/imc.c
parentc613c2fb9b826b0eff2d28c23f3ec47a2ab3c410 (diff)
downloadskiboot-7def6cdac27f407bbcb15e83699abdb33078447e.zip
skiboot-7def6cdac27f407bbcb15e83699abdb33078447e.tar.gz
skiboot-7def6cdac27f407bbcb15e83699abdb33078447e.tar.bz2
SLW: Add p9_stop_api calls for IMC
Add p9_stop_api for EVENT_MASK and PDBAR scoms. These scoms are lost on wakeup from stop11. Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> Reviewed-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/imc.c')
-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),