[8/9] SCOM restore for DARN and XIVE

Message ID 1515065286-8656-9-git-send-email-akshay.adiga@linux.vnet.ibm.com
State Accepted
Headers show
Series
  • p9_stop_api error handling
Related show

Commit Message

Akshay Adiga Jan. 4, 2018, 11:28 a.m.
While waking up from stop11, we want NCU_DARN_BAR to have enable bit set.
Without this stop_api call, the value restored is without enable bit set.
We loose NCU_SPEC_BAR when the quad goes into stop11, stop_api will
restore while waking up from stop11.

Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
---
 hw/nx.c           | 42 ++++++++++++++++++++++++++++++++++++++++++
 hw/slw.c          |  6 ++++--
 hw/xive.c         | 30 ++++++++++++++++++++++++++++++
 include/skiboot.h |  4 ++++
 4 files changed, 80 insertions(+), 2 deletions(-)

Patch

diff --git a/hw/nx.c b/hw/nx.c
index f6e823f6..0f6ff04d 100644
--- a/hw/nx.c
+++ b/hw/nx.c
@@ -24,6 +24,7 @@ 
 #include <chip.h>
 #include <xscom-p9-regs.h>
 #include <phys-map.h>
+#include <p9_stop_api.H>
 
 static void p9_darn_init(void)
 {
@@ -61,6 +62,47 @@  static void p9_darn_init(void)
 						P9X_EX_NCU_DARN_BAR);
 			xscom_write(chip->id, addr,
 				    bar | P9X_EX_NCU_DARN_BAR_EN);
+
+		}
+	}
+}
+
+void nx_p9_rng_late_init(void)
+{
+	struct cpu_thread *c;
+	uint64_t rc;
+
+	if (proc_gen != proc_gen_p9)
+		return;
+	if (chip_quirk(QUIRK_NO_RNG))
+		return;
+
+	prlog(PR_NOTICE, "SLW: Configuring self-restore for P9X_EX_NCU_DARN_BAR\n");
+	for_each_present_cpu(c) {
+		if(cpu_is_thread0(c)) {
+			struct proc_chip *chip = get_chip(c->chip_id);
+			uint64_t addr, bar;
+
+			phys_map_get(chip->id, NX_RNG, 0, &bar, NULL);
+			addr = XSCOM_ADDR_P9_EX(pir_to_core_id(c->pir),
+					P9X_EX_NCU_DARN_BAR);
+			/* Bail out if wakeup engine has already failed */
+			if ( wakeup_engine_state != WAKEUP_ENGINE_PRESENT) {
+				prlog(PR_ERR,"DARN BAR p9_stop_api fail detected\n");
+				break;
+			}
+			rc = p9_stop_save_scom((void *)chip->homer_base,
+					addr, bar | P9X_EX_NCU_DARN_BAR_EN,
+					P9_STOP_SCOM_REPLACE,
+					P9_STOP_SECTION_EQ_SCOM);
+			if (rc) {
+				prlog(PR_ERR,
+				"p9_stop_api for DARN_BAR failed rc= %lld",
+				rc);
+				prlog(PR_ERR, "Disabling deep stop states\n");
+				wakeup_engine_state = WAKEUP_ENGINE_FAILED;
+				break;
+			}
 		}
 	}
 }
diff --git a/hw/slw.c b/hw/slw.c
index e461030c..ee02124b 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -907,9 +907,11 @@  void add_cpu_idle_state_properties(void)
 					has_deep_states = true;
 				}
 			}
-
-			if ((wakeup_engine_state == WAKEUP_ENGINE_PRESENT) && has_deep_states)
+			if ((wakeup_engine_state == WAKEUP_ENGINE_PRESENT) && has_deep_states) {
 				slw_late_init_p9(chip);
+				xive_late_init();
+				nx_p9_rng_late_init();
+			}
 			if (wakeup_engine_state != WAKEUP_ENGINE_PRESENT)
 				has_deep_states = false;
 	} else if (chip->type == PROC_CHIP_P8_MURANO ||
diff --git a/hw/xive.c b/hw/xive.c
index c0ee2ab8..b87cb985 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -24,6 +24,7 @@ 
 #include <bitmap.h>
 #include <buddy.h>
 #include <phys-map.h>
+#include <p9_stop_api.H>
 
 /* Use Block group mode to move chip_id into block .... */
 #define USE_BLOCK_GROUP_MODE
@@ -3159,6 +3160,35 @@  static void xive_configure_ex_special_bar(struct xive *x, struct cpu_thread *c)
 	}
 }
 
+void xive_late_init(void)
+{
+	struct cpu_thread *c;
+
+	prlog(PR_NOTICE, "SLW: Configuring self-restore for NCU_SPEC_BAR\n");
+	for_each_present_cpu(c) {
+		if(cpu_is_thread0(c)) {
+			struct proc_chip *chip = get_chip(c->chip_id);
+			struct xive *x = chip->xive;
+			uint64_t xa, val, rc;
+			xa = XSCOM_ADDR_P9_EX(pir_to_core_id(c->pir),
+				P9X_EX_NCU_SPEC_BAR);
+			val = (uint64_t)x->tm_base | P9X_EX_NCU_SPEC_BAR_ENABLE;
+			/* Bail out if wakeup engine has already failed */
+			if ( wakeup_engine_state != WAKEUP_ENGINE_PRESENT) {
+				prlog(PR_ERR, "XIVE p9_stop_api fail detected\n");
+				break;
+			}
+			rc = p9_stop_save_scom((void *)chip->homer_base, xa, val,
+				P9_STOP_SCOM_REPLACE, P9_STOP_SECTION_EQ_SCOM);
+			if (rc) {
+				xive_cpu_err(c, "p9_stop_api failed for NCU_SPEC_BAR rc=%lld\n",
+				rc);
+				wakeup_engine_state = WAKEUP_ENGINE_FAILED;
+			}
+		}
+	}
+
+}
 static void xive_provision_cpu(struct xive_cpu_state *xs, struct cpu_thread *c)
 {
 	struct xive *x;
diff --git a/include/skiboot.h b/include/skiboot.h
index 859db56d..cc3820b2 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -305,6 +305,10 @@  enum wakeup_engine_states {
 };
 extern enum wakeup_engine_states wakeup_engine_state;
 extern bool has_deep_states;
+extern void nx_p9_rng_late_init(void);
+extern void xive_late_init(void);
+
+
 
 /* SLW reinit function for switching core settings */
 extern int64_t slw_reinit(uint64_t flags);