From d06966c4d9eefa823dd25b87224c2c4c489630e2 Mon Sep 17 00:00:00 2001 From: Lakshmanan M Date: Mon, 7 Nov 2016 15:54:56 +0530 Subject: gpu: nvgpu: Add thermal alert event handling * Added the thermal alert event handling * Added the thermal alert event PMU RPC JIRA DNVGPU-130 Bug 200231080 Change-Id: I54ab0dc35a940e70733238fd95669db28389619a Signed-off-by: Lakshmanan M Reviewed-on: http://git-master/r/1248968 (cherry picked from commit a20593c89a374d64201e4720552160a65533ecc3) Reviewed-on: http://git-master/r/1282076 GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu --- drivers/gpu/nvgpu/therm/thrmpmu.c | 137 ++++++++++++++++++++++++++++++++++---- drivers/gpu/nvgpu/therm/thrmpmu.h | 2 +- 2 files changed, 125 insertions(+), 14 deletions(-) (limited to 'drivers/gpu/nvgpu/therm') diff --git a/drivers/gpu/nvgpu/therm/thrmpmu.c b/drivers/gpu/nvgpu/therm/thrmpmu.c index 0d0a4b3a..0f780730 100644 --- a/drivers/gpu/nvgpu/therm/thrmpmu.c +++ b/drivers/gpu/nvgpu/therm/thrmpmu.c @@ -77,9 +77,47 @@ exit: return status; } -u32 therm_set_warn_temp_limit(struct gk20a *g) +static u32 therm_pmu_cmd_post(struct gk20a *g, struct pmu_cmd *cmd, + struct pmu_msg *msg, struct pmu_payload *payload, + u32 queue_id, pmu_callback callback, void* cb_param, + u32 *seq_desc, unsigned long timeout) { u32 status; + struct therm_pmucmdhandler_params *handlerparams = NULL; + + status = gk20a_pmu_cmd_post(g, cmd, msg, payload, + queue_id, + callback, + cb_param, + seq_desc, + timeout); + if (status) { + gk20a_err(dev_from_gk20a(g), + "unable to post therm cmd for unit %x cmd id %x size %x", + cmd->hdr.unit_id, cmd->cmd.therm.cmd_type, cmd->hdr.size); + goto exit; + } + + if (cb_param) { + handlerparams = (struct therm_pmucmdhandler_params*)cb_param; + + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handlerparams->success, 1); + + if (handlerparams->success == 0) { + gk20a_err(dev_from_gk20a(g), "could not process cmd\n"); + status = -ETIMEDOUT; + goto exit; + } + } + +exit: + return status; +} + +static u32 therm_set_warn_temp_limit(struct gk20a *g) +{ u32 seqdesc = 0; struct pmu_cmd cmd = { {0} }; struct pmu_msg msg = { {0} }; @@ -94,7 +132,69 @@ u32 therm_set_warn_temp_limit(struct gk20a *g) rpccall.b_supported = 0; cmd.hdr.unit_id = PMU_UNIT_THERM; - cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd) + + cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + + (u32)sizeof(struct pmu_hdr)); + cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; + + msg.hdr.size = sizeof(struct pmu_msg); + + payload.in.buf = (u8 *)&rpccall; + payload.in.size = (u32)sizeof(struct nv_pmu_therm_rpc); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = NV_PMU_THERM_CMD_RPC_ALLOC_OFFSET; + + payload.out.buf = (u8 *)&rpccall; + payload.out.size = (u32)sizeof(struct nv_pmu_therm_rpc); + payload.out.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.out.offset = NV_PMU_CLK_MSG_RPC_ALLOC_OFFSET; + + /* Setup the handler params to communicate back results.*/ + handlerparams.success = 0; + handlerparams.prpccall = &rpccall; + + return therm_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + therm_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); +} + +static u32 therm_enable_slct_notification_request(struct gk20a *g) +{ + u32 seqdesc = 0; + struct pmu_cmd cmd = { {0} }; + + cmd.hdr.unit_id = PMU_UNIT_THERM; + cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_hw_slowdown_notification) + + (u32)sizeof(struct pmu_hdr)); + + cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_HW_SLOWDOWN_NOTIFICATION; + cmd.cmd.therm.hw_slct_notification.request = + NV_RM_PMU_THERM_HW_SLOWDOWN_NOTIFICATION_REQUEST_ENABLE; + + return therm_pmu_cmd_post(g, &cmd, NULL, NULL, + PMU_COMMAND_QUEUE_LPQ, + NULL, + NULL, + &seqdesc, ~0); +} + +static u32 therm_send_slct_configuration_to_pmu(struct gk20a *g) +{ + u32 seqdesc = 0; + struct pmu_cmd cmd = { {0} }; + struct pmu_msg msg = { {0} }; + struct pmu_payload payload = { {0} }; + struct nv_pmu_therm_rpc rpccall = {0}; + struct therm_pmucmdhandler_params handlerparams = {0}; + + rpccall.function = NV_PMU_THERM_RPC_ID_SLCT; + rpccall.params.slct.mask_enabled = + (1 << NV_PMU_THERM_EVENT_THERMAL_1); + rpccall.b_supported = 0; + + cmd.hdr.unit_id = PMU_UNIT_THERM; + cmd.hdr.size = ((u32)sizeof(struct nv_pmu_therm_cmd_rpc) + (u32)sizeof(struct pmu_hdr)); cmd.cmd.therm.cmd_type = NV_PMU_THERM_CMD_ID_RPC; @@ -114,29 +214,40 @@ u32 therm_set_warn_temp_limit(struct gk20a *g) handlerparams.success = 0; handlerparams.prpccall = &rpccall; - status = gk20a_pmu_cmd_post(g, &cmd, NULL, &payload, + return therm_pmu_cmd_post(g, &cmd, NULL, &payload, PMU_COMMAND_QUEUE_LPQ, therm_pmucmdhandler, (void *)&handlerparams, &seqdesc, ~0); +} + +u32 therm_configure_therm_alert(struct gk20a *g) +{ + u32 status; + + status = therm_enable_slct_notification_request(g); if (status) { gk20a_err(dev_from_gk20a(g), - "unable to post pmgr cmd for unit %x cmd id %x size %x", - cmd.hdr.unit_id, cmd.cmd.therm.cmd_type, cmd.hdr.size); + "therm_enable_slct_notification_request-failed %d", + status); goto exit; } - pmu_wait_message_cond(&g->pmu, - gk20a_get_gr_idle_timeout(g), - &handlerparams.success, 1); - - if (handlerparams.success == 0) { - gk20a_err(dev_from_gk20a(g), "could not process cmd\n"); - status = -ETIMEDOUT; + status = therm_send_slct_configuration_to_pmu(g); + if (status) { + gk20a_err(dev_from_gk20a(g), + "therm_send_slct_configuration_to_pmu-failed %d", + status); goto exit; } + status = therm_set_warn_temp_limit(g); + if (status) { + gk20a_err(dev_from_gk20a(g), + "therm_set_warn_temp_limit-failed %d", + status); + goto exit; + } exit: return status; } - diff --git a/drivers/gpu/nvgpu/therm/thrmpmu.h b/drivers/gpu/nvgpu/therm/thrmpmu.h index e6f70411..8f0d7501 100644 --- a/drivers/gpu/nvgpu/therm/thrmpmu.h +++ b/drivers/gpu/nvgpu/therm/thrmpmu.h @@ -17,6 +17,6 @@ u32 therm_send_pmgr_tables_to_pmu(struct gk20a *g); -u32 therm_set_warn_temp_limit(struct gk20a *g); +u32 therm_configure_therm_alert(struct gk20a *g); #endif -- cgit v1.2.2