From 3c44e37fd5c3d29c3cab012e360f1b8ea7f44f57 Mon Sep 17 00:00:00 2001 From: Eric Yang Date: Wed, 25 Nov 2015 16:13:55 -0500 Subject: [PATCH 0531/1110] drm/amd/dal: Move scaling param to commit surface and fix underscan flash 1. Move destination rectangle calculation to commit surface instead of commit targets. 2. Change set property so that there is no mode change only surface change. This fixes flashing of the screen when underscan adjustment is set. Signed-off-by: Eric Yang Signed-off-by: Harry Wentland Acked-by: Harry Wentland --- .../gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c | 131 ++++++++++++--------- drivers/gpu/drm/amd/dal/dc/basics/logger.c | 3 +- drivers/gpu/drm/amd/dal/dc/core/dc_resource.c | 21 ++++ drivers/gpu/drm/amd/dal/dc/core/dc_stream.c | 8 ++ drivers/gpu/drm/amd/dal/dc/dc.h | 3 + 5 files changed, 109 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c index 1b46426..113c2e0 100644 --- a/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c +++ b/drivers/gpu/drm/amd/dal/amdgpu_dm/amdgpu_dm_types.c @@ -568,9 +568,59 @@ struct amdgpu_connector *aconnector_from_drm_crtc_id( return NULL; } +static void calculate_stream_scaling_settings( + const struct drm_display_mode *mode, + const struct dc_stream *stream, + struct dm_connector_state *dm_state) +{ + enum amdgpu_rmx_type rmx_type; + + struct rect src = { 0 }; /* viewport in target space*/ + struct rect dst = { 0 }; /* stream addressable area */ + + /* Full screen scaling by default */ + src.width = mode->hdisplay; + src.height = mode->vdisplay; + dst.width = stream->timing.h_addressable; + dst.height = stream->timing.v_addressable; + + rmx_type = dm_state->scaling; + if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) { + if (src.width * dst.height < + src.height * dst.width) { + /* height needs less upscaling/more downscaling */ + dst.width = src.width * + dst.height / src.height; + } else { + /* width needs less upscaling/more downscaling */ + dst.height = src.height * + dst.width / src.width; + } + } else if (rmx_type == RMX_CENTER) { + dst = src; + } + + dst.x = (stream->timing.h_addressable - dst.width) / 2; + dst.y = (stream->timing.v_addressable - dst.height) / 2; + + if (dm_state->underscan_enable) { + dst.x += dm_state->underscan_hborder / 2; + dst.y += dm_state->underscan_vborder / 2; + dst.width -= dm_state->underscan_hborder; + dst.height -= dm_state->underscan_vborder; + } + + dc_update_stream(stream, &src, &dst); + + DRM_DEBUG_KMS("Destination Rectangle x:%d y:%d width:%d height:%d\n", + dst.x, dst.y, dst.width, dst.height); + +} + static void dm_dc_surface_commit( struct dc *dc, - struct drm_crtc *crtc) + struct drm_crtc *crtc, + struct dm_connector_state *dm_state) { struct dc_surface *dc_surface; const struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); @@ -593,8 +643,11 @@ static void dm_dc_surface_commit( goto fail; } - /* Surface programming */ + calculate_stream_scaling_settings(&crtc->state->mode, + dc_target->streams[0], + dm_state); + /* Surface programming */ fill_plane_attributes(dc_surface, crtc); if (crtc->mode.private_flags & AMDGPU_CRTC_MODE_PRIVATE_FLAGS_GAMMASET) { @@ -753,47 +806,6 @@ static void fill_audio_info( /*TODO: move these defines elsewhere*/ #define DAL_MAX_CONTROLLERS 4 -static void calculate_stream_scaling_settings( - const struct drm_display_mode *mode, - enum amdgpu_rmx_type rmx_type, - struct dc_stream *stream, - uint8_t underscan_vborder, - uint8_t underscan_hborder, - bool underscan_enable) -{ - /* Full screen scaling by default */ - stream->src.width = mode->hdisplay; - stream->src.height = mode->vdisplay; - stream->dst.width = stream->timing.h_addressable; - stream->dst.height = stream->timing.v_addressable; - - if (rmx_type == RMX_ASPECT || rmx_type == RMX_OFF) { - if (stream->src.width * stream->dst.height < - stream->src.height * stream->dst.width) { - /* height needs less upscaling/more downscaling */ - stream->dst.width = stream->src.width * - stream->dst.height / stream->src.height; - } else { - /* width needs less upscaling/more downscaling */ - stream->dst.height = stream->src.height * - stream->dst.width / stream->src.width; - } - } else if (rmx_type == RMX_CENTER) { - stream->dst = stream->src; - } - - stream->dst.x = (stream->timing.h_addressable - stream->dst.width) / 2; - stream->dst.y = (stream->timing.v_addressable - stream->dst.height) / 2; - - if (underscan_enable) { - stream->dst.x += underscan_hborder / 2; - stream->dst.y += underscan_vborder / 2; - stream->dst.width -= underscan_hborder; - stream->dst.height -= underscan_vborder; - } -} - - static void copy_crtc_timing_for_drm_display_mode( const struct drm_display_mode *src_mode, struct drm_display_mode *dst_mode) @@ -877,12 +889,6 @@ static struct dc_target *create_target_for_sink( dc_timing_from_drm_display_mode(&stream->timing, &mode, &aconnector->base); - calculate_stream_scaling_settings(&mode, dm_state->scaling, stream, - dm_state->underscan_vborder, - dm_state->underscan_hborder, - dm_state->underscan_enable); - - fill_audio_info( &stream->audio_info, drm_connector, @@ -1079,8 +1085,6 @@ int amdgpu_dm_connector_atomic_set_property( if (crtc == state->crtc) { struct drm_plane_state *plane_state; - new_crtc_state->mode_changed = true; - /* * Bit of magic done here. We need to ensure * that planes get update after mode is set. @@ -1122,6 +1126,9 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) if (state) { state->scaling = RMX_OFF; + state->underscan_enable = false; + state->underscan_hborder = 0; + state->underscan_vborder = 0; connector->state = &state->base; connector->state->connector = connector; @@ -2180,10 +2187,10 @@ int amdgpu_dm_atomic_commit( struct drm_plane_state *plane_state = plane->state; struct drm_crtc *crtc = plane_state->crtc; struct drm_framebuffer *fb = plane_state->fb; + struct drm_connector *connector; - if (fb && crtc) { - if (!crtc->state->planes_changed) - continue; + if (fb && crtc && crtc->state->planes_changed) { + struct dm_connector_state *dm_state = NULL; if (page_flip_needed( plane_state, @@ -2193,8 +2200,20 @@ int amdgpu_dm_atomic_commit( fb, crtc->state->event, 0); - else - dm_dc_surface_commit(dm->dc, crtc); + else { + list_for_each_entry(connector, + &dev->mode_config.connector_list, head) { + if (connector->state->crtc == crtc) { + dm_state = to_dm_connector_state(connector->state); + break; + } + } + + dm_dc_surface_commit( + dm->dc, + crtc, + dm_state); + } } } diff --git a/drivers/gpu/drm/amd/dal/dc/basics/logger.c b/drivers/gpu/drm/amd/dal/dc/basics/logger.c index 50db743..5aadda7 100644 --- a/drivers/gpu/drm/amd/dal/dc/basics/logger.c +++ b/drivers/gpu/drm/amd/dal/dc/basics/logger.c @@ -237,6 +237,7 @@ struct log_major_mask_info { (1 << LOG_MINOR_HW_TRACE_HPD_IRQ) #define LG_HW_TR_PLANES_MSK (1 << LOG_MINOR_HW_TRACE_MPO) #define LG_ALL_MSK 0xffffffff +#define LG_DCP_MSK ~(1 << LOG_MINOR_DCP_SCALER) #define LG_SYNC_MSK (1 << LOG_MINOR_SYNC_TIMING) @@ -254,7 +255,7 @@ static const struct log_major_mask_info log_major_mask_info_tbl[] = { hw_trace_minor_info_tbl, NUM_ELEMENTS(hw_trace_minor_info_tbl)}, {{LOG_MAJOR_MST, "MST" }, LG_ALL_MSK, mst_minor_info_tbl, NUM_ELEMENTS(mst_minor_info_tbl)}, {{LOG_MAJOR_DCS, "DCS" }, LG_ALL_MSK, dcs_minor_info_tbl, NUM_ELEMENTS(dcs_minor_info_tbl)}, - {{LOG_MAJOR_DCP, "DCP" }, LG_ALL_MSK, dcp_minor_info_tbl, NUM_ELEMENTS(dcp_minor_info_tbl)}, + {{LOG_MAJOR_DCP, "DCP" }, LG_DCP_MSK, dcp_minor_info_tbl, NUM_ELEMENTS(dcp_minor_info_tbl)}, {{LOG_MAJOR_BIOS, "Bios" }, LG_ALL_MSK, bios_minor_info_tbl, NUM_ELEMENTS(bios_minor_info_tbl)}, {{LOG_MAJOR_REGISTER, "Register" }, LG_ALL_MSK, reg_minor_info_tbl, NUM_ELEMENTS(reg_minor_info_tbl)}, {{LOG_MAJOR_INFO_PACKETS, "InfoPacket" }, LG_ALL_MSK, info_packet_minor_info_tbl, NUM_ELEMENTS(info_packet_minor_info_tbl)}, diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c index 082fb02..e5b1d02 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_resource.c @@ -330,6 +330,27 @@ void build_scaling_params( stream->taps.v_taps_c = 1; else stream->taps.v_taps_c = surface->scaling_quality.v_taps_c; + + dal_logger_write(stream->ctx->logger, + LOG_MAJOR_DCP, + LOG_MINOR_DCP_SCALER, + "%s: Overscan:\n bot:%d left:%d right:%d " + "top:%d\nViewport:\nheight:%d width:%d x:%d " + "y:%d\n dst_rect:\nheight:%d width:%d x:%d " + "y:%d\n", + __func__, + stream->overscan.bottom, + stream->overscan.left, + stream->overscan.right, + stream->overscan.top, + stream->viewport.height, + stream->viewport.width, + stream->viewport.x, + stream->viewport.y, + surface->dst_rect.height, + surface->dst_rect.width, + surface->dst_rect.x, + surface->dst_rect.y); } void build_scaling_params_for_context( diff --git a/drivers/gpu/drm/amd/dal/dc/core/dc_stream.c b/drivers/gpu/drm/amd/dal/dc/core/dc_stream.c index 1a7bf50..986368a 100644 --- a/drivers/gpu/drm/amd/dal/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/dal/dc/core/dc_stream.c @@ -168,5 +168,13 @@ alloc_fail: return NULL; } +void dc_update_stream(const struct dc_stream *dc_stream, + struct rect *src, + struct rect *dst) +{ + struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream); + stream->public.src = *src; + stream->public.dst = *dst; +} diff --git a/drivers/gpu/drm/amd/dal/dc/dc.h b/drivers/gpu/drm/amd/dal/dc/dc.h index 1db9395..0cb9d77 100644 --- a/drivers/gpu/drm/amd/dal/dc/dc.h +++ b/drivers/gpu/drm/amd/dal/dc/dc.h @@ -258,6 +258,9 @@ struct dc_stream *dc_create_stream_for_sink(const struct dc_sink *dc_sink); void dc_stream_retain(struct dc_stream *dc_stream); void dc_stream_release(struct dc_stream *dc_stream); +void dc_update_stream(const struct dc_stream *dc_stream, + struct rect *src, struct rect *dst); + /******************************************************************************* * Link Interfaces ******************************************************************************/ -- 2.7.4