diff options
author | Pratik Rajesh Sampat <psampat@linux.ibm.com> | 2021-08-04 12:51:34 +0530 |
---|---|---|
committer | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2021-08-06 12:30:46 +0530 |
commit | 545391ffd6b791474e5e7b1231738a1cb19a6cf8 (patch) | |
tree | fad65ff1b9de883201bb9629b4c1a181b1d65690 /hw/slw.c | |
parent | 5232a9038a0a95f8d23549038ab791ac97c6a4ff (diff) | |
download | skiboot-545391ffd6b791474e5e7b1231738a1cb19a6cf8.zip skiboot-545391ffd6b791474e5e7b1231738a1cb19a6cf8.tar.gz skiboot-545391ffd6b791474e5e7b1231738a1cb19a6cf8.tar.bz2 |
libpore: P10 stop-api support
Update libpore with P10 STOP API. Add minor changes to make
P9 stop-api and P10 stop-api to co-exist in OPAL.
These calls are required for STOP11 support on P10.
STIOP0,2,3 on P10 does not lose full core state or scoms.
stop-api based restore of SPRs or xscoms required only
for STOP11 on P10.
STOP11 on P10 will be a limited lab test/stress feature
and not a product feature. (Same case as P9)
Co-authored-by: Pratik Rajesh Sampat <psampat@linux.ibm.com>
Signed-off-by: Pratik Rajesh Sampat <psampat@linux.ibm.com>
Co-authored-by: Vaidyanathan Srinivasan <svaidy@linux.ibm.com>
Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.ibm.com>
Co-authored-by: Ryan Grimm <grimm@linux.ibm.com>
Signed-off-by: Ryan Grimm <grimm@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw/slw.c')
-rw-r--r-- | hw/slw.c | 86 |
1 files changed, 82 insertions, 4 deletions
@@ -10,6 +10,7 @@ #include <xscom.h> #include <xscom-p8-regs.h> #include <xscom-p9-regs.h> +#include <xscom-p10-regs.h> #include <io.h> #include <cpu.h> #include <chip.h> @@ -24,7 +25,7 @@ #include <sbe-p8.h> #include <xive.h> -#include <p9_stop_api.H> +#include <p10_stop_api.H> #include <p8_pore_table_gen_api.H> #include <sbe_xip_image.h> @@ -220,6 +221,30 @@ static bool slw_set_overrides(struct proc_chip *chip, struct cpu_thread *c) return true; } +static bool slw_set_overrides_p10(struct proc_chip *chip, struct cpu_thread *c) +{ + uint64_t tmp; + int rc; + uint32_t core = pir_to_core_id(c->pir); + + /* Special wakeup bits that could hold power mgt */ + rc = xscom_read(chip->id, + XSCOM_ADDR_P10_QME_CORE(core, P10_QME_SPWU_HYP), + &tmp); + if (rc) { + log_simple_error(&e_info(OPAL_RC_SLW_SET), + "SLW: Failed to read P10_QME_SPWU_HYP\n"); + return false; + } + if (tmp & P10_SPWU_REQ) + prlog(PR_WARNING, + "SLW: core %d P10_QME_SPWU_HYP requested 0x%016llx\n", + core, tmp); + + return true; +} + + static bool slw_set_overrides_p9(struct proc_chip *chip, struct cpu_thread *c) { uint64_t tmp; @@ -872,6 +897,31 @@ static void slw_late_init_p9(struct proc_chip *chip) } } +static void slw_late_init_p10(struct proc_chip *chip) +{ + struct cpu_thread *c; + int rc; + + prlog(PR_INFO, "SLW: Configuring self-restore for HRMOR\n"); + for_each_available_cpu(c) { + if (c->chip_id != chip->id) + continue; + /* + * Clear HRMOR. Need to update only for thread + * 0 of each core. Doing it anyway for all threads + */ + rc = proc_stop_save_cpureg((void *)chip->homer_base, + PROC_STOP_SPR_HRMOR, 0, + c->pir); + if (rc) { + log_simple_error(&e_info(OPAL_RC_SLW_REG), + "SLW: Failed to set HRMOR for CPU %x,RC=0x%x\n", + c->pir, rc); + prlog(PR_ERR, "Disabling deep stop states\n"); + } + } +} + /* Add device tree properties to describe idle states */ void add_cpu_idle_state_properties(void) { @@ -971,7 +1021,7 @@ void add_cpu_idle_state_properties(void) xive_late_init(); nx_p9_rng_late_init(); } else if (chip->type == PROC_CHIP_P10) { - /* TODO (p10): need P10 stop state engine */ + slw_late_init_p10(chip); xive2_late_init(); } } @@ -1380,6 +1430,20 @@ static void slw_init_chip_p9(struct proc_chip *chip) } +static void slw_init_chip_p10(struct proc_chip *chip) +{ + struct cpu_thread *c; + + prlog(PR_DEBUG, "SLW: Init chip 0x%x\n", chip->id); + + /* At power ON setup inits for power-mgt */ + for_each_available_core_in_chip(c, chip->id) + slw_set_overrides_p10(chip, c); + + +} + + static bool slw_image_check_p9(struct proc_chip *chip) { @@ -1575,8 +1639,13 @@ int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val) wakeup_engine_state,chip->id); return OPAL_INTERNAL_ERROR; } - rc = p9_stop_save_cpureg((void *)chip->homer_base, + if (proc_gen == proc_gen_p9) { + rc = p9_stop_save_cpureg((void *)chip->homer_base, + sprn, val, cpu_pir); + } else { + rc = proc_stop_save_cpureg((void *)chip->homer_base, sprn, val, cpu_pir); + } } else if (proc_gen == proc_gen_p8) { int spr_is_supported = 0; @@ -1640,7 +1709,7 @@ void slw_init(void) slw_late_init_p8(chip); } p8_sbe_init_timer(); - } else if (proc_gen >= proc_gen_p9) { + } else if (proc_gen == proc_gen_p9) { for_each_chip(chip) { slw_init_chip_p9(chip); if(slw_image_check_p9(chip)) @@ -1648,6 +1717,15 @@ void slw_init(void) if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT) slw_late_init_p9(chip); } + } else if (proc_gen == proc_gen_p10) { + for_each_chip(chip) { + slw_init_chip_p10(chip); + if(slw_image_check_p9(chip)) + wakeup_engine_state = WAKEUP_ENGINE_PRESENT; + if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT) { + slw_late_init_p10(chip); + } + } } add_cpu_idle_state_properties(); } |