[Skiboot] [PATCH] [SCHEME 2]SLW: Add new device tree format
Akshay Adiga
akshay.adiga at linux.vnet.ibm.com
Thu May 31 12:52:11 AEST 2018
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 at linux.vnet.ibm.com>
---
hw/slw.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++----
include/skiboot.h | 7 ++++++-
2 files changed, 56 insertions(+), 5 deletions(-)
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);
--
2.5.5
More information about the Skiboot
mailing list