[SCHEME,2] SLW: Add new device tree format

Message ID 1527735131-23820-1-git-send-email-akshay.adiga@linux.vnet.ibm.com
State New
Headers show
Series
  • [SCHEME,2] SLW: Add new device tree format
Related show

Commit Message

Akshay Adiga May 31, 2018, 2:52 a.m.
Adds a node ibm,idle-states which will contain additional idle states
with version strings. ibm,cpu-idle-state-versions is an array of
version strings for each idle state respectively.

Idea is that older kernel will continue to look at
"power-mgt/ibm,cpu-idle-state-names"  for available idle-states. Newer
kernel will additionally look at
"power-mgt/ibm,idle-states/ibm,cpu-idle-state-names" and corresponding
version strings, before enabling an idle state in cpuidle driver.

Limitation :
- We can only have 1 version-string per idle-state

Device tree out-put  :

power-mgt {
	ibm,cpu-idle-state-names = "stop0_lite", "stop0";
	ibm,cpu-idle-state-residency-ns = <0x2710 0x4e20>;
	ibm,cpu-idle-state-latencies-ns = <0x3e8 0x7d0>;
	ibm,cpu-idle-state-psscr-mask = <0x0 0x3003ff 0x0 0x3003ff>;
	ibm,cpu-idle-state-psscr = <0x0 0x330 0x0 0x300330>;
	ibm,cpu-idle-state-flags = <0x100000 0x101000>;
	ibm,enabled-stop-levels = <0xec000000>;
	ibm,idle-states {
	  ibm,cpu-idle-state-names = "stop1", "stop2", "stop4", "stop5";
	  ibm,cpu-idle-state-residency-ns = <0xc350 0x186a0 0x989680
0x1312d00>;
	  ibm,cpu-idle-state-latencies-ns = <0x1388 0x2710 0x186a0
0x30d40>;
	  ibm,cpu-idle-state-psscr-mask = <0x0 0x3003ff 0x0 0x3003ff 0x0
0x3003ff 0x0 0x3003ff>;
	  ibm,cpu-idle-state-psscr = <0x0 0x300331 0x0 0x300332 0x0
0x300374 0x0 0x300375>;
	  ibm,cpu-idle-state-versions = "ibm,idle-state-v1
", "ibm,idle-state-v1", "ibm,idle-state-v1", "ibm,idle-state-v1";
	  ibm,cpu-idle-state-flags = <0x101000 0x101000 0x207000 0x207000>;

Signed-off-by: Akshay Adiga <akshay.adiga@linux.vnet.ibm.com>
---
 hw/slw.c          | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 include/skiboot.h |  7 ++++++-
 2 files changed, 56 insertions(+), 5 deletions(-)

Patch

diff --git a/hw/slw.c b/hw/slw.c
index 49bcd83..f87544f 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -414,8 +414,11 @@  static bool idle_prepare_core(struct proc_chip *chip, struct cpu_thread *c)
 
 /* Define device-tree fields */
 #define MAX_NAME_LEN	16
+#define MAX_VERSION_LEN	26
 struct cpu_idle_states {
 	char name[MAX_NAME_LEN];
+	char version[MAX_VERSION_LEN];
+	enum dt_format node_type;
 	u32 latency_ns;
 	u32 residency_ns;
 	/*
@@ -503,6 +506,8 @@  static struct cpu_idle_states power8_cpu_idle_states[] = {
 static struct cpu_idle_states power9_cpu_idle_states[] = {
 	{
 		.name = "stop0_lite", /* Enter stop0 with no state loss */
+		.version = "ibm,idle-state-v1",
+		.node_type = OLD_FORMAT,
 		.latency_ns = 1000,
 		.residency_ns = 10000,
 		.flags = 0*OPAL_PM_DEC_STOP \
@@ -517,6 +522,8 @@  static struct cpu_idle_states power9_cpu_idle_states[] = {
 		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 	{
 		.name = "stop0",
+		.node_type = OLD_FORMAT,
+		.version = "ibm,idle-state-v1",
 		.latency_ns = 2000,
 		.residency_ns = 20000,
 		.flags = 0*OPAL_PM_DEC_STOP \
@@ -536,6 +543,8 @@  static struct cpu_idle_states power9_cpu_idle_states[] = {
 
 	{
 		.name = "stop1",
+		.node_type = V1_FORMAT,
+		.version = "ibm,idle-state-v1",
 		.latency_ns = 5000,
 		.residency_ns = 50000,
 		.flags = 0*OPAL_PM_DEC_STOP \
@@ -557,6 +566,8 @@  static struct cpu_idle_states power9_cpu_idle_states[] = {
 
 	{
 		.name = "stop2",
+		.node_type = V1_FORMAT,
+		.version = "ibm,idle-state-v1",
 		.latency_ns = 10000,
 		.residency_ns = 100000,
 		.flags = 0*OPAL_PM_DEC_STOP \
@@ -573,6 +584,8 @@  static struct cpu_idle_states power9_cpu_idle_states[] = {
 		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 	{
 		.name = "stop4",
+		.node_type = V1_FORMAT,
+		.version = "ibm,idle-state-v1",
 		.latency_ns = 100000,
 		.residency_ns = 10000000,
 		.flags = 0*OPAL_PM_DEC_STOP \
@@ -589,6 +602,8 @@  static struct cpu_idle_states power9_cpu_idle_states[] = {
 		.pm_ctrl_reg_mask = OPAL_PM_PSSCR_MASK },
 	{
 		.name = "stop5",
+		.node_type = V1_FORMAT,
+		.version = "ibm,idle-state-v1",
 		.latency_ns = 200000,
 		.residency_ns = 20000000,
 		.flags = 0*OPAL_PM_DEC_STOP \
@@ -606,6 +621,8 @@  static struct cpu_idle_states power9_cpu_idle_states[] = {
 
 	{
 		.name = "stop8",
+		.node_type = V1_FORMAT,
+		.version = "ibm,idle-state-v1",
 		.latency_ns = 2000000,
 		.residency_ns = 20000000,
 		.flags = 1*OPAL_PM_DEC_STOP \
@@ -623,6 +640,8 @@  static struct cpu_idle_states power9_cpu_idle_states[] = {
 
 	{
 		.name = "stop11",
+		.node_type = V1_FORMAT,
+		.version = "ibm,idle-state-v1",
 		.latency_ns = 10000000,
 		.residency_ns = 100000000,
 		.flags = 1*OPAL_PM_DEC_STOP \
@@ -819,9 +838,10 @@  static void slw_late_init_p9(struct proc_chip *chip)
 }
 
 /* Add device tree properties to describe idle states */
-void add_cpu_idle_state_properties(void)
+void add_cpu_idle_state_properties(enum dt_format dt_format)
 {
 	struct dt_node *power_mgt;
+	struct dt_node *parent_node;
 	struct cpu_idle_states *states;
 	struct proc_chip *chip;
 	int nr_states;
@@ -839,11 +859,12 @@  void add_cpu_idle_state_properties(void)
 	u32 stop_levels;
 
 	/* Variables to track buffer length */
-	u8 name_buf_len;
+	u8 name_buf_len,version_buf_len;
 	u8 num_supported_idle_states;
 
 	/* Buffers to hold idle state properties */
 	char *name_buf, *alloced_name_buf;
+	char *version_buf, *alloced_version_buf;
 	u32 *latency_ns_buf;
 	u32 *residency_ns_buf;
 	u32 *flags_buf;
@@ -951,6 +972,8 @@  void add_cpu_idle_state_properties(void)
 	/* Allocate memory to idle state property buffers. */
 	alloced_name_buf= malloc(nr_states * sizeof(char) * MAX_NAME_LEN);
 	name_buf = alloced_name_buf;
+	alloced_version_buf= malloc(nr_states * sizeof(char) * MAX_VERSION_LEN);
+	version_buf = alloced_version_buf;
 	latency_ns_buf	= malloc(nr_states * sizeof(u32));
 	residency_ns_buf= malloc(nr_states * sizeof(u32));
 	flags_buf	= malloc(nr_states * sizeof(u32));
@@ -958,6 +981,7 @@  void add_cpu_idle_state_properties(void)
 	pm_ctrl_reg_mask_buf	= malloc(nr_states * sizeof(u64));
 
 	name_buf_len = 0;
+	version_buf_len = 0;
 	num_supported_idle_states = 0;
 
 	/*
@@ -995,6 +1019,8 @@  void add_cpu_idle_state_properties(void)
 
 			if (!(stop_levels & (1ul << level)))
 				continue;
+			if ( dt_format != states[i].node_type)
+				continue;
 
 			if ((opal_disabled_states_mask |
 			     nvram_disabled_states_mask) &
@@ -1021,6 +1047,10 @@  void add_cpu_idle_state_properties(void)
 		strncpy(name_buf, states[i].name, MAX_NAME_LEN);
 		name_buf = name_buf + strlen(states[i].name) + 1;
 
+		strncpy(version_buf, states[i].version, MAX_VERSION_LEN);
+		version_buf = version_buf + strlen(states[i].version) + 1;
+		version_buf_len += strlen(states[i].version) + 1;
+
 		*latency_ns_buf = cpu_to_fdt32(states[i].latency_ns);
 		latency_ns_buf++;
 
@@ -1036,6 +1066,7 @@  void add_cpu_idle_state_properties(void)
 		*pm_ctrl_reg_mask_buf = cpu_to_fdt64(states[i].pm_ctrl_reg_mask);
 		pm_ctrl_reg_mask_buf++;
 
+
 		/* Increment buffer length trackers */
 		name_buf_len += strlen(states[i].name) + 1;
 		num_supported_idle_states++;
@@ -1049,6 +1080,19 @@  void add_cpu_idle_state_properties(void)
 	flags_buf -= num_supported_idle_states;
 	pm_ctrl_reg_val_buf -= num_supported_idle_states;
 	pm_ctrl_reg_mask_buf -= num_supported_idle_states;
+
+	if (dt_format == V1_FORMAT) {
+		version_buf -= version_buf_len;
+		parent_node = dt_new_check(power_mgt,  "ibm,idle-states"); 
+		if (!parent_node) {
+			prlog(PR_ERR, "Error creating ibm,idle-states\n");
+			return ;
+		}
+		power_mgt = parent_node;
+		dt_add_property(power_mgt, "ibm,cpu-idle-state-versions", version_buf,
+			version_buf_len* sizeof(char));
+	}
+
 	/* Create dt properties with the buffer content */
 	dt_add_property(power_mgt, "ibm,cpu-idle-state-names", name_buf,
 			name_buf_len* sizeof(char));
@@ -1076,6 +1120,7 @@  void add_cpu_idle_state_properties(void)
 	}
 	assert(alloced_name_buf == name_buf);
 	free(alloced_name_buf);
+	free(alloced_version_buf);
 	free(latency_ns_buf);
 	free(residency_ns_buf);
 	free(flags_buf);
@@ -1563,7 +1608,7 @@  void slw_init(void)
 
 	if (proc_chip_quirks & QUIRK_MAMBO_CALLOUTS) {
 		wakeup_engine_state = WAKEUP_ENGINE_NOT_PRESENT;
-		add_cpu_idle_state_properties();
+		add_cpu_idle_state_properties(OLD_FORMAT);
 		return;
 	}
 	if (proc_gen == proc_gen_p8) {
@@ -1584,5 +1629,6 @@  void slw_init(void)
 				slw_late_init_p9(chip);
 		}
 	}
-	add_cpu_idle_state_properties();
+	add_cpu_idle_state_properties(OLD_FORMAT);
+	add_cpu_idle_state_properties(V1_FORMAT);
 }
diff --git a/include/skiboot.h b/include/skiboot.h
index b4bdf37..bfeca9e 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -141,6 +141,11 @@  enum proc_gen {
 };
 extern enum proc_gen proc_gen;
 
+enum dt_format {
+	OLD_FORMAT,
+	V1_FORMAT,
+};
+
 extern unsigned int pcie_max_link_speed;
 
 /* Convert a 4-bit number to a hex char */
@@ -243,7 +248,7 @@  extern void early_uart_init(void);
 extern void homer_init(void);
 extern void occ_pstates_init(void);
 extern void slw_init(void);
-extern void add_cpu_idle_state_properties(void);
+extern void add_cpu_idle_state_properties(enum dt_format format);
 extern void occ_fsp_init(void);
 extern void lpc_rtc_init(void);