aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0531-drm-amd-dal-Move-scaling-param-to-commit-surface-and.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0531-drm-amd-dal-Move-scaling-param-to-commit-surface-and.patch')
-rw-r--r--common/recipes-kernel/linux/files/0531-drm-amd-dal-Move-scaling-param-to-commit-surface-and.patch305
1 files changed, 305 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0531-drm-amd-dal-Move-scaling-param-to-commit-surface-and.patch b/common/recipes-kernel/linux/files/0531-drm-amd-dal-Move-scaling-param-to-commit-surface-and.patch
new file mode 100644
index 00000000..26447c5d
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0531-drm-amd-dal-Move-scaling-param-to-commit-surface-and.patch
@@ -0,0 +1,305 @@
+From 3c44e37fd5c3d29c3cab012e360f1b8ea7f44f57 Mon Sep 17 00:00:00 2001
+From: Eric Yang <eric.yang2@amd.com>
+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 <eric.yang2@amd.com>
+Signed-off-by: Harry Wentland <harry.wentland@amd.com>
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+---
+ .../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
+