Blob Blame History Raw
From f1cdc98fd9d9bb0eb4b6599825b52ce25757eb9f Mon Sep 17 00:00:00 2001
From: Dingchen Zhang <dingchen.zhang@amd.com>
Date: Fri, 28 Jun 2019 17:23:24 -0400
Subject: drm/amd/display: add pipe CRC sources without disabling dithering.
Git-commit: f1cdc98fd9d9bb0eb4b6599825b52ce25757eb9f
Patch-mainline: v5.4-rc1
References: bsc#1152489

[Why]
need to verify the impact of spatial dithering on 8bpc bypass mode.

[How]
added CRC sources and configure dihter option from dc stream.

Signed-off-by: Dingchen Zhang <dingchen.zhang@amd.com>
Reviewed-by: Hanghong Ma <Hanghong.Ma@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 58 ++++++++++++++-----
 .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h |  6 +-
 2 files changed, 48 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
index b966e1410484..365aaef3ecaf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
@@ -33,7 +33,9 @@
 static const char *const pipe_crc_sources[] = {
 	"none",
 	"crtc",
+	"crtc dither",
 	"dprx",
+	"dprx dither",
 	"auto",
 };
 
@@ -45,10 +47,33 @@ static enum amdgpu_dm_pipe_crc_source dm_parse_crc_source(const char *source)
 		return AMDGPU_DM_PIPE_CRC_SOURCE_CRTC;
 	if (!strcmp(source, "dprx"))
 		return AMDGPU_DM_PIPE_CRC_SOURCE_DPRX;
+	if (!strcmp(source, "crtc dither"))
+		return AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER;
+	if (!strcmp(source, "dprx dither"))
+		return AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER;
 
 	return AMDGPU_DM_PIPE_CRC_SOURCE_INVALID;
 }
 
+static bool dm_is_crc_source_crtc(enum amdgpu_dm_pipe_crc_source src)
+{
+	return (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER);
+}
+
+static bool dm_is_crc_source_dprx(enum amdgpu_dm_pipe_crc_source src)
+{
+	return (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER);
+}
+
+static bool dm_need_crc_dither(enum amdgpu_dm_pipe_crc_source src)
+{
+	return (src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER) ||
+	       (src == AMDGPU_DM_PIPE_CRC_SOURCE_NONE);
+}
+
 const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc,
 						  size_t *count)
 {
@@ -102,14 +127,18 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 	 * USER REQ SRC | CURRENT SRC | BEHAVIOR
 	 * -----------------------------
 	 * None         | None        | Do nothing
-	 * None         | CRTC        | Disable CRTC CRC
-	 * None         | DPRX        | Disable DPRX CRC, need 'aux'
-	 * CRTC         | XXXX        | Enable CRTC CRC, configure DC strm
-	 * DPRX         | XXXX        | Enable DPRX CRC, need 'aux'
+	 * None         | CRTC        | Disable CRTC CRC, set default to dither
+	 * None         | DPRX        | Disable DPRX CRC, need 'aux', set default to dither
+	 * None         | CRTC DITHER | Disable CRTC CRC
+	 * None         | DPRX DITHER | Disable DPRX CRC, need 'aux'
+	 * CRTC         | XXXX        | Enable CRTC CRC, no dither
+	 * DPRX         | XXXX        | Enable DPRX CRC, need 'aux', no dither
+	 * CRTC DITHER  | XXXX        | Enable CRTC CRC, set dither
+	 * DPRX DITHER  | XXXX        | Enable DPRX CRC, need 'aux', set dither
 	 */
-	if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX ||
+	if (dm_is_crc_source_dprx(source) ||
 		(source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE &&
-		 crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX)) {
+		 dm_is_crc_source_dprx(crtc_state->crc_src))) {
 		aconn = stream_state->link->priv;
 
 		if (!aconn) {
@@ -125,7 +154,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 			mutex_unlock(&adev->dm.dc_lock);
 			return -EINVAL;
 		}
-	} else if (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) {
+	} else if (dm_is_crc_source_crtc(source)) {
 		if (!dc_stream_configure_crc(stream_state->ctx->dc, stream_state,
 					     enable, enable)) {
 			mutex_unlock(&adev->dm.dc_lock);
@@ -133,10 +162,11 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 		}
 	}
 
-	/* When enabling CRC, we should also disable dithering. */
-	dc_stream_set_dither_option(stream_state,
-				    enable ? DITHER_OPTION_TRUN8
-					   : DITHER_OPTION_DEFAULT);
+	/* configure dithering */
+	if (!dm_need_crc_dither(source))
+		dc_stream_set_dither_option(stream_state, DITHER_OPTION_TRUN8);
+	else if (!dm_need_crc_dither(crtc_state->crc_src))
+		dc_stream_set_dither_option(stream_state, DITHER_OPTION_DEFAULT);
 
 	mutex_unlock(&adev->dm.dc_lock);
 
@@ -147,7 +177,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 	enabled = amdgpu_dm_is_valid_crc_source(crtc_state->crc_src);
 	if (!enabled && enable) {
 		drm_crtc_vblank_get(crtc);
-		if (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) {
+		if (dm_is_crc_source_dprx(source)) {
 			if (drm_dp_start_crc(aux, crtc)) {
 				DRM_DEBUG_DRIVER("dp start crc failed\n");
 				return -EINVAL;
@@ -155,7 +185,7 @@ int amdgpu_dm_crtc_set_crc_source(struct drm_crtc *crtc, const char *src_name)
 		}
 	} else if (enabled && !enable) {
 		drm_crtc_vblank_put(crtc);
-		if (crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX) {
+		if (dm_is_crc_source_dprx(source)) {
 			if (drm_dp_stop_crc(aux)) {
 				DRM_DEBUG_DRIVER("dp stop crc failed\n");
 				return -EINVAL;
@@ -204,7 +234,7 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc)
 		return;
 	}
 
-	if (crtc_state->crc_src == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) {
+	if (dm_is_crc_source_crtc(crtc_state->crc_src)) {
 		if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state,
 				       &crcs[0], &crcs[1], &crcs[2]))
 			return;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
index b63a9011f511..14de7301c28d 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h
@@ -29,15 +29,17 @@
 enum amdgpu_dm_pipe_crc_source {
 	AMDGPU_DM_PIPE_CRC_SOURCE_NONE = 0,
 	AMDGPU_DM_PIPE_CRC_SOURCE_CRTC,
+	AMDGPU_DM_PIPE_CRC_SOURCE_CRTC_DITHER,
 	AMDGPU_DM_PIPE_CRC_SOURCE_DPRX,
+	AMDGPU_DM_PIPE_CRC_SOURCE_DPRX_DITHER,
 	AMDGPU_DM_PIPE_CRC_SOURCE_MAX,
 	AMDGPU_DM_PIPE_CRC_SOURCE_INVALID = -1,
 };
 
 static inline bool amdgpu_dm_is_valid_crc_source(enum amdgpu_dm_pipe_crc_source source)
 {
-	return (source == AMDGPU_DM_PIPE_CRC_SOURCE_CRTC) ||
-		   (source == AMDGPU_DM_PIPE_CRC_SOURCE_DPRX);
+	return (source > AMDGPU_DM_PIPE_CRC_SOURCE_NONE) &&
+	       (source < AMDGPU_DM_PIPE_CRC_SOURCE_MAX);
 }
 
 /* amdgpu_dm_crc.c */
-- 
2.28.0