diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc')
5 files changed, 80 insertions, 17 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c index eeb04471b2f5..6d1c4981a185 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c @@ -1997,6 +1997,19 @@ bool dc_link_set_backlight_level(const struct dc_link *link, uint32_t level, return true; } +bool dc_link_set_abm_disable(const struct dc_link *link) +{ + struct dc *core_dc = link->ctx->dc; + struct abm *abm = core_dc->res_pool->abm; + + if ((abm == NULL) || (abm->funcs->set_backlight_level == NULL)) + return false; + + abm->funcs->set_abm_immediate_disable(abm); + + return true; +} + bool dc_link_set_psr_enable(const struct dc_link *link, bool enable, bool wait) { struct dc *core_dc = link->ctx->dc; diff --git a/drivers/gpu/drm/amd/display/dc/dc_link.h b/drivers/gpu/drm/amd/display/dc/dc_link.h index fb4d9eafdc6e..dc34515ef01f 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_link.h +++ b/drivers/gpu/drm/amd/display/dc/dc_link.h @@ -132,6 +132,8 @@ static inline struct dc_link *dc_get_link_at_index(struct dc *dc, uint32_t link_ bool dc_link_set_backlight_level(const struct dc_link *dc_link, uint32_t level, uint32_t frame_ramp, const struct dc_stream_state *stream); +bool dc_link_set_abm_disable(const struct dc_link *dc_link); + bool dc_link_set_psr_enable(const struct dc_link *dc_link, bool enable, bool wait); bool dc_link_get_psr_state(const struct dc_link *dc_link, uint32_t *psr_state); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 444558ca6533..162f6a6c4208 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -735,6 +735,8 @@ static void dce110_stream_encoder_update_hdmi_info_packets( if (info_frame->avi.valid) { const uint32_t *content = (const uint32_t *) &info_frame->avi.sb[0]; + /*we need turn on clock before programming AFMT block*/ + REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); REG_WRITE(AFMT_AVI_INFO0, content[0]); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index 775d3bf0bd39..9150d2694450 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c @@ -102,6 +102,43 @@ static uint32_t align_to_chunks_number_per_line(uint32_t pixels) return 256 * ((pixels + 255) / 256); } +static void reset_lb_on_vblank(struct dc_context *ctx) +{ + uint32_t value, frame_count; + uint32_t retry = 0; + uint32_t status_pos = + dm_read_reg(ctx, mmCRTC_STATUS_POSITION); + + + /* Only if CRTC is enabled and counter is moving we wait for one frame. */ + if (status_pos != dm_read_reg(ctx, mmCRTC_STATUS_POSITION)) { + /* Resetting LB on VBlank */ + value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL); + set_reg_field_value(value, 3, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL); + set_reg_field_value(value, 1, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2); + dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value); + + frame_count = dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT); + + + for (retry = 100; retry > 0; retry--) { + if (frame_count != dm_read_reg(ctx, mmCRTC_STATUS_FRAME_COUNT)) + break; + msleep(1); + } + if (!retry) + dm_error("Frame count did not increase for 100ms.\n"); + + /* Resetting LB on VBlank */ + value = dm_read_reg(ctx, mmLB_SYNC_RESET_SEL); + set_reg_field_value(value, 2, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL); + set_reg_field_value(value, 0, LB_SYNC_RESET_SEL, LB_SYNC_RESET_SEL2); + dm_write_reg(ctx, mmLB_SYNC_RESET_SEL, value); + + } + +} + static void wait_for_fbc_state_changed( struct dce110_compressor *cp110, bool enabled) @@ -232,19 +269,23 @@ void dce110_compressor_disable_fbc(struct compressor *compressor) { struct dce110_compressor *cp110 = TO_DCE110_COMPRESSOR(compressor); - if (compressor->options.bits.FBC_SUPPORT && - dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) { - uint32_t reg_data; - /* Turn off compression */ - reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL); - set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN); - dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data); - - /* Reset enum controller_id to undefined */ - compressor->attached_inst = 0; - compressor->is_enabled = false; - - wait_for_fbc_state_changed(cp110, false); + if (compressor->options.bits.FBC_SUPPORT) { + if (dce110_compressor_is_fbc_enabled_in_hw(compressor, NULL)) { + uint32_t reg_data; + /* Turn off compression */ + reg_data = dm_read_reg(compressor->ctx, mmFBC_CNTL); + set_reg_field_value(reg_data, 0, FBC_CNTL, FBC_GRPH_COMP_EN); + dm_write_reg(compressor->ctx, mmFBC_CNTL, reg_data); + + /* Reset enum controller_id to undefined */ + compressor->attached_inst = 0; + compressor->is_enabled = false; + + wait_for_fbc_state_changed(cp110, false); + } + + /* Sync line buffer - dce100/110 only*/ + reset_lb_on_vblank(compressor->ctx); } } diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 30dd62f0f5fa..d0575999f172 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -453,10 +453,13 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, } else { /* 10 segments - * segment is from 2^-10 to 2^0 + * segment is from 2^-10 to 2^1 + * We include an extra segment for range [2^0, 2^1). This is to + * ensure that colors with normalized values of 1 don't miss the + * LUT. */ region_start = -10; - region_end = 0; + region_end = 1; seg_distr[0] = 4; seg_distr[1] = 4; @@ -468,7 +471,7 @@ dce110_translate_regamma_to_hw_format(const struct dc_transfer_func *output_tf, seg_distr[7] = 4; seg_distr[8] = 4; seg_distr[9] = 4; - seg_distr[10] = -1; + seg_distr[10] = 0; seg_distr[11] = -1; seg_distr[12] = -1; seg_distr[13] = -1; @@ -1016,8 +1019,10 @@ void dce110_blank_stream(struct pipe_ctx *pipe_ctx) struct dc_stream_state *stream = pipe_ctx->stream; struct dc_link *link = stream->sink->link; - if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) + if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { link->dc->hwss.edp_backlight_control(link, false); + dc_link_set_abm_disable(link); + } if (dc_is_dp_signal(pipe_ctx->stream->signal)) pipe_ctx->stream_res.stream_enc->funcs->dp_blank(pipe_ctx->stream_res.stream_enc); |