aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorVaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>2014-07-29 10:53:30 +0530
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-07-30 10:56:17 +1000
commitd5aed5be5a63f991b80458b3a8eedaa26e203639 (patch)
treed8a0629f9e3419478acbcb204fe2a49bce96221f /hw
parenta02875504d6c182ec27fd29638f0451bfa13b969 (diff)
downloadskiboot-d5aed5be5a63f991b80458b3a8eedaa26e203639.zip
skiboot-d5aed5be5a63f991b80458b3a8eedaa26e203639.tar.gz
skiboot-d5aed5be5a63f991b80458b3a8eedaa26e203639.tar.bz2
sleep: Add workarounds for fast sleep
Add OPAL calls to setup xscom before and after sleep V1:https://w3-01.ibm.com/stg/linux/ltc/mailinglists/pipermail/sapphire/2014-July/003170.html Changes in V2: 1.Store L2 Fir Action register contents in primary thread's pointer 2.Enable secondary threads also to call opal, now that the synchronization across threads of a core will be taken care of by the kernel. We can hence safely call fastsleep in smt on mode. Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com> Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/slw.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/hw/slw.c b/hw/slw.c
index cfa5a7e..cecfbf7 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -527,7 +527,7 @@ void add_cpu_idle_state_properties(void)
/* Check if hostboot say we can sleep */
if (p && !dt_prop_find_string(p, "fastsleep"))
- can_sleep = false;
+ can_sleep = true;
/* Clip to NAP only on Murano DD1.x */
if (chip->type == PROC_CHIP_P8_MURANO &&
@@ -874,3 +874,90 @@ void slw_init(void)
slw_init_chip(chip);
}
+/* Workarounds while entering fast-sleep */
+
+static void fast_sleep_enter(void)
+{
+ uint32_t core = pir_to_core_id(this_cpu()->pir);
+ uint32_t chip_id = this_cpu()->chip_id;
+ struct cpu_thread *primary_thread;
+ uint64_t tmp;
+ int rc;
+
+ primary_thread = this_cpu()->primary;
+
+ rc = xscom_read(chip_id, XSCOM_ADDR_P8_EX(core, L2_FIR_ACTION1),
+ &tmp);
+ if (rc) {
+ printf("fast_sleep_enter XSCOM failed\n");
+ return;
+ }
+
+ primary_thread->save_l2_fir_action1 = tmp;
+ tmp = tmp & ~0x0200000000000000ULL;
+ rc = xscom_write(chip_id, XSCOM_ADDR_P8_EX(core, L2_FIR_ACTION1),
+ tmp);
+ if (rc) {
+ printf("fast_sleep_enter XSCOM failed\n");
+ return;
+ }
+ rc = xscom_read(chip_id, XSCOM_ADDR_P8_EX(core, L2_FIR_ACTION1),
+ &tmp);
+ printf("fastsleep: core %d: l2 fir before %016llx, after %016llx\n",
+ this_cpu()->pir, primary_thread->save_l2_fir_action1, tmp);
+ if (rc) {
+ printf("fast_sleep_enter XSCOM failed\n");
+ return;
+ }
+
+}
+
+/* Workarounds while exiting fast-sleep */
+
+static void fast_sleep_exit(void)
+{
+ uint32_t core = pir_to_core_id(this_cpu()->pir);
+ uint32_t chip_id = this_cpu()->chip_id;
+ struct cpu_thread *primary_thread;
+ int rc;
+
+ primary_thread = this_cpu()->primary;
+
+ rc = xscom_write(chip_id, XSCOM_ADDR_P8_EX(core, L2_FIR_ACTION1),
+ primary_thread->save_l2_fir_action1);
+ if (rc) {
+ printf("fast_sleep_exit XSCOM failed\n");
+ return;
+ }
+ printf("fastsleep: core %d: l2 fir restored %016llx\n",
+ this_cpu()->pir, primary_thread->save_l2_fir_action1);
+}
+
+/*
+ * Setup and cleanup method for fast-sleep workarounds
+ * state = 1 fast-sleep
+ * enter = 1 Enter state
+ * exit = 0 Exit state
+ */
+
+static int64_t opal_config_cpu_idle_state(uint64_t state, uint64_t enter)
+{
+ /* Only fast-sleep for now */
+ if (state != 1)
+ return OPAL_PARAMETER;
+
+ switch(enter) {
+ case 1:
+ fast_sleep_enter();
+ break;
+ case 0:
+ fast_sleep_exit();
+ break;
+ default:
+ return OPAL_PARAMETER;
+ }
+
+ return OPAL_SUCCESS;
+}
+
+opal_call(OPAL_CONFIG_CPU_IDLE_STATE, opal_config_cpu_idle_state, 2);