Commit b6fcc386 authored by Wayne Lin's avatar Wayne Lin Committed by Alex Deucher
Browse files

drm/amd/display: Add support to configure CRC window on specific CRC instance



[Why]
Have the need to specify the CRC window on specific CRC engine.
dc_stream_configure_crc() today calculates CRC on crc engine 0 only and always
resets CRC engine at first.

[How]
Add index parameter to dc_stream_configure_crc() for selecting the desired crc
engine. Additionally, add another parameter to specify whether to skip the
default reset of crc engine.

Reviewed-by: default avatarHaoPing Liu <haoping.liu@amd.com>
Signed-off-by: default avatarWayne Lin <Wayne.Lin@amd.com>
Signed-off-by: default avatarTom Chung <chiahsuan.chung@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4a9a9185
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -510,7 +510,7 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc,
	/* Enable or disable CRTC CRC generation */
	if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) {
		if (!dc_stream_configure_crc(stream_state->ctx->dc,
					     stream_state, NULL, enable, enable)) {
					     stream_state, NULL, enable, enable, 0, true)) {
			ret = -EINVAL;
			goto unlock;
		}
+8 −3
Original line number Diff line number Diff line
@@ -687,15 +687,17 @@ dc_stream_forward_multiple_crc_window(struct dc_stream_state *stream,
 * @enable: Enable CRC if true, disable otherwise.
 * @continuous: Capture CRC on every frame if true. Otherwise, only capture
 *              once.
 * @idx: Capture CRC on which CRC engine instance
 * @reset: Reset CRC engine before the configuration
 *
 * By default, only CRC0 is configured, and the entire frame is used to
 * calculate the CRC.
 * By default, the entire frame is used to calculate the CRC.
 *
 * Return: %false if the stream is not found or CRC capture is not supported;
 *         %true if the stream has been configured.
 */
bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
			     struct crc_params *crc_window, bool enable, bool continuous)
			     struct crc_params *crc_window, bool enable, bool continuous,
			     uint8_t idx, bool reset)
{
	struct pipe_ctx *pipe;
	struct crc_params param;
@@ -739,6 +741,9 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream,
	param.continuous_mode = continuous;
	param.enable = enable;

	param.crc_eng_inst = idx;
	param.reset = reset;

	tg = pipe->stream_res.tg;

	/* Only call if supported */
+3 −1
Original line number Diff line number Diff line
@@ -550,7 +550,9 @@ bool dc_stream_configure_crc(struct dc *dc,
			     struct dc_stream_state *stream,
			     struct crc_params *crc_window,
			     bool enable,
			     bool continuous);
			     bool continuous,
			     uint8_t idx,
			     bool reset);

bool dc_stream_get_crc(struct dc *dc,
		       struct dc_stream_state *stream,
+115 −54
Original line number Diff line number Diff line
@@ -2127,6 +2127,7 @@ bool dce110_configure_crc(struct timing_generator *tg,

	cntl_addr = CRTC_REG(mmCRTC_CRC_CNTL);

	if (!params->enable || params->reset)
		/* First, disable CRC before we configure it. */
		dm_write_reg(tg->ctx, cntl_addr, 0);

@@ -2134,6 +2135,8 @@ bool dce110_configure_crc(struct timing_generator *tg,
		return true;

	/* Program frame boundaries */
	switch (params->crc_eng_inst) {
	case 0:
		/* Window A x axis start and end. */
		value = 0;
		addr = CRTC_REG(mmCRTC_CRC0_WINDOWA_X_CONTROL);
@@ -2178,7 +2181,7 @@ bool dce110_configure_crc(struct timing_generator *tg,
				    CRTC_CRC0_WINDOWB_Y_END);
		dm_write_reg(tg->ctx, addr, value);

	/* Set crc mode and selection, and enable. Only using CRC0*/
		/* Set crc mode and selection, and enable.*/
		value = 0;
		set_reg_field_value(value, params->continuous_mode ? 1 : 0,
				    CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
@@ -2186,6 +2189,64 @@ bool dce110_configure_crc(struct timing_generator *tg,
				    CRTC_CRC_CNTL, CRTC_CRC0_SELECT);
		set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
		dm_write_reg(tg->ctx, cntl_addr, value);
		break;
	case 1:
		/* Window A x axis start and end. */
		value = 0;
		addr = CRTC_REG(mmCRTC_CRC1_WINDOWA_X_CONTROL);
		set_reg_field_value(value, params->windowa_x_start,
				    CRTC_CRC1_WINDOWA_X_CONTROL,
				    CRTC_CRC1_WINDOWA_X_START);
		set_reg_field_value(value, params->windowa_x_end,
				    CRTC_CRC1_WINDOWA_X_CONTROL,
				    CRTC_CRC1_WINDOWA_X_END);
		dm_write_reg(tg->ctx, addr, value);

		/* Window A y axis start and end. */
		value = 0;
		addr = CRTC_REG(mmCRTC_CRC1_WINDOWA_Y_CONTROL);
		set_reg_field_value(value, params->windowa_y_start,
				    CRTC_CRC1_WINDOWA_Y_CONTROL,
				    CRTC_CRC1_WINDOWA_Y_START);
		set_reg_field_value(value, params->windowa_y_end,
				    CRTC_CRC1_WINDOWA_Y_CONTROL,
				    CRTC_CRC1_WINDOWA_Y_END);
		dm_write_reg(tg->ctx, addr, value);

		/* Window B x axis start and end. */
		value = 0;
		addr = CRTC_REG(mmCRTC_CRC1_WINDOWB_X_CONTROL);
		set_reg_field_value(value, params->windowb_x_start,
				    CRTC_CRC1_WINDOWB_X_CONTROL,
				    CRTC_CRC1_WINDOWB_X_START);
		set_reg_field_value(value, params->windowb_x_end,
				    CRTC_CRC1_WINDOWB_X_CONTROL,
				    CRTC_CRC1_WINDOWB_X_END);
		dm_write_reg(tg->ctx, addr, value);

		/* Window B y axis start and end. */
		value = 0;
		addr = CRTC_REG(mmCRTC_CRC1_WINDOWB_Y_CONTROL);
		set_reg_field_value(value, params->windowb_y_start,
				    CRTC_CRC1_WINDOWB_Y_CONTROL,
				    CRTC_CRC1_WINDOWB_Y_START);
		set_reg_field_value(value, params->windowb_y_end,
				    CRTC_CRC1_WINDOWB_Y_CONTROL,
				    CRTC_CRC1_WINDOWB_Y_END);
		dm_write_reg(tg->ctx, addr, value);

		/* Set crc mode and selection, and enable.*/
		value = 0;
		set_reg_field_value(value, params->continuous_mode ? 1 : 0,
				    CRTC_CRC_CNTL, CRTC_CRC_CONT_EN);
		set_reg_field_value(value, params->selection,
				    CRTC_CRC_CNTL, CRTC_CRC1_SELECT);
		set_reg_field_value(value, 1, CRTC_CRC_CNTL, CRTC_CRC_EN);
		dm_write_reg(tg->ctx, cntl_addr, value);
		break;
	default:
		return false;
	}

	return true;
}
+62 −28
Original line number Diff line number Diff line
@@ -1100,6 +1100,7 @@ static bool dce120_configure_crc(struct timing_generator *tg,
	if (!dce120_is_tg_enabled(tg))
		return false;

	if (!params->enable || params->reset)
		/* First, disable CRC before we configure it. */
		dm_write_reg_soc15(tg->ctx, mmCRTC0_CRTC_CRC_CNTL,
				   tg110->offsets.crtc, 0);
@@ -1108,6 +1109,8 @@ static bool dce120_configure_crc(struct timing_generator *tg,
		return true;

	/* Program frame boundaries */
	switch (params->crc_eng_inst) {
	case 0:
		/* Window A x axis start and end. */
		CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC0_WINDOWA_X_CONTROL,
				  CRTC_CRC0_WINDOWA_X_START, params->windowa_x_start,
@@ -1128,11 +1131,42 @@ static bool dce120_configure_crc(struct timing_generator *tg,
				  CRTC_CRC0_WINDOWB_Y_START, params->windowb_y_start,
				  CRTC_CRC0_WINDOWB_Y_END, params->windowb_y_end);

	/* Set crc mode and selection, and enable. Only using CRC0*/
		/* Set crc mode and selection, and enable.*/
		CRTC_REG_UPDATE_3(CRTC0_CRTC_CRC_CNTL,
			  CRTC_CRC_EN, params->continuous_mode ? 1 : 0,
				  CRTC_CRC_CONT_EN, params->continuous_mode ? 1 : 0,
				  CRTC_CRC0_SELECT, params->selection,
				  CRTC_CRC_EN, 1);
		break;
	case 1:
		/* Window A x axis start and end. */
		CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWA_X_CONTROL,
				  CRTC_CRC1_WINDOWA_X_START, params->windowa_x_start,
				  CRTC_CRC1_WINDOWA_X_END, params->windowa_x_end);

		/* Window A y axis start and end. */
		CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWA_Y_CONTROL,
				  CRTC_CRC1_WINDOWA_Y_START, params->windowa_y_start,
				  CRTC_CRC1_WINDOWA_Y_END, params->windowa_y_end);

		/* Window B x axis start and end. */
		CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWB_X_CONTROL,
				  CRTC_CRC1_WINDOWB_X_START, params->windowb_x_start,
				  CRTC_CRC1_WINDOWB_X_END, params->windowb_x_end);

		/* Window B y axis start and end. */
		CRTC_REG_UPDATE_2(CRTC0_CRTC_CRC1_WINDOWB_Y_CONTROL,
				  CRTC_CRC1_WINDOWB_Y_START, params->windowb_y_start,
				  CRTC_CRC1_WINDOWB_Y_END, params->windowb_y_end);

		/* Set crc mode and selection, and enable */
		CRTC_REG_UPDATE_3(CRTC0_CRTC_CRC_CNTL,
				  CRTC_CRC_CONT_EN, params->continuous_mode ? 1 : 0,
				  CRTC_CRC1_SELECT, params->selection,
				  CRTC_CRC_EN, 1);
		break;
	default:
		return false;
	}

	return true;
}
Loading