aboutsummaryrefslogtreecommitdiff
path: root/hw/occ.c
diff options
context:
space:
mode:
authorShilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>2019-03-06 14:53:18 +0530
committerStewart Smith <stewart@linux.ibm.com>2019-03-15 14:31:09 +1100
commit27e4943eade205da99c885cb0a879a92e63ce53f (patch)
tree812baac1f3a20a8d1b26bff0e19c7b079ad4ec1e /hw/occ.c
parent998911498597f3a057d73f7c78c075d830d22731 (diff)
downloadskiboot-27e4943eade205da99c885cb0a879a92e63ce53f.zip
skiboot-27e4943eade205da99c885cb0a879a92e63ce53f.tar.gz
skiboot-27e4943eade205da99c885cb0a879a92e63ce53f.tar.bz2
fast-reboot: occ: Remove 'freq-domain-mask' from fast-reboot path
OCC can change the pstate table at runtime to modify pstate limits or for characterization purpose. These changes are reflected by re-parsing the pstate table during fast-reboot to update the device-tree. Only relevant pstate DT properties are deleted and newly added during fast-reboot. The device-tree properties like 'freq-domain-mask' and 'domain-runs-at' are currently hard-coded and need not be updated during fast-reboot. So this patch removes them from the fast-reboot path. This patch fixes the below crash: [ 270.313998453,5] OCC: All Chip Rdy after 0 ms [ 270.314148918,3] Duplicate property "freq-domain-mask" in node /ibm,opal/power-mgt [ 270.314208553,0] Aborting! CPU 083c Backtrace: S: 0000000035de3a20 R: 000000003001b480 ._abort+0x4c S: 0000000035de3aa0 R: 0000000030028704 .new_property+0xd8 S: 0000000035de3b30 R: 0000000030028964 .__dt_add_property_cells+0x30 S: 0000000035de3bd0 R: 0000000030042980 .occ_pstates_init+0x7c8 S: 0000000035de3d90 R: 00000000300145f4 .load_and_boot_kernel+0x980 S: 0000000035de3e70 R: 00000000300276b4 .fast_reboot_entry+0x37c S: 0000000035de3f00 R: 0000000030002ac4 reset_fast_reboot_wakeup+0x40 Fixes: b821f8c2a8e3("power-mgmt : occ : Add 'freq-domain-mask' DT property") Reported-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com> Tested-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
Diffstat (limited to 'hw/occ.c')
-rw-r--r--hw/occ.c85
1 files changed, 42 insertions, 43 deletions
diff --git a/hw/occ.c b/hw/occ.c
index 9af0338..5dc05d3 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -491,27 +491,18 @@ static void parse_vid(struct occ_pstate_table *occ_data,
/* Add device tree properties to describe pstates states */
/* Return nominal pstate to set in each core */
-static bool add_cpu_pstate_properties(int *pstate_nom)
+static bool add_cpu_pstate_properties(struct dt_node *power_mgt,
+ int *pstate_nom)
{
struct proc_chip *chip;
uint64_t occ_data_area;
struct occ_pstate_table *occ_data;
- struct dt_node *power_mgt;
/* Arrays for device tree */
u32 *dt_id, *dt_freq;
int pmax, pmin, pnom;
u8 nr_pstates;
bool ultra_turbo_supported;
int i, major, minor;
- u8 domain_runs_at;
- u32 freq_domain_mask;
-
- /* TODO Firmware plumbing required so as to have two modes to set
- * PMCR based on max in domain or most recently used. As of today,
- * it is always max in domain for P9.
- */
- domain_runs_at = 0;
- freq_domain_mask = 0;
prlog(PR_DEBUG, "OCC: CPU pstate state device tree init\n");
@@ -654,18 +645,6 @@ static bool add_cpu_pstate_properties(int *pstate_nom)
return false;
}
- power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
- if (!power_mgt) {
- /**
- * @fwts-label OCCDTNodeNotFound
- * @fwts-advice Device tree node /ibm,opal/power-mgt not
- * found. OPAL didn't add pstate information to device tree.
- * Probably a firmware bug.
- */
- prlog(PR_ERR, "OCC: dt node /ibm,opal/power-mgt not found\n");
- return false;
- }
-
dt_id = malloc(nr_pstates * sizeof(u32));
assert(dt_id);
dt_freq = malloc(nr_pstates * sizeof(u32));
@@ -684,14 +663,6 @@ static bool add_cpu_pstate_properties(int *pstate_nom)
return false;
}
- if (proc_gen == proc_gen_p8) {
- freq_domain_mask = P8_PIR_CORE_MASK;
- domain_runs_at = FREQ_MOST_RECENTLY_SET;
- } else if (proc_gen == proc_gen_p9) {
- freq_domain_mask = P9_PIR_QUAD_MASK;
- domain_runs_at = FREQ_MAX_IN_DOMAIN;
- }
-
/* Add the device-tree entries */
dt_add_property(power_mgt, "ibm,pstate-ids", dt_id,
nr_pstates * sizeof(u32));
@@ -700,8 +671,6 @@ static bool add_cpu_pstate_properties(int *pstate_nom)
dt_add_property_cells(power_mgt, "ibm,pstate-min", pmin);
dt_add_property_cells(power_mgt, "ibm,pstate-nominal", pnom);
dt_add_property_cells(power_mgt, "ibm,pstate-max", pmax);
- dt_add_property_cells(power_mgt, "freq-domain-mask", freq_domain_mask);
- dt_add_property_cells(power_mgt, "domain-runs-at", domain_runs_at);
free(dt_freq);
free(dt_id);
@@ -1752,15 +1721,31 @@ void occ_pstates_init(void)
{
struct proc_chip *chip;
struct cpu_thread *c;
+ struct dt_node *power_mgt;
int pstate_nom;
+ u32 freq_domain_mask;
+ u8 domain_runs_at;
static bool occ_pstates_initialized;
/* OCC is supported in P8 and P9 */
if (proc_gen < proc_gen_p8)
return;
+
+ power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
+ if (!power_mgt) {
+ /**
+ * @fwts-label OCCDTNodeNotFound
+ * @fwts-advice Device tree node /ibm,opal/power-mgt not
+ * found. OPAL didn't add pstate information to device tree.
+ * Probably a firmware bug.
+ */
+ prlog(PR_ERR, "OCC: dt node /ibm,opal/power-mgt not found\n");
+ return;
+ }
+
/* Handle fast reboots */
if (occ_pstates_initialized) {
- struct dt_node *power_mgt, *child;
+ struct dt_node *child;
int i;
const char *props[] = {
"ibm,pstate-core-max",
@@ -1775,15 +1760,12 @@ void occ_pstates_init(void)
"#size-cells",
};
- power_mgt = dt_find_by_path(dt_root, "/ibm,opal/power-mgt");
- if (power_mgt) {
- for (i = 0; i < ARRAY_SIZE(props); i++)
- dt_check_del_prop(power_mgt, props[i]);
+ for (i = 0; i < ARRAY_SIZE(props); i++)
+ dt_check_del_prop(power_mgt, props[i]);
- dt_for_each_child(power_mgt, child)
- if (!strncmp(child->name, "occ", 3))
- dt_free(child);
- }
+ dt_for_each_child(power_mgt, child)
+ if (!strncmp(child->name, "occ", 3))
+ dt_free(child);
}
switch (proc_gen) {
@@ -1816,7 +1798,7 @@ void occ_pstates_init(void)
* Check boundary conditions and add device tree nodes
* and return nominal pstate to set for the core
*/
- if (!add_cpu_pstate_properties(&pstate_nom)) {
+ if (!add_cpu_pstate_properties(power_mgt, &pstate_nom)) {
log_simple_error(&e_info(OPAL_RC_OCC_PSTATE_INIT),
"Skiping core cpufreq init due to OCC error\n");
} else if (proc_gen == proc_gen_p8) {
@@ -1840,6 +1822,23 @@ void occ_pstates_init(void)
/* Init OPAL-OCC command-response interface */
occ_cmd_interface_init();
+
+ /* TODO Firmware plumbing required so as to have two modes to set
+ * PMCR based on max in domain or most recently used. As of today,
+ * it is always max in domain for P9.
+ */
+ domain_runs_at = 0;
+ freq_domain_mask = 0;
+ if (proc_gen == proc_gen_p8) {
+ freq_domain_mask = P8_PIR_CORE_MASK;
+ domain_runs_at = FREQ_MOST_RECENTLY_SET;
+ } else if (proc_gen == proc_gen_p9) {
+ freq_domain_mask = P9_PIR_QUAD_MASK;
+ domain_runs_at = FREQ_MAX_IN_DOMAIN;
+ }
+
+ dt_add_property_cells(power_mgt, "freq-domain-mask", freq_domain_mask);
+ dt_add_property_cells(power_mgt, "domain-runs-at", domain_runs_at);
}
struct occ_load_req {