aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAkshay Adiga <akshay.adiga@linux.vnet.ibm.com>2018-01-04 16:58:05 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2018-01-14 21:05:51 -0600
commitc613c2fb9b826b0eff2d28c23f3ec47a2ab3c410 (patch)
treeb16c1f09e316d338b9ef23bf9d4c97aa306a73a0 /hw
parente5c663c3f6debd5164cfced486fa926ab57b3656 (diff)
downloadskiboot-c613c2fb9b826b0eff2d28c23f3ec47a2ab3c410.zip
skiboot-c613c2fb9b826b0eff2d28c23f3ec47a2ab3c410.tar.gz
skiboot-c613c2fb9b826b0eff2d28c23f3ec47a2ab3c410.tar.bz2
SCOM restore for DARN and XIVE
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> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/nx.c42
-rw-r--r--hw/slw.c6
-rw-r--r--hw/xive.c30
3 files changed, 76 insertions, 2 deletions
diff --git a/hw/nx.c b/hw/nx.c
index f6e823f..0f6ff04 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 01d24f0..57b52a2 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -923,9 +923,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 dff94ab..271256b 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
@@ -3215,6 +3216,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;