drm/amd/display: add pipe CRC sources without disabling dithering.
authorDingchen Zhang <dingchen.zhang@amd.com>
Fri, 28 Jun 2019 21:23:24 +0000 (17:23 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 18 Jul 2019 19:27:25 +0000 (14:27 -0500)
[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>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h

index b966e141048440b39e74dc8a2a9e45bd662e60e1..365aaef3ecaffe30b427099747acd2dc3e7004b1 100644 (file)
@@ -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;
index b63a9011f5112a01132a47283474d53e1dae54a5..14de7301c28df3cb3caaf6ab182cb1b36fb9985f 100644 (file)
 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 */