[PATCH 043/103] drm/amd/display: moving cursor functions from ipp to mem_input

Harry Wentland harry.wentland at amd.com
Tue Oct 10 22:40:12 UTC 2017


From: Yue Hin Lau <Yuehin.Lau at amd.com>

Signed-off-by: Yue Hin Lau <Yuehin.Lau at amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng at amd.com>
Acked-by: Harry Wentland <Harry.Wentland at amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c    |  32 +++-
 drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c       |   2 +
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c   |  51 ++++++
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h   |  15 +-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c   | 189 ---------------------
 .../gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c | 163 ++++++++++++++++++
 .../gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h |  57 ++++++-
 drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h  |  10 ++
 drivers/gpu/drm/amd/display/dc/inc/hw/transform.h  |  11 ++
 9 files changed, 329 insertions(+), 201 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
index 23df7bc020d2..c19b478bcdc7 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -195,13 +195,23 @@ bool dc_stream_set_cursor_attributes(
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
 
-		if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp)
+		if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.mi || !pipe_ctx->plane_res.xfm)
 			continue;
 		if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
 			continue;
 
-		pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
-				pipe_ctx->plane_res.ipp, attributes);
+
+		if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
+			pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
+						pipe_ctx->plane_res.ipp, attributes);
+
+		if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
+			pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
+					pipe_ctx->plane_res.mi, attributes);
+
+		if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
+			pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
+				pipe_ctx->plane_res.xfm, attributes);
 	}
 
 	return true;
@@ -231,6 +241,8 @@ bool dc_stream_set_cursor_position(
 	for (i = 0; i < MAX_PIPES; i++) {
 		struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
 		struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
+		struct mem_input *mi = pipe_ctx->plane_res.mi;
+		struct transform *xfm = pipe_ctx->plane_res.xfm;
 		struct dc_cursor_position pos_cpy = *position;
 		struct dc_cursor_mi_param param = {
 			.pixel_clk_khz = stream->timing.pix_clk_khz,
@@ -241,7 +253,9 @@ bool dc_stream_set_cursor_position(
 		};
 
 		if (pipe_ctx->stream != stream ||
-				!pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state)
+				!pipe_ctx->plane_res.mi ||
+				!pipe_ctx->plane_state ||
+				!pipe_ctx->plane_res.xfm)
 			continue;
 
 		if (pipe_ctx->plane_state->address.type
@@ -251,7 +265,15 @@ bool dc_stream_set_cursor_position(
 		if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
 			pos_cpy.enable = false;
 
-		ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+
+		if (ipp->funcs->ipp_cursor_set_position != NULL)
+			ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, &param);
+
+		if (mi->funcs->set_cursor_attributes != NULL)
+			mi->funcs->set_cursor_position(mi, &pos_cpy, &param);
+
+		if (xfm->funcs->set_cursor_attributes != NULL)
+			xfm->funcs->set_cursor_position(xfm, &pos_cpy, &param, mi->curs_attr.width);
 	}
 
 	return true;
diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
index fa481d481132..d618fdd0cc82 100644
--- a/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
+++ b/drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c
@@ -37,6 +37,7 @@
 #define CTX \
 	ipp_dce->base.ctx
 
+
 static void dce_ipp_cursor_set_position(
 	struct input_pixel_processor *ipp,
 	const struct dc_cursor_position *position,
@@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes(
 	REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
 }
 
+
 static void dce_ipp_program_prescale(
 	struct input_pixel_processor *ipp,
 	struct ipp_prescale_params *params)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
index f9e43e68fc0c..05df3b222945 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -372,6 +372,55 @@ void ippn10_cnv_setup (
 	}
 }
 
+void dcn10_set_cursor_attributes(
+		struct transform *xfm_base,
+		const struct dc_cursor_attributes *attr)
+{
+	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	enum dc_cursor_color_format color_format = attr->color_format;
+
+	REG_UPDATE_2(CURSOR0_CONTROL,
+			CUR0_MODE, color_format,
+			CUR0_EXPANSION_MODE, 0);
+
+	if (color_format == CURSOR_MODE_MONO) {
+		/* todo: clarify what to program these to */
+		REG_UPDATE(CURSOR0_COLOR0,
+				CUR0_COLOR0, 0x00000000);
+		REG_UPDATE(CURSOR0_COLOR1,
+				CUR0_COLOR1, 0xFFFFFFFF);
+	}
+
+	/* TODO: Fixed vs float */
+
+	REG_UPDATE_3(FORMAT_CONTROL,
+				CNVC_BYPASS, 0,
+				FORMAT_CONTROL__ALPHA_EN, 1,
+				FORMAT_EXPANSION_MODE, 0);
+}
+
+
+void dcn10_set_cursor_position(
+		struct transform *xfm_base,
+		const struct dc_cursor_position *pos,
+		const struct dc_cursor_mi_param *param,
+		uint32_t width)
+{
+	struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
+	int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
+	uint32_t cur_en = pos->enable ? 1 : 0;
+
+	if (src_x_offset >= (int)param->viewport_width)
+		cur_en = 0;  /* not visible beyond right edge*/
+
+	if (src_x_offset + (int)width < 0)
+		cur_en = 0;  /* not visible beyond left edge*/
+
+	REG_UPDATE(CURSOR0_CONTROL,
+			CUR0_ENABLE, cur_en);
+
+}
+
 static const struct transform_funcs dcn10_dpp_funcs = {
 		.transform_reset = dpp_reset,
 		.transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale,
@@ -391,6 +440,8 @@ static const struct transform_funcs dcn10_dpp_funcs = {
 		.ipp_program_degamma_pwl	= ippn10_set_degamma_pwl,
 		.ipp_setup			= ippn10_cnv_setup,
 		.ipp_full_bypass		= ippn10_full_bypass,
+		.set_cursor_attributes = dcn10_set_cursor_attributes,
+		.set_cursor_position = dcn10_set_cursor_position,
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
index a1f6b01a2eb4..7fecdb19761d 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -112,7 +112,10 @@
 	SRI(CM_DGAM_CONTROL, CM, id), \
 	SRI(FORMAT_CONTROL, CNVC_CFG, id), \
 	SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
-	SRI(CURSOR0_CONTROL, CNVC_CUR, id)
+	SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
+	SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
+	SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
+	SRI(CURSOR0_COLOR1, CNVC_CUR, id)
 
 
 
@@ -302,7 +305,9 @@
 	TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
 	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
 	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
-	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh)
+	TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
+	TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
+	TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
 
 #define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
 	TF_REG_LIST_SH_MASK_DCN(mask_sh),\
@@ -989,7 +994,9 @@
 	type CUR0_EXPANSION_MODE; \
 	type CUR0_ENABLE; \
 	type CM_BYPASS; \
-	type FORMAT_CONTROL__ALPHA_EN
+	type FORMAT_CONTROL__ALPHA_EN; \
+	type CUR0_COLOR0; \
+	type CUR0_COLOR1
 
 
 
@@ -1237,6 +1244,8 @@ struct dcn_dpp_registers {
 	uint32_t CNVC_SURFACE_PIXEL_FORMAT;
 	uint32_t CURSOR_CONTROL;
 	uint32_t CURSOR0_CONTROL;
+	uint32_t CURSOR0_COLOR0;
+	uint32_t CURSOR0_COLOR1;
 };
 
 struct dcn10_dpp {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
index 67bd6a738fe9..08db1e6b5166 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c
@@ -37,188 +37,6 @@
 #define CTX \
 	ippn10->base.ctx
 
-static bool ippn10_cursor_program_control(
-		struct dcn10_ipp *ippn10,
-		bool pixel_data_invert,
-		enum dc_cursor_color_format color_format)
-{
-	if (REG(CURSOR_SETTINS))
-		REG_SET_2(CURSOR_SETTINS, 0,
-				/* no shift of the cursor HDL schedule */
-				CURSOR0_DST_Y_OFFSET, 0,
-				 /* used to shift the cursor chunk request deadline */
-				CURSOR0_CHUNK_HDL_ADJUST, 3);
-	else
-		REG_SET_2(CURSOR_SETTINGS, 0,
-				/* no shift of the cursor HDL schedule */
-				CURSOR0_DST_Y_OFFSET, 0,
-				 /* used to shift the cursor chunk request deadline */
-				CURSOR0_CHUNK_HDL_ADJUST, 3);
-
-	REG_UPDATE_2(CURSOR0_CONTROL,
-			CUR0_MODE, color_format,
-			CUR0_EXPANSION_MODE, 0);
-
-	if (color_format == CURSOR_MODE_MONO) {
-		/* todo: clarify what to program these to */
-		REG_UPDATE(CURSOR0_COLOR0,
-				CUR0_COLOR0, 0x00000000);
-		REG_UPDATE(CURSOR0_COLOR1,
-				CUR0_COLOR1, 0xFFFFFFFF);
-	}
-
-	/* TODO: Fixed vs float */
-
-	REG_UPDATE_3(FORMAT_CONTROL,
-				CNVC_BYPASS, 0,
-				ALPHA_EN, 1,
-				FORMAT_EXPANSION_MODE, 0);
-
-	return true;
-}
-
-enum cursor_pitch {
-	CURSOR_PITCH_64_PIXELS = 0,
-	CURSOR_PITCH_128_PIXELS,
-	CURSOR_PITCH_256_PIXELS
-};
-
-enum cursor_lines_per_chunk {
-	CURSOR_LINE_PER_CHUNK_2 = 1,
-	CURSOR_LINE_PER_CHUNK_4,
-	CURSOR_LINE_PER_CHUNK_8,
-	CURSOR_LINE_PER_CHUNK_16
-};
-
-static enum cursor_pitch ippn10_get_cursor_pitch(
-		unsigned int pitch)
-{
-	enum cursor_pitch hw_pitch;
-
-	switch (pitch) {
-	case 64:
-		hw_pitch = CURSOR_PITCH_64_PIXELS;
-		break;
-	case 128:
-		hw_pitch = CURSOR_PITCH_128_PIXELS;
-		break;
-	case 256:
-		hw_pitch = CURSOR_PITCH_256_PIXELS;
-		break;
-	default:
-		DC_ERR("Invalid cursor pitch of %d. "
-				"Only 64/128/256 is supported on DCN.\n", pitch);
-		hw_pitch = CURSOR_PITCH_64_PIXELS;
-		break;
-	}
-	return hw_pitch;
-}
-
-static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
-		unsigned int cur_width,
-		enum dc_cursor_color_format format)
-{
-	enum cursor_lines_per_chunk line_per_chunk;
-
-	if (format == CURSOR_MODE_MONO)
-		/* impl B. expansion in CUR Buffer reader */
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
-	else if (cur_width <= 32)
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
-	else if (cur_width <= 64)
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
-	else if (cur_width <= 128)
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
-	else
-		line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
-
-	return line_per_chunk;
-}
-
-static void ippn10_cursor_set_attributes(
-		struct input_pixel_processor *ipp,
-		const struct dc_cursor_attributes *attr)
-{
-	struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
-	enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
-	enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
-			attr->width, attr->color_format);
-
-	ippn10->curs_attr = *attr;
-
-	REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
-			CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
-	REG_UPDATE(CURSOR_SURFACE_ADDRESS,
-			CURSOR_SURFACE_ADDRESS, attr->address.low_part);
-
-	REG_UPDATE_2(CURSOR_SIZE,
-			CURSOR_WIDTH, attr->width,
-			CURSOR_HEIGHT, attr->height);
-	REG_UPDATE_3(CURSOR_CONTROL,
-			CURSOR_MODE, attr->color_format,
-			CURSOR_PITCH, hw_pitch,
-			CURSOR_LINES_PER_CHUNK, lpc);
-	ippn10_cursor_program_control(ippn10,
-			attr->attribute_flags.bits.INVERT_PIXEL_DATA,
-			attr->color_format);
-}
-
-static void ippn10_cursor_set_position(
-		struct input_pixel_processor *ipp,
-		const struct dc_cursor_position *pos,
-		const struct dc_cursor_mi_param *param)
-{
-	struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
-	int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
-	uint32_t cur_en = pos->enable ? 1 : 0;
-	uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
-
-	/*
-	 * Guard aganst cursor_set_position() from being called with invalid
-	 * attributes
-	 *
-	 * TODO: Look at combining cursor_set_position() and
-	 * cursor_set_attributes() into cursor_update()
-	 */
-	if (ippn10->curs_attr.address.quad_part == 0)
-		return;
-
-	dst_x_offset *= param->ref_clk_khz;
-	dst_x_offset /= param->pixel_clk_khz;
-
-	ASSERT(param->h_scale_ratio.value);
-
-	if (param->h_scale_ratio.value)
-		dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
-				dal_fixed31_32_from_int(dst_x_offset),
-				param->h_scale_ratio));
-
-	if (src_x_offset >= (int)param->viewport_width)
-		cur_en = 0;  /* not visible beyond right edge*/
-
-	if (src_x_offset + (int)ippn10->curs_attr.width < 0)
-		cur_en = 0;  /* not visible beyond left edge*/
-
-	if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
-		ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr);
-	REG_UPDATE(CURSOR_CONTROL,
-			CURSOR_ENABLE, cur_en);
-	REG_UPDATE(CURSOR0_CONTROL,
-			CUR0_ENABLE, cur_en);
-
-	REG_SET_2(CURSOR_POSITION, 0,
-			CURSOR_X_POSITION, pos->x,
-			CURSOR_Y_POSITION, pos->y);
-
-	REG_SET_2(CURSOR_HOT_SPOT, 0,
-			CURSOR_HOT_SPOT_X, pos->x_hotspot,
-			CURSOR_HOT_SPOT_Y, pos->y_hotspot);
-
-	REG_SET(CURSOR_DST_OFFSET, 0,
-			CURSOR_DST_X_OFFSET, dst_x_offset);
-	/* TODO Handle surface pixel formats other than 4:4:4 */
-}
-
 /*****************************************/
 /* Constructor, Destructor               */
 /*****************************************/
@@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp)
 }
 
 static const struct ipp_funcs dcn10_ipp_funcs = {
-	.ipp_cursor_set_attributes	= ippn10_cursor_set_attributes,
-	.ipp_cursor_set_position	= ippn10_cursor_set_position,
-	.ipp_set_degamma		= NULL,
-	.ipp_program_input_lut		= NULL,
-	.ipp_full_bypass		= NULL,
-	.ipp_setup			= NULL,
-	.ipp_program_degamma_pwl	= NULL,
 	.ipp_destroy			= dcn10_ipp_destroy
 };
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c
index a28495d95a15..efa1aca187ad 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.c
@@ -766,6 +766,167 @@ void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
 			QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
 }
 
+enum cursor_pitch {
+	CURSOR_PITCH_64_PIXELS = 0,
+	CURSOR_PITCH_128_PIXELS,
+	CURSOR_PITCH_256_PIXELS
+};
+
+enum cursor_lines_per_chunk {
+	CURSOR_LINE_PER_CHUNK_2 = 1,
+	CURSOR_LINE_PER_CHUNK_4,
+	CURSOR_LINE_PER_CHUNK_8,
+	CURSOR_LINE_PER_CHUNK_16
+};
+
+static bool ippn10_cursor_program_control(
+		struct dcn10_mem_input *mi,
+		bool pixel_data_invert,
+		enum dc_cursor_color_format color_format)
+{
+	if (REG(CURSOR_SETTINS))
+		REG_SET_2(CURSOR_SETTINS, 0,
+				/* no shift of the cursor HDL schedule */
+				CURSOR0_DST_Y_OFFSET, 0,
+				 /* used to shift the cursor chunk request deadline */
+				CURSOR0_CHUNK_HDL_ADJUST, 3);
+	else
+		REG_SET_2(CURSOR_SETTINGS, 0,
+				/* no shift of the cursor HDL schedule */
+				CURSOR0_DST_Y_OFFSET, 0,
+				 /* used to shift the cursor chunk request deadline */
+				CURSOR0_CHUNK_HDL_ADJUST, 3);
+
+	return true;
+}
+
+static enum cursor_pitch ippn10_get_cursor_pitch(
+		unsigned int pitch)
+{
+	enum cursor_pitch hw_pitch;
+
+	switch (pitch) {
+	case 64:
+		hw_pitch = CURSOR_PITCH_64_PIXELS;
+		break;
+	case 128:
+		hw_pitch = CURSOR_PITCH_128_PIXELS;
+		break;
+	case 256:
+		hw_pitch = CURSOR_PITCH_256_PIXELS;
+		break;
+	default:
+		DC_ERR("Invalid cursor pitch of %d. "
+				"Only 64/128/256 is supported on DCN.\n", pitch);
+		hw_pitch = CURSOR_PITCH_64_PIXELS;
+		break;
+	}
+	return hw_pitch;
+}
+
+static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
+		unsigned int cur_width,
+		enum dc_cursor_color_format format)
+{
+	enum cursor_lines_per_chunk line_per_chunk;
+
+	if (format == CURSOR_MODE_MONO)
+		/* impl B. expansion in CUR Buffer reader */
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
+	else if (cur_width <= 32)
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
+	else if (cur_width <= 64)
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
+	else if (cur_width <= 128)
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
+	else
+		line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
+
+	return line_per_chunk;
+}
+
+static void ippn10_cursor_set_attributes(
+		struct mem_input *mem_input,
+		const struct dc_cursor_attributes *attr)
+{
+	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
+	enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
+			attr->width, attr->color_format);
+
+	mem_input->curs_attr = *attr;
+
+	REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
+			CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
+	REG_UPDATE(CURSOR_SURFACE_ADDRESS,
+			CURSOR_SURFACE_ADDRESS, attr->address.low_part);
+
+	REG_UPDATE_2(CURSOR_SIZE,
+			CURSOR_WIDTH, attr->width,
+			CURSOR_HEIGHT, attr->height);
+	REG_UPDATE_3(CURSOR_CONTROL,
+			CURSOR_MODE, attr->color_format,
+			CURSOR_PITCH, hw_pitch,
+			CURSOR_LINES_PER_CHUNK, lpc);
+	ippn10_cursor_program_control(mi,
+			attr->attribute_flags.bits.INVERT_PIXEL_DATA,
+			attr->color_format);
+}
+
+static void ippn10_cursor_set_position(
+		struct mem_input *mem_input,
+		const struct dc_cursor_position *pos,
+		const struct dc_cursor_mi_param *param)
+{
+	struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
+	int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
+	uint32_t cur_en = pos->enable ? 1 : 0;
+	uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
+
+	/*
+	 * Guard aganst cursor_set_position() from being called with invalid
+	 * attributes
+	 *
+	 * TODO: Look at combining cursor_set_position() and
+	 * cursor_set_attributes() into cursor_update()
+	 */
+	if (mem_input->curs_attr.address.quad_part == 0)
+		return;
+
+	dst_x_offset *= param->ref_clk_khz;
+	dst_x_offset /= param->pixel_clk_khz;
+
+	ASSERT(param->h_scale_ratio.value);
+
+	if (param->h_scale_ratio.value)
+		dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
+				dal_fixed31_32_from_int(dst_x_offset),
+				param->h_scale_ratio));
+
+	if (src_x_offset >= (int)param->viewport_width)
+		cur_en = 0;  /* not visible beyond right edge*/
+
+	if (src_x_offset + (int)mem_input->curs_attr.width < 0)
+		cur_en = 0;  /* not visible beyond left edge*/
+
+	if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
+		ippn10_cursor_set_attributes(mem_input, &mem_input->curs_attr);
+	REG_UPDATE(CURSOR_CONTROL,
+			CURSOR_ENABLE, cur_en);
+
+	REG_SET_2(CURSOR_POSITION, 0,
+			CURSOR_X_POSITION, pos->x,
+			CURSOR_Y_POSITION, pos->y);
+
+	REG_SET_2(CURSOR_HOT_SPOT, 0,
+			CURSOR_HOT_SPOT_X, pos->x_hotspot,
+			CURSOR_HOT_SPOT_Y, pos->y_hotspot);
+
+	REG_SET(CURSOR_DST_OFFSET, 0,
+			CURSOR_DST_X_OFFSET, dst_x_offset);
+	/* TODO Handle surface pixel formats other than 4:4:4 */
+}
+
 static struct mem_input_funcs dcn10_mem_input_funcs = {
 	.mem_input_program_display_marks = min10_program_display_marks,
 	.mem_input_program_surface_flip_and_addr =
@@ -780,6 +941,8 @@ static struct mem_input_funcs dcn10_mem_input_funcs = {
 	.dcc_control = min10_dcc_control,
 	.mem_program_viewport = min_set_viewport,
 	.set_hubp_blank_en = min10_set_hubp_blank_en,
+	.set_cursor_attributes	= ippn10_cursor_set_attributes,
+	.set_cursor_position	= ippn10_cursor_set_position,
 };
 
 /*****************************************/
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h
index 0b7d4faff82f..2c79d7aa3f91 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mem_input.h
@@ -30,7 +30,6 @@
 #define TO_DCN10_MEM_INPUT(mi)\
 	container_of(mi, struct dcn10_mem_input, base)
 
-
 #define MI_REG_LIST_DCN(id)\
 	SRI(DCHUBP_CNTL, HUBP, id),\
 	SRI(HUBPREQ_DEBUG_DB, HUBP, id),\
@@ -118,7 +117,15 @@
 	SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
 	SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
 	SR(DCHUBBUB_SDPIF_FB_BASE),\
-	SR(DCHUBBUB_SDPIF_FB_OFFSET)
+	SR(DCHUBBUB_SDPIF_FB_OFFSET),\
+	SRI(CURSOR_SETTINS, HUBPREQ, id), \
+	SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \
+	SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \
+	SRI(CURSOR_SIZE, CURSOR, id), \
+	SRI(CURSOR_CONTROL, CURSOR, id), \
+	SRI(CURSOR_POSITION, CURSOR, id), \
+	SRI(CURSOR_HOT_SPOT, CURSOR, id), \
+	SRI(CURSOR_DST_OFFSET, CURSOR, id)
 
 
 
@@ -217,6 +224,15 @@ struct dcn_mi_registers {
 	uint32_t DCN_VM_AGP_BASE;
 	uint32_t DCN_VM_AGP_BOT;
 	uint32_t DCN_VM_AGP_TOP;
+	uint32_t CURSOR_SETTINS;
+	uint32_t CURSOR_SETTINGS;
+	uint32_t CURSOR_SURFACE_ADDRESS_HIGH;
+	uint32_t CURSOR_SURFACE_ADDRESS;
+	uint32_t CURSOR_SIZE;
+	uint32_t CURSOR_CONTROL;
+	uint32_t CURSOR_POSITION;
+	uint32_t CURSOR_HOT_SPOT;
+	uint32_t CURSOR_DST_OFFSET;
 };
 
 #define MI_SF(reg_name, field_name, post_fix)\
@@ -362,7 +378,23 @@ struct dcn_mi_registers {
 	MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
 	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
-	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh)
+	MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\
+	MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \
+	MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
+	MI_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
 
 #define DCN_MI_REG_FIELD_LIST(type) \
 	type HUBP_BLANK_EN;\
@@ -523,7 +555,24 @@ struct dcn_mi_registers {
 	type PHYSICAL_PAGE_ADDR_LO32;\
 	type PHYSICAL_PAGE_NUMBER_MSB;\
 	type PHYSICAL_PAGE_NUMBER_LSB;\
-	type LOGICAL_ADDR
+	type LOGICAL_ADDR;\
+	type CURSOR0_DST_Y_OFFSET; \
+	type CURSOR0_CHUNK_HDL_ADJUST; \
+	type CURSOR_SURFACE_ADDRESS_HIGH; \
+	type CURSOR_SURFACE_ADDRESS; \
+	type CURSOR_WIDTH; \
+	type CURSOR_HEIGHT; \
+	type CURSOR_MODE; \
+	type CURSOR_2X_MAGNIFY; \
+	type CURSOR_PITCH; \
+	type CURSOR_LINES_PER_CHUNK; \
+	type CURSOR_ENABLE; \
+	type CURSOR_X_POSITION; \
+	type CURSOR_Y_POSITION; \
+	type CURSOR_HOT_SPOT_X; \
+	type CURSOR_HOT_SPOT_Y; \
+	type CURSOR_DST_X_OFFSET; \
+	type OUTPUT_FP
 
 struct dcn_mi_shift {
 	DCN_MI_REG_FIELD_LIST(uint8_t);
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
index 6cef9ad0af91..5c8e45ba8f45 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/mem_input.h
@@ -72,6 +72,7 @@ struct mem_input {
 	int opp_id;
 	int mpcc_id;
 	struct stutter_modes stutter_mode;
+	struct dc_cursor_attributes curs_attr;
 };
 
 struct vm_system_aperture_param {
@@ -163,6 +164,15 @@ struct mem_input_funcs {
 	void (*set_blank)(struct mem_input *mi, bool blank);
 	void (*set_hubp_blank_en)(struct mem_input *mi, bool blank);
 
+	void (*set_cursor_attributes)(
+			struct mem_input *mem_input,
+			const struct dc_cursor_attributes *attr);
+
+	void (*set_cursor_position)(
+			struct mem_input *mem_input,
+			const struct dc_cursor_position *pos,
+			const struct dc_cursor_mi_param *param);
+
 };
 
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
index 785d39706832..f95621dfd4d4 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/transform.h
@@ -238,6 +238,17 @@ struct transform_funcs {
 
 	void (*ipp_full_bypass)(struct transform *xfm_base);
 
+	void (*set_cursor_attributes)(
+			struct transform *xfm_base,
+			const struct dc_cursor_attributes *attr);
+
+	void (*set_cursor_position)(
+			struct transform *xfm_base,
+			const struct dc_cursor_position *pos,
+			const struct dc_cursor_mi_param *param,
+			uint32_t width
+			);
+
 };
 
 const uint16_t *get_filter_2tap_16p(void);
-- 
2.14.1



More information about the amd-gfx mailing list