From 353c7398469f749a6607d4a7bef52158fa909e55 Mon Sep 17 00:00:00 2001 From: Dingchen Zhang Date: Fri, 28 Jun 2019 17:23:24 -0400 Subject: [PATCH 3077/4256] drm/amd/display: add pipe CRC sources without disabling dithering. [Why] need to verify the impact of spatial dithering on 8bpc bypass mode. [How] added CRC sources and configure dihter option from dc stream. Change-Id: I8b6a55065146856ee210c98804e10316ab3e7e4b Signed-off-by: Dingchen Zhang Reviewed-by: Hanghong Ma Acked-by: Leo Li --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 61 ++++++++++++++----- .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h | 6 +- 2 files changed, 51 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 609f1fdc10b3..e9a2c432e4d0 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 @@ -32,7 +32,9 @@ static const char *const pipe_crc_sources[] = { "none", "crtc", + "crtc dither", "dprx", + "dprx dither", "auto", }; @@ -44,10 +46,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) { @@ -55,6 +80,7 @@ const char *const *amdgpu_dm_crtc_get_crc_sources(struct drm_crtc *crtc, return pipe_crc_sources; } + int amdgpu_dm_crtc_verify_crc_source(struct drm_crtc *crtc, const char *src_name, size_t *values_cnt) @@ -102,14 +128,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 +155,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 +163,13 @@ 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); /* * Reading the CRC requires the vblank interrupt handler to be @@ -145,7 +178,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; @@ -153,7 +186,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; @@ -202,7 +235,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.17.1