diff options
author | Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> | 2016-02-11 13:01:46 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-02-23 17:23:03 +1100 |
commit | 934ae908f94cf7f5b4153c1c87395eecf642f30f (patch) | |
tree | 2375b56f89dc9ad9507a87a81c7d0c69943a83fb | |
parent | f7ad0d75f45130e0cec6787a7629da47f5f40f21 (diff) | |
download | skiboot-934ae908f94cf7f5b4153c1c87395eecf642f30f.zip skiboot-934ae908f94cf7f5b4153c1c87395eecf642f30f.tar.gz skiboot-934ae908f94cf7f5b4153c1c87395eecf642f30f.tar.bz2 |
occ: Add support to read V2 format of OCC-OPAL shared memory region
Add support to read OCC-OPAL shared memory region version2 to parse
ultra-turbo pstates and core-to-max-pstate-allowed array and append
it to device tree. Each element of core-to-max-pstate-allowed indicates
the maximum pstate sustained with 'n' online cores.
Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | doc/device-tree/ibm,opal/power-mgt.txt | 11 | ||||
-rw-r--r-- | hw/occ.c | 63 |
2 files changed, 63 insertions, 11 deletions
diff --git a/doc/device-tree/ibm,opal/power-mgt.txt b/doc/device-tree/ibm,opal/power-mgt.txt index 0852650..d9cadb8 100644 --- a/doc/device-tree/ibm,opal/power-mgt.txt +++ b/doc/device-tree/ibm,opal/power-mgt.txt @@ -55,6 +55,17 @@ These properties list a voltage-identifier of each of the pstates listed in ibm,pstate-ids for the Vcs and Vdd values used for that pstate. Each VID is a single byte. +ibm,pstate-ultra-turbo ibm,pstate-turbo +--------------------------------------- + +These properties are added when ultra-turbo(WOF) is enabled. These properties +give the max turbo and max ultra-turbo pstate. + +ibm,pstate-core-max +------------------- + +This property is added when ultra_turbo(WOF) is enabled. This property gives +the list of max pstate for each 'n' number of active cores in the chip. FIXME: document these: ibm,cpu-idle-state-flags @@ -49,18 +49,24 @@ struct occ_pstate_entry { u32 freq_khz; }; +/* + * OCC-OPAL Shared Memory Region Version 2 + * https://github.com/open-power/occ/blob/master/src/occ/proc/proc_pstate.h + * Interface defined in 'sapphire_table_t' + */ struct occ_pstate_table { u8 valid; u8 version; u8 throttle; s8 pstate_min; s8 pstate_nom; - s8 pstate_max; - u8 spare1; - u8 spare2; + s8 pstate_turbo; + s8 pstate_ultra_turbo; + u8 spare; u64 reserved; struct occ_pstate_entry pstates[MAX_PSTATES]; -}; + s8 core_max[16]; +} __packed; DEFINE_LOG_ENTRY(OPAL_RC_OCC_LOAD, OPAL_PLATFORM_ERR_EVT, OPAL_OCC, OPAL_CEC_HARDWARE, OPAL_PREDICTIVE_ERR_GENERAL, @@ -142,11 +148,13 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom) uint64_t occ_data_area; struct occ_pstate_table *occ_data; struct dt_node *power_mgt; - u8 nr_pstates; + u8 nr_pstates, nr_cores = 0; + s8 pmax; /* Arrays for device tree */ u32 *dt_id, *dt_freq; u8 *dt_vdd, *dt_vcs; - bool rc; + s8 *dt_core_max = NULL; + bool rc, ultra_turbo_en; int i; prlog(PR_DEBUG, "OCC: CPU pstate state device tree init\n"); @@ -171,10 +179,18 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom) return false; } - nr_pstates = occ_data->pstate_max - occ_data->pstate_min + 1; + if (occ_data->version > 1 && + occ_data->pstate_ultra_turbo > occ_data->pstate_turbo) + ultra_turbo_en = true; + else + ultra_turbo_en = false; + + pmax = ultra_turbo_en ? occ_data->pstate_ultra_turbo : + occ_data->pstate_turbo; + nr_pstates = pmax - occ_data->pstate_min + 1; prlog(PR_DEBUG, "OCC: Min %d Nom %d Max %d Nr States %d\n", occ_data->pstate_min, occ_data->pstate_nom, - occ_data->pstate_max, nr_pstates); + pmax, nr_pstates); if (nr_pstates <= 1 || nr_pstates > 128) { prerror("OCC: OCC range is not valid\n"); @@ -215,6 +231,18 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom) goto out_free_vdd; } + if (ultra_turbo_en) { + nr_cores = get_available_nr_cores_in_chip(chip->id); + dt_core_max = malloc(nr_cores * sizeof(s8)); + if (!dt_core_max) { + prerror("OCC: dt_core_max alloc failure\n"); + goto out_free_vcs; + } + + for (i = 0; i < nr_cores; i++) + dt_core_max[i] = occ_data->core_max[i]; + } + for( i=0; i < nr_pstates; i++) { dt_id[i] = occ_data->pstates[i].id; dt_freq[i] = occ_data->pstates[i].freq_khz/1000; @@ -223,18 +251,31 @@ static bool add_cpu_pstate_properties(s8 *pstate_nom) } /* Add the device-tree entries */ - dt_add_property(power_mgt, "ibm,pstate-ids", dt_id, nr_pstates * 4); - dt_add_property(power_mgt, "ibm,pstate-frequencies-mhz", dt_freq, nr_pstates * 4); + dt_add_property(power_mgt, "ibm,pstate-ids", dt_id, + nr_pstates * sizeof(u32)); + dt_add_property(power_mgt, "ibm,pstate-frequencies-mhz", dt_freq, + nr_pstates * sizeof(u32)); dt_add_property(power_mgt, "ibm,pstate-vdds", dt_vdd, nr_pstates); dt_add_property(power_mgt, "ibm,pstate-vcss", dt_vcs, nr_pstates); dt_add_property_cells(power_mgt, "ibm,pstate-min", occ_data->pstate_min); dt_add_property_cells(power_mgt, "ibm,pstate-nominal", occ_data->pstate_nom); - dt_add_property_cells(power_mgt, "ibm,pstate-max", occ_data->pstate_max); + dt_add_property_cells(power_mgt, "ibm,pstate-max", pmax); + + if (ultra_turbo_en) { + dt_add_property_cells(power_mgt, "ibm,pstate-turbo", + occ_data->pstate_turbo); + dt_add_property_cells(power_mgt, "ibm,pstate-ultra-turbo", + occ_data->pstate_ultra_turbo); + dt_add_property(power_mgt, "ibm,pstate-core-max", dt_core_max, + nr_cores); + free(dt_core_max); + } /* Return pstate to set for each core */ *pstate_nom = occ_data->pstate_nom; rc = true; +out_free_vcs: free(dt_vcs); out_free_vdd: free(dt_vdd); |