From b87d78d6aa104b207ff588d2cfd13633c2385994 Mon Sep 17 00:00:00 2001 From: Yue Hin Lau Date: Tue, 19 Sep 2017 17:29:28 -0400 Subject: [PATCH] drm/amd/display: moving cursor functions from ipp to mem_input Signed-off-by: Yue Hin Lau Reviewed-by: Tony Cheng Acked-by: Harry Wentland Signed-off-by: Alex Deucher --- .../gpu/drm/amd/display/dc/core/dc_stream.c | 32 ++- drivers/gpu/drm/amd/display/dc/dce/dce_ipp.c | 2 + .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c | 51 +++++ .../gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h | 15 +- .../gpu/drm/amd/display/dc/dcn10/dcn10_ipp.c | 189 ------------------ .../amd/display/dc/dcn10/dcn10_mem_input.c | 163 +++++++++++++++ .../amd/display/dc/dcn10/dcn10_mem_input.h | 57 +++++- .../gpu/drm/amd/display/dc/inc/hw/mem_input.h | 10 + .../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, ¶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 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.30.2