Commit f1cdc98f authored by Dingchen Zhang's avatar Dingchen Zhang Committed by Alex Deucher
Browse files

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.

Signed-off-by: default avatarDingchen Zhang <dingchen.zhang@amd.com>
Reviewed-by: default avatarHanghong Ma <Hanghong.Ma@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e9bcc1e0
Loading
Loading
Loading
Loading
+44 −14
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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 */