<html>
<head>
<meta content="text/html; charset=windows-1252"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<br>
<br>
<div class="moz-cite-prefix">On 06/03/2015 06:24 PM, Shilpasri G
Bhat wrote:<br>
</div>
<blockquote
cite="mid:1433336061-17438-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com"
type="cite">
<pre wrap="">
+static void occ_throttle_poll(void *data __unused)
+{
+ struct proc_chip *chip;
+ struct occ_pstate_table *occ_data;
+ struct opal_occ_msg occ_msg;
+ int rc;
+
+ if (occ_reset) {
+ int inactive = 0;
+
+ for_each_chip(chip) {
+ occ_data = chip_occ_data(chip);
+ if (occ_data->valid != 1) {
+ inactive = 1;
+ break;
+ }
+ }
+ if (!inactive) {
+ /*
+ * Queue OCC_THROTTLE with throttle status as 0 to
+ * indicate all OCCs are active after a reset.
+ */
+ occ_msg.type = OCC_THROTTLE;
+ occ_msg.chip = 0;
+ occ_msg.throttle_status = 0;
+ rc = _opal_queue_msg(OPAL_MSG_OCC, NULL, NULL, 3,
+ (uint64_t *)&occ_msg);
+ if (!rc)
+ occ_reset = false;
+ }
+ } else {
+ for_each_chip(chip) {
+ occ_data = chip_occ_data(chip);
+ if ((occ_data->valid == 1) &&
+ (chip->prev_throttle != occ_data->throttle) &&
+ (occ_data->throttle <= OCC_MAX_THROTTLE_STATUS)) {
+ occ_msg.type = OCC_THROTTLE;
+ occ_msg.chip = chip->id;
+ occ_msg.throttle_status = occ_data->throttle;
+ rc = _opal_queue_msg(OPAL_MSG_OCC, NULL, NULL,
+ 3, (uint64_t *)&occ_msg);
+ if (!rc)
+ chip->prev_throttle =
+ occ_data->throttle;
+ } else if (occ_data->valid == 0) {
+ occ_msg.type = OCC_RESET;
+ occ_msg.chip = 0;
+ occ_msg.throttle_status = 0;
+ rc = _opal_queue_msg(OPAL_MSG_OCC, NULL, NULL,
+ 3, (uint64_t *)&occ_msg);
+ if (!rc)
+ occ_reset = true;</pre>
</blockquote>
<br>
<small>OCC in reset, should we 'break' here ?<br>
Otherwise, it start sending 'OCC_THROTTLE' before recovering..<br>
</small><br>
<blockquote
cite="mid:1433336061-17438-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com"
type="cite">
<pre wrap="">
+ }
+ }
+ }
+}
+
/* CPU-OCC PState init */
/* Called after OCC init on P8 */
void occ_pstates_init(void)
@@ -345,6 +410,11 @@ void occ_pstates_init(void)
cpu_pstates_prepare_core(chip, c, pstate_nom);
}
}
+
+ /* Add opal_poller to poll OCC throttle status of each chip */
+ for_each_chip(chip)
+ chip->prev_throttle = 0;
+ opal_add_poller(occ_throttle_poll, NULL);
}
struct occ_load_req {
@@ -386,6 +456,14 @@ static void __occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id)
prlog(PR_INFO, "OCC: Load: Fallback to preloaded image\n");
rc = 0;
} else if (!rc) {
+ struct opal_occ_msg occ_msg = { OCC_LOAD, 0, 0 };
+
+ rc = _opal_queue_msg(OPAL_MSG_OCC, NULL, NULL, 3,
+ (uint64_t *)&occ_msg);
+ if (rc)
+ prlog(PR_INFO, "OCC: Failed to queue message %d\n",
+ OCC_LOAD);
+
/* Success, start OCC */
rc = host_services_occ_start();
}
@@ -509,6 +587,27 @@ static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id)
rc = 0;
}
if (!rc) {
+ struct opal_occ_msg occ_msg = { OCC_RESET, 0, 0 };
+
+ rc = _opal_queue_msg(OPAL_MSG_OCC, NULL, NULL, 3,
+ (uint64_t *)&occ_msg);
+ if (rc)
+ prlog(PR_INFO, "OCC: Failed to queue message %d\n",
+ OCC_RESET);
+ /*
+ * Set 'valid' byte of chip_occ_data to 0 since OCC
+ * may not clear this byte on a reset.
+ * OCC will set the 'valid' byte to 1 when it becomes
+ * active again.
+ */
+ for_each_chip(chip) {
+ struct occ_pstate_table *occ_data;
+
+ occ_data = chip_occ_data(chip);
+ occ_data->valid = 0;
+ chip->prev_throttle = 0;
+ }
+ occ_reset = true;
/* Send a single success response for all chips */
stat = fsp_mkmsg(FSP_CMD_RESET_OCC_STAT, 2, 0, seq_id);
if (stat)
diff --git a/include/chip.h b/include/chip.h
index 1b4f4c4..5b57c87 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -147,6 +147,7 @@ struct proc_chip {
uint64_t homer_size;
uint64_t occ_common_base;
uint64_t occ_common_size;
+ u8 prev_throttle;</pre>
</blockquote>
<br>
<small>It is common chip structure shared across and contains the
prevailing value<br>
of 'throttle' until we read the new occ data.. so I think
'throttle' is apt here.. :)<br>
<br>
Rest looks good to me.<br>
<br>
Neelesh.<br>
</small><br>
<blockquote
cite="mid:1433336061-17438-1-git-send-email-shilpa.bhat@linux.vnet.ibm.com"
type="cite">
<pre wrap="">
/* Must hold capi_lock to change */
u8 capp_phb3_attached_mask;
diff --git a/include/opal-api.h b/include/opal-api.h
index 29421c1..ba35543 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -418,6 +418,7 @@ enum opal_msg_type {
OPAL_MSG_HMI_EVT,
OPAL_MSG_DPO,
OPAL_MSG_PRD,
+ OPAL_MSG_OCC,
OPAL_MSG_TYPE_MAX,
};
@@ -882,6 +883,30 @@ struct opal_prd_msg {
};
};
+#define OCC_RESET 0
+#define OCC_LOAD 1
+#define OCC_THROTTLE 2
+#define OCC_MAX_THROTTLE_STATUS 5
+/*
+ * struct opal_occ_msg:
+ * type: OCC_RESET, OCC_LOAD, OCC_THROTTLE
+ * chip: chip id
+ * throttle status: indicates the reason why OCC may have limited
+ * the max Pstate of the chip.
+ * 0x00 = No throttle
+ * 0x01 = Power Cap
+ * 0x02 = Processor Over Temperature
+ * 0x03 = Power Supply Failure (currently not used)
+ * 0x04 = Over current (currently not used)
+ * 0x05 = OCC Reset (not reliable as some failures will not allow for
+ * OCC to update throttle status)
+ */
+struct opal_occ_msg {
+ __be64 type;
+ __be64 chip;
+ __be64 throttle_status;
+};
+
/*
* SG entries
*
</pre>
</blockquote>
<br>
</body>
</html>