diff mbox series

Disable stop states from OPAL

Message ID 20180411092510.7581-1-stewart@linux.ibm.com
State Accepted
Headers show
Series Disable stop states from OPAL | expand

Commit Message

Stewart Smith April 11, 2018, 9:25 a.m. UTC
On ZZ, stop4,5,11 are enabled for PHYP, even though doing
so may cause problems with OPAL due to bugs in hcode.

For other platforms, this isn't so much of an issue as
we can just control stop states by the MRW. However the
rebuild-the-world approach to changing values there is a bit
annoying if you just want to rule out a specific stop state
from being problematic.

Provide an nvram option to override what's disabled in OPAL.

The OPAL mask is currently ~0xE0000000 (i.e. all but stop 0,1,2)
You can set an NVRAM override with:
  nvram -p ibm,skiboot --update-config opal-stop-state-disable-mask=0xFFFFFFF

This will disable *all* stop states.

Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
---
 hw/slw.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

Comments

Stewart Smith April 12, 2018, 6:24 a.m. UTC | #1
Stewart Smith <stewart@linux.ibm.com> writes:
> On ZZ, stop4,5,11 are enabled for PHYP, even though doing
> so may cause problems with OPAL due to bugs in hcode.
>
> For other platforms, this isn't so much of an issue as
> we can just control stop states by the MRW. However the
> rebuild-the-world approach to changing values there is a bit
> annoying if you just want to rule out a specific stop state
> from being problematic.
>
> Provide an nvram option to override what's disabled in OPAL.
>
> The OPAL mask is currently ~0xE0000000 (i.e. all but stop 0,1,2)
> You can set an NVRAM override with:
>   nvram -p ibm,skiboot --update-config opal-stop-state-disable-mask=0xFFFFFFF
>
> This will disable *all* stop states.
>
> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
> ---
>  hw/slw.c | 23 +++++++++++++++++++++++
>  1 file changed, 23 insertions(+)

Merged to master as of 217e5a4ecbfab8e88b6e250d5d8fdfe502cfe5da
diff mbox series

Patch

diff --git a/hw/slw.c b/hw/slw.c
index 905e54c9be36..3f9abaad2c7a 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -29,6 +29,7 @@ 
 #include <errorlog.h>
 #include <libfdt/libfdt.h>
 #include <opal-api.h>
+#include <nvram.h>
 
 #include <p9_stop_api.H>
 #include <p8_pore_table_gen_api.H>
@@ -857,6 +858,9 @@  void add_cpu_idle_state_properties(void)
 	u64 *pm_ctrl_reg_val_buf;
 	u64 *pm_ctrl_reg_mask_buf;
 	u32 supported_states_mask;
+	u32 opal_disabled_states_mask = ~0xE0000000; /* all but stop0,1,2 */
+	const char* nvram_disable_str;
+	u32 nvram_disabled_states_mask = 0x00;
 	u32 stop_levels;
 
 	/* Variables to track buffer length */
@@ -1000,6 +1004,10 @@  void add_cpu_idle_state_properties(void)
 		if (wakeup_engine_state == WAKEUP_ENGINE_PRESENT)
 			supported_states_mask |= OPAL_PM_WINKLE_ENABLED;
 	}
+	nvram_disable_str = nvram_query("opal-stop-state-disable-mask");
+	if (nvram_disable_str)
+		nvram_disabled_states_mask = strtol(nvram_disable_str, NULL, 0);
+	prlog(PR_DEBUG, "NVRAM stop disable mask: %x\n", nvram_disabled_states_mask);
 	for (i = 0; i < nr_states; i++) {
 		/* For each state, check if it is one of the supported states. */
 		if (!(states[i].flags & supported_states_mask))
@@ -1012,6 +1020,21 @@  void add_cpu_idle_state_properties(void)
 
 			if (!(stop_levels & (1ul << level)))
 				continue;
+
+			if ((opal_disabled_states_mask |
+			     nvram_disabled_states_mask) &
+			    (1ul << level)) {
+				if (nvram_disable_str &&
+				    !(nvram_disabled_states_mask & (1ul << level))) {
+					prlog(PR_NOTICE, "SLW: Enabling: %s "
+					      "(disabled in OPAL, forced by "
+					      "NVRAM)\n",states[i].name);
+				} else {
+					prlog(PR_NOTICE, "SLW: Disabling: %s in OPAL\n",
+					      states[i].name);
+					continue;
+				}
+			}
 		}
 
 		prlog(PR_NOTICE, "SLW: Enabling: %s\n", states[i].name);