diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2506-drm-amd-display-moving-cursor-functions-from-ipp-to-.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2506-drm-amd-display-moving-cursor-functions-from-ipp-to-.patch | 762 |
1 files changed, 762 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2506-drm-amd-display-moving-cursor-functions-from-ipp-to-.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2506-drm-amd-display-moving-cursor-functions-from-ipp-to-.patch new file mode 100644 index 00000000..9c0d69c3 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2506-drm-amd-display-moving-cursor-functions-from-ipp-to-.patch @@ -0,0 +1,762 @@ +From cb8f7d1a867881f80ef1128274fd05221b2ca09c Mon Sep 17 00:00:00 2001 +From: Yue Hin Lau <Yuehin.Lau@amd.com> +Date: Tue, 19 Sep 2017 17:29:28 -0400 +Subject: [PATCH 2506/4131] drm/amd/display: moving cursor functions from ipp + to mem_input + +Signed-off-by: Yue Hin Lau <Yuehin.Lau@amd.com> +Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> +Acked-by: Harry Wentland <Harry.Wentland@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 23df7bc..c19b478 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, ¶m); ++ ++ if (ipp->funcs->ipp_cursor_set_position != NULL) ++ ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m); ++ ++ if (mi->funcs->set_cursor_attributes != NULL) ++ mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m); ++ ++ if (xfm->funcs->set_cursor_attributes != NULL) ++ xfm->funcs->set_cursor_position(xfm, &pos_cpy, ¶m, 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 fa481d4..d618fdd 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 f9e43e6..05df3b2 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 a1f6b01..7fecdb1 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 67bd6a7..08db1e6 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 a28495d..efa1aca 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 0b7d4fa..2c79d7a 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 6cef9ad..5c8e45b 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 785d397..f95621df 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.7.4 + |