drm/amd/display: Wake DMCUB before executing GPINT commands
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dc_dmub_srv.c
index fea13bc..4b93e7a 100644 (file)
@@ -301,17 +301,11 @@ bool dc_dmub_srv_optimized_init_done(struct dc_dmub_srv *dc_dmub_srv)
 bool dc_dmub_srv_notify_stream_mask(struct dc_dmub_srv *dc_dmub_srv,
                                    unsigned int stream_mask)
 {
-       struct dmub_srv *dmub;
-       const uint32_t timeout = 30;
-
        if (!dc_dmub_srv || !dc_dmub_srv->dmub)
                return false;
 
-       dmub = dc_dmub_srv->dmub;
-
-       return dmub_srv_send_gpint_command(
-                      dmub, DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK,
-                      stream_mask, timeout) == DMUB_STATUS_OK;
+       return dc_wake_and_execute_gpint(dc_dmub_srv->ctx, DMUB_GPINT__IDLE_OPT_NOTIFY_STREAM_MASK,
+                                        stream_mask, NULL, DM_DMUB_WAIT_TYPE_WAIT);
 }
 
 bool dc_dmub_srv_is_restore_required(struct dc_dmub_srv *dc_dmub_srv)
@@ -1126,25 +1120,20 @@ bool dc_dmub_check_min_version(struct dmub_srv *srv)
 void dc_dmub_srv_enable_dpia_trace(const struct dc *dc)
 {
        struct dc_dmub_srv *dc_dmub_srv = dc->ctx->dmub_srv;
-       struct dmub_srv *dmub;
-       enum dmub_status status;
-       static const uint32_t timeout_us = 30;
 
        if (!dc_dmub_srv || !dc_dmub_srv->dmub) {
                DC_LOG_ERROR("%s: invalid parameters.", __func__);
                return;
        }
 
-       dmub = dc_dmub_srv->dmub;
-
-       status = dmub_srv_send_gpint_command(dmub, DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD1, 0x0010, timeout_us);
-       if (status != DMUB_STATUS_OK) {
+       if (!dc_wake_and_execute_gpint(dc->ctx, DMUB_GPINT__SET_TRACE_BUFFER_MASK_WORD1,
+                                      0x0010, NULL, DM_DMUB_WAIT_TYPE_WAIT)) {
                DC_LOG_ERROR("timeout updating trace buffer mask word\n");
                return;
        }
 
-       status = dmub_srv_send_gpint_command(dmub, DMUB_GPINT__UPDATE_TRACE_BUFFER_MASK, 0x0000, timeout_us);
-       if (status != DMUB_STATUS_OK) {
+       if (!dc_wake_and_execute_gpint(dc->ctx, DMUB_GPINT__UPDATE_TRACE_BUFFER_MASK,
+                                      0x0000, NULL, DM_DMUB_WAIT_TYPE_WAIT)) {
                DC_LOG_ERROR("timeout updating trace buffer mask word\n");
                return;
        }
@@ -1368,3 +1357,52 @@ bool dc_wake_and_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned in
 
        return result;
 }
+
+static bool dc_dmub_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_command command_code,
+                                 uint16_t param, uint32_t *response, enum dm_dmub_wait_type wait_type)
+{
+       struct dc_dmub_srv *dc_dmub_srv = ctx->dmub_srv;
+       const uint32_t wait_us = wait_type == DM_DMUB_WAIT_TYPE_NO_WAIT ? 0 : 30;
+       enum dmub_status status;
+
+       if (response)
+               *response = 0;
+
+       if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+               return false;
+
+       status = dmub_srv_send_gpint_command(dc_dmub_srv->dmub, command_code, param, wait_us);
+       if (status != DMUB_STATUS_OK) {
+               if (status == DMUB_STATUS_TIMEOUT && wait_type == DM_DMUB_WAIT_TYPE_NO_WAIT)
+                       return true;
+
+               return false;
+       }
+
+       if (response && wait_type == DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY)
+               dmub_srv_get_gpint_response(dc_dmub_srv->dmub, response);
+
+       return true;
+}
+
+bool dc_wake_and_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_command command_code,
+                              uint16_t param, uint32_t *response, enum dm_dmub_wait_type wait_type)
+{
+       struct dc_dmub_srv *dc_dmub_srv = ctx->dmub_srv;
+       bool result = false, reallow_idle = false;
+
+       if (!dc_dmub_srv || !dc_dmub_srv->dmub)
+               return false;
+
+       if (dc_dmub_srv->idle_allowed) {
+               dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, false);
+               reallow_idle = true;
+       }
+
+       result = dc_dmub_execute_gpint(ctx, command_code, param, response, wait_type);
+
+       if (result && reallow_idle)
+               dc_dmub_srv_apply_idle_power_optimizations(ctx->dc, true);
+
+       return result;
+}