diff options
author | Akshay Adiga <akshay.adiga@linux.vnet.ibm.com> | 2017-03-24 20:01:49 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-03-30 19:37:48 +1100 |
commit | c3e405b3b1e0c47efbbf31ce37ea02e9a1e005e3 (patch) | |
tree | 5f7580b592aae8f7ef8a7d2051950166c6bb4c86 /hw/slw.c | |
parent | d95ffaa6fac5b0094cb473ad6bbc8923ce4107d7 (diff) | |
download | skiboot-c3e405b3b1e0c47efbbf31ce37ea02e9a1e005e3.zip skiboot-c3e405b3b1e0c47efbbf31ce37ea02e9a1e005e3.tar.gz skiboot-c3e405b3b1e0c47efbbf31ce37ea02e9a1e005e3.tar.bz2 |
SLW: Add init for power9 power management
This patch adds new function to init core for power9 power management.
SPECIAL_WKUP_* SCOM registers, if set, can hold the cores from going into
idle states. Hence, clear PPM_SPECIAL_WKUP_HYP_REG scom register for each
core during init. (This init are not required for MAMBO)
Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
Reviewed-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/slw.c')
-rw-r--r-- | hw/slw.c | 58 |
1 files changed, 51 insertions, 7 deletions
@@ -287,6 +287,39 @@ static bool slw_set_overrides(struct proc_chip *chip, struct cpu_thread *c) return true; } +static bool slw_set_overrides_p9(struct proc_chip *chip, struct cpu_thread *c) +{ + uint64_t tmp; + int rc; + uint32_t core = pir_to_core_id(c->pir); + + /* MAMBO does not require this init */ + if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS) { + return true; + } + + /* Clear special wakeup bits that could hold power mgt */ + rc = xscom_write(chip->id, + XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_HYP), + 0); + if (rc) { + log_simple_error(&e_info(OPAL_RC_SLW_SET), + "SLW: Failed to write EC_PPM_SPECIAL_WKUP_HYP\n"); + return false; + } + /* Read back for debug */ + rc = xscom_read(chip->id, + XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_HYP), + &tmp); + prlog(PR_NOTICE, "SLW: EC_PPM_SPECIAL_WKUP_HYP read 0x%016llx\n", tmp); + rc = xscom_read(chip->id, + XSCOM_ADDR_P9_EC_SLAVE(core, EC_PPM_SPECIAL_WKUP_OTR), + &tmp); + if (tmp) + prlog(PR_WARNING, "SLW: EC_PPM_SPECIAL_WKUP_OTR read 0x%016llx\n", tmp); + return true; +} + #ifdef __HAVE_LIBPORE__ static bool slw_unset_overrides(struct proc_chip *chip, struct cpu_thread *c) { @@ -1128,6 +1161,16 @@ static void slw_patch_regs(struct proc_chip *chip) } #endif /* __HAVE_LIBPORE__ */ +static void slw_init_chip_p9(struct proc_chip *chip) +{ + struct cpu_thread *c; + + prlog(PR_NOTICE, "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_p9(chip, c); +} static void slw_init_chip(struct proc_chip *chip) { int64_t rc; @@ -1493,11 +1536,12 @@ void slw_init(void) { struct proc_chip *chip; - if (proc_gen != proc_gen_p8) - return; - - for_each_chip(chip) - slw_init_chip(chip); - - slw_init_timer(); + if (proc_gen == proc_gen_p8) { + for_each_chip(chip) + slw_init_chip(chip); + slw_init_timer(); + } else if (proc_gen == proc_gen_p9) { + for_each_chip(chip) + slw_init_chip_p9(chip); + } } |