diff options
-rw-r--r-- | external/opal-prd/opal-prd.c | 6 | ||||
-rw-r--r-- | hw/occ.c | 56 | ||||
-rw-r--r-- | hw/prd.c | 4 | ||||
-rw-r--r-- | include/opal-api.h | 1 | ||||
-rw-r--r-- | include/opal-internal.h | 1 |
5 files changed, 45 insertions, 23 deletions
diff --git a/external/opal-prd/opal-prd.c b/external/opal-prd/opal-prd.c index 56943c40..17239248 100644 --- a/external/opal-prd/opal-prd.c +++ b/external/opal-prd/opal-prd.c @@ -1381,6 +1381,7 @@ static void handle_prd_control_run_cmd(struct control_msg *send_msg, static void handle_prd_control(struct opal_prd_ctx *ctx, int fd) { struct control_msg msg, *recv_msg, *send_msg; + struct opal_prd_msg omsg; bool enabled = false; int rc, size; @@ -1433,6 +1434,11 @@ static void handle_prd_control(struct opal_prd_ctx *ctx, int fd) handle_prd_control_occ_actuation(send_msg, enabled); break; case CONTROL_MSG_TEMP_OCC_RESET: + omsg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY; + omsg.hdr.size = htobe16(sizeof(omsg)); + rc = write(ctx->fd, &omsg, sizeof(omsg)); + if (rc != sizeof(omsg)) + pr_log(LOG_WARNING, "FW: Failed to send OCC_RESET message: %m"); handle_prd_control_occ_reset(send_msg); break; case CONTROL_MSG_TEMP_OCC_ERROR: @@ -742,6 +742,38 @@ static void occ_do_load(u8 scope, u32 dbob_id __unused, u32 seq_id) __occ_do_load(scope, dbob_id, seq_id); } +int occ_msg_queue_occ_reset(void) +{ + struct opal_occ_msg occ_msg = { OCC_RESET, 0, 0 }; + struct proc_chip *chip; + int rc; + + lock(&occ_lock); + rc = _opal_queue_msg(OPAL_MSG_OCC, NULL, NULL, 3, + (uint64_t *)&occ_msg); + if (rc) { + prlog(PR_INFO, "OCC: Failed to queue OCC_RESET message\n"); + goto out; + } + /* + * 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->throttle = 0; + } + occ_reset = true; +out: + unlock(&occ_lock); + return rc; +} + static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id) { struct fsp_msg *rsp, *stat; @@ -790,8 +822,6 @@ 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 }; - /* Send a single success response for all chips */ stat = fsp_mkmsg(FSP_CMD_RESET_OCC_STAT, 2, 0, seq_id); if (stat) @@ -802,27 +832,7 @@ static void occ_do_reset(u8 scope, u32 dbob_id, u32 seq_id) "OCC: Error %d queueing FSP OCC RESET" " STATUS message\n", rc); } - lock(&occ_lock); - 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->throttle = 0; - } - occ_reset = true; - unlock(&occ_lock); + occ_msg_queue_occ_reset(); } else { /* @@ -182,6 +182,7 @@ static void send_next_pending_event(void) } else if (event & EVENT_OCC_RESET) { prd_msg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET; prd_msg.occ_reset.chip = proc; + occ_msg_queue_occ_reset(); } queue_prd_msg(&prd_msg, prd_msg_consumed); @@ -339,6 +340,9 @@ static int64_t opal_prd_msg(struct opal_prd_msg *msg) case OPAL_PRD_MSG_TYPE_ATTN_ACK: rc = prd_msg_handle_attn_ack(msg); break; + case OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY: + rc = occ_msg_queue_occ_reset(); + break; default: rc = OPAL_UNSUPPORTED; } diff --git a/include/opal-api.h b/include/opal-api.h index f607a416..05ff51dd 100644 --- a/include/opal-api.h +++ b/include/opal-api.h @@ -923,6 +923,7 @@ enum opal_prd_msg_type { OPAL_PRD_MSG_TYPE_ATTN_ACK, /* HBRT --> OPAL */ OPAL_PRD_MSG_TYPE_OCC_ERROR, /* HBRT <-- OPAL */ OPAL_PRD_MSG_TYPE_OCC_RESET, /* HBRT <-- OPAL */ + OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY, /* HBRT --> OPAL */ }; struct opal_prd_msg_header { diff --git a/include/opal-internal.h b/include/opal-internal.h index 2faaa468..583e9994 100644 --- a/include/opal-internal.h +++ b/include/opal-internal.h @@ -81,6 +81,7 @@ extern void opal_del_host_sync_notifier(bool (*notify)(void *data)); */ struct OpalHMIEvent; extern int handle_hmi_exception(__be64 hmer, struct OpalHMIEvent *hmi_evt); +extern int occ_msg_queue_occ_reset(void); extern unsigned long top_of_ram; |