diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/core/dc.c | 54 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dc.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/inc/hw/abm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h | 54 |
5 files changed, 132 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 331a7517176b..644005846433 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -3536,3 +3536,57 @@ void dc_disable_accelerated_mode(struct dc *dc) { bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 0); } + + +/** + ***************************************************************************** + * dc_notify_vsync_int_state() - notifies vsync enable/disable state + * @dc: dc structure + * @stream: stream where vsync int state changed + * @enable: whether vsync is enabled or disabled + * + * Called when vsync is enabled/disabled + * Will notify DMUB to start/stop ABM interrupts after steady state is reached + * + ***************************************************************************** + */ +void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable) +{ + int i; + int edp_num; + struct pipe_ctx *pipe = NULL; + struct dc_link *link = stream->sink->link; + struct dc_link *edp_links[MAX_NUM_EDP]; + + + if (link->psr_settings.psr_feature_enabled) + return; + + /*find primary pipe associated with stream*/ + for (i = 0; i < MAX_PIPES; i++) { + pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + + if (pipe->stream == stream && pipe->stream_res.tg) + break; + } + + if (i == MAX_PIPES) { + ASSERT(0); + return; + } + + get_edp_links(dc, edp_links, &edp_num); + + /* Determine panel inst */ + for (i = 0; i < edp_num; i++) { + if (edp_links[i] == link) + break; + } + + if (i == edp_num) { + return; + } + + if (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause) + pipe->stream_res.abm->funcs->set_abm_pause(pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst); +} diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index e5dcbee6e672..b194a2727bd8 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1313,6 +1313,8 @@ void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src); enum dc_irq_source dc_get_hpd_irq_source_at_index( struct dc *dc, uint32_t link_index); +void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bool enable); + /******************************************************************************* * Power Interfaces ******************************************************************************/ diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index 54a1408c8015..fb0dec4ed3a6 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -203,12 +203,33 @@ static bool dmub_abm_init_config(struct abm *abm, return true; } +static bool dmub_abm_set_pause(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int stream_inst) +{ + union dmub_rb_cmd cmd; + struct dc_context *dc = abm->ctx; + uint8_t panel_mask = 0x01 << panel_inst; + + memset(&cmd, 0, sizeof(cmd)); + cmd.abm_pause.header.type = DMUB_CMD__ABM; + cmd.abm_pause.header.sub_type = DMUB_CMD__ABM_PAUSE; + cmd.abm_pause.abm_pause_data.enable = pause; + cmd.abm_pause.abm_pause_data.panel_mask = panel_mask; + cmd.abm_set_level.header.payload_bytes = sizeof(struct dmub_cmd_abm_pause_data); + + dc_dmub_srv_cmd_queue(dc->dmub_srv, &cmd); + dc_dmub_srv_cmd_execute(dc->dmub_srv); + dc_dmub_srv_wait_idle(dc->dmub_srv); + + return true; +} + static const struct abm_funcs abm_funcs = { .abm_init = dmub_abm_init, .set_abm_level = dmub_abm_set_level, .get_current_backlight = dmub_abm_get_current_backlight, .get_target_backlight = dmub_abm_get_target_backlight, .init_abm_config = dmub_abm_init_config, + .set_abm_pause = dmub_abm_set_pause, }; static void dmub_abm_construct( diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h index 142753644377..ecb4191b6e64 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/abm.h @@ -54,6 +54,7 @@ struct abm_funcs { const char *src, unsigned int bytes, unsigned int inst); + bool (*set_abm_pause)(struct abm *abm, bool pause, unsigned int panel_inst, unsigned int otg_inst); }; #endif diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 4647129c66fd..70e6d6905fda 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -1731,6 +1731,11 @@ enum dmub_cmd_abm_type { * Enable/disable fractional duty cycle for backlight PWM. */ DMUB_CMD__ABM_SET_PWM_FRAC = 5, + + /** + * unregister vertical interrupt after steady state is reached + */ + DMUB_CMD__ABM_PAUSE = 6, }; /** @@ -2087,6 +2092,50 @@ struct dmub_rb_cmd_abm_init_config { }; /** + * Data passed from driver to FW in a DMUB_CMD__ABM_PAUSE command. + */ + +struct dmub_cmd_abm_pause_data { + + /** + * Panel Control HW instance mask. + * Bit 0 is Panel Control HW instance 0. + * Bit 1 is Panel Control HW instance 1. + */ + uint8_t panel_mask; + + /** + * OTG hw instance + */ + uint8_t otg_inst; + + /** + * Enable or disable ABM pause + */ + uint8_t enable; + + /** + * Explicit padding to 4 byte boundary. + */ + uint8_t pad[1]; +}; + +/** + * Definition of a DMUB_CMD__ABM_PAUSE command. + */ +struct dmub_rb_cmd_abm_pause { + /** + * Command header. + */ + struct dmub_cmd_header header; + + /** + * Data passed from driver to FW in a DMUB_CMD__ABM_PAUSE command. + */ + struct dmub_cmd_abm_pause_data abm_pause_data; +}; + +/** * Data passed from driver to FW in a DMUB_CMD__QUERY_FEATURE_CAPS command. */ struct dmub_cmd_query_feature_caps_data { @@ -2365,6 +2414,11 @@ union dmub_rb_cmd { struct dmub_rb_cmd_abm_init_config abm_init_config; /** + * Definition of a DMUB_CMD__ABM_PAUSE command. + */ + struct dmub_rb_cmd_abm_pause abm_pause; + + /** * Definition of a DMUB_CMD__DP_AUX_ACCESS command. */ struct dmub_rb_cmd_dp_aux_access dp_aux_access; |