diff options
author | Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> | 2018-01-04 16:58:05 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2018-01-14 21:05:51 -0600 |
commit | c613c2fb9b826b0eff2d28c23f3ec47a2ab3c410 (patch) | |
tree | b16c1f09e316d338b9ef23bf9d4c97aa306a73a0 /hw | |
parent | e5c663c3f6debd5164cfced486fa926ab57b3656 (diff) | |
download | skiboot-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.c | 42 | ||||
-rw-r--r-- | hw/slw.c | 6 | ||||
-rw-r--r-- | hw/xive.c | 30 |
3 files changed, 76 insertions, 2 deletions
@@ -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; + } } } } @@ -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 || @@ -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; |