From: Gloria Li <[email protected]>

[Why]
There are outstanding bugs for PIP in Dal3:
-Crash when toggling PIP visibility
-Global Alpha is not working, Adjusting global alpha
 doesn’t have an effect
-Cursor is not working with pip plane and pipe splits
-One flash occurs when cursor enters PIP plane from
 top/bottom
-Crash when moving PIP plane off the screen

[How]
Resolve divide by 0 error
Implement global alpha
Program cursor on all pipes
Add dst rects' x and y offests into cursor position
Disable cursor when it is beyond bottom/top edge

Change-Id: I0cc29fb03412437695f99cb34554841fbe2d6ed8
Signed-off-by: Gloria Li <[email protected]>
Reviewed-by: Aric Cyr <[email protected]>
Acked-by: Leo Li <[email protected]>
---
 drivers/gpu/drm/amd/display/dc/core/dc.c               |  3 +++
 drivers/gpu/drm/amd/display/dc/core/dc_resource.c      |  9 ++++++---
 drivers/gpu/drm/amd/display/dc/core/dc_stream.c        |  2 --
 drivers/gpu/drm/amd/display/dc/dc.h                    |  5 +++++
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c       | 10 +++++++++-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h       |  3 ++-
 drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c      |  7 +++++++
 .../gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c  | 18 ++++++++++++------
 drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h            |  3 ++-
 9 files changed, 46 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c 
b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 76cb43d..4249dd5 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -1093,6 +1093,9 @@ static enum surface_update_type 
get_plane_info_update_type(const struct dc_surfa
        if (u->plane_info->per_pixel_alpha != u->surface->per_pixel_alpha)
                update_flags->bits.per_pixel_alpha_change = 1;
 
+       if (u->plane_info->global_alpha_value != u->surface->global_alpha_value)
+               update_flags->bits.global_alpha_change = 1;
+
        if (u->plane_info->dcc.enable != u->surface->dcc.enable
                        || u->plane_info->dcc.grph.independent_64b_blks != 
u->surface->dcc.grph.independent_64b_blks
                        || u->plane_info->dcc.grph.meta_pitch != 
u->surface->dcc.grph.meta_pitch)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c 
b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 21b5c4c..0154013 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -571,8 +571,10 @@ static void calculate_viewport(struct pipe_ctx *pipe_ctx)
                data->viewport.width = (data->viewport.width + 1) / 2;
                data->viewport_c.width = (data->viewport_c.width + 1) / 2;
        } else if (pri_split) {
-               data->viewport.width /= 2;
-               data->viewport_c.width /= 2;
+               if (data->viewport.width > 1)
+                       data->viewport.width /= 2;
+               if (data->viewport_c.width > 1)
+                       data->viewport_c.width /= 2;
        }
 
        if (plane_state->rotation == ROTATION_ANGLE_90 ||
@@ -652,7 +654,8 @@ static void calculate_recout(struct pipe_ctx *pipe_ctx, 
struct rect *recout_full
                        pipe_ctx->plane_res.scl_data.recout.width =
                                        
(pipe_ctx->plane_res.scl_data.recout.width + 1) / 2;
                } else {
-                       pipe_ctx->plane_res.scl_data.recout.width /= 2;
+                       if (pipe_ctx->plane_res.scl_data.recout.width > 1)
+                               pipe_ctx->plane_res.scl_data.recout.width /= 2;
                }
        }
        /* Unclipped recout offset = stream dst offset + ((surf dst offset - 
stream surf_src offset)
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 fdcc8ab..2ac848a1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c
@@ -205,8 +205,6 @@ bool dc_stream_set_cursor_attributes(
 
                if (pipe_ctx->stream != stream)
                        continue;
-               if (pipe_ctx->top_pipe && pipe_ctx->plane_state != 
pipe_ctx->top_pipe->plane_state)
-                       continue;
 
                if (!pipe_to_program) {
                        pipe_to_program = pipe_ctx;
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h 
b/drivers/gpu/drm/amd/display/dc/dc.h
index 1010774..57fb0a8 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -442,6 +442,7 @@ union surface_update_flags {
                uint32_t color_space_change:1;
                uint32_t horizontal_mirror_change:1;
                uint32_t per_pixel_alpha_change:1;
+               uint32_t global_alpha_change:1;
                uint32_t rotation_change:1;
                uint32_t swizzle_change:1;
                uint32_t scaling_change:1;
@@ -496,6 +497,8 @@ struct dc_plane_state {
 
        bool is_tiling_rotated;
        bool per_pixel_alpha;
+       bool global_alpha;
+       int  global_alpha_value;
        bool visible;
        bool flip_immediate;
        bool horizontal_mirror;
@@ -522,6 +525,8 @@ struct dc_plane_info {
        bool horizontal_mirror;
        bool visible;
        bool per_pixel_alpha;
+       bool global_alpha;
+       int  global_alpha_value;
        bool input_csc_enabled;
 };
 
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 1d64255..5f2054a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.c
@@ -444,10 +444,12 @@ void dpp1_set_cursor_position(
                struct dpp *dpp_base,
                const struct dc_cursor_position *pos,
                const struct dc_cursor_mi_param *param,
-               uint32_t width)
+               uint32_t width,
+               uint32_t height)
 {
        struct dcn10_dpp *dpp = TO_DCN10_DPP(dpp_base);
        int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
+       int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
        uint32_t cur_en = pos->enable ? 1 : 0;
 
        if (src_x_offset >= (int)param->viewport.width)
@@ -456,6 +458,12 @@ void dpp1_set_cursor_position(
        if (src_x_offset + (int)width <= 0)
                cur_en = 0;  /* not visible beyond left edge*/
 
+       if (src_y_offset >= (int)param->viewport.height)
+               cur_en = 0;  /* not visible beyond bottom edge*/
+
+       if (src_y_offset < 0)
+               cur_en = 0;  /* not visible beyond top edge*/
+
        REG_UPDATE(CURSOR0_CONTROL,
                        CUR0_ENABLE, cur_en);
 
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 e2889e6..282e22f 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_dpp.h
@@ -1374,7 +1374,8 @@ void dpp1_set_cursor_position(
                struct dpp *dpp_base,
                const struct dc_cursor_position *pos,
                const struct dc_cursor_mi_param *param,
-               uint32_t width);
+               uint32_t width,
+               uint32_t height);
 
 void dpp1_cnv_set_optional_cursor_attributes(
                        struct dpp *dpp_base,
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
index fe44a8e..8da2b8a 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.c
@@ -1084,6 +1084,7 @@ void hubp1_cursor_set_position(
 {
        struct dcn10_hubp *hubp1 = TO_DCN10_HUBP(hubp);
        int src_x_offset = pos->x - pos->x_hotspot - param->viewport.x;
+       int src_y_offset = pos->y - pos->y_hotspot - param->viewport.y;
        int x_hotspot = pos->x_hotspot;
        int y_hotspot = pos->y_hotspot;
        uint32_t dst_x_offset;
@@ -1127,6 +1128,12 @@ void hubp1_cursor_set_position(
        if (src_x_offset + (int)hubp->curs_attr.width <= 0)
                cur_en = 0;  /* not visible beyond left edge*/
 
+       if (src_y_offset >= (int)param->viewport.height)
+               cur_en = 0;  /* not visible beyond bottom edge*/
+
+       if (src_y_offset < 0) //+ (int)hubp->curs_attr.height
+               cur_en = 0;  /* not visible beyond top edge*/
+
        if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
                hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
 
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c 
b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
index 82fb1f9..4b8bedb 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
@@ -1947,9 +1947,13 @@ static void dcn10_update_mpcc(struct dc *dc, struct 
pipe_ctx *pipe_ctx)
                blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;
 
        blnd_cfg.overlap_only = false;
-       blnd_cfg.global_alpha = 0xff;
        blnd_cfg.global_gain = 0xff;
 
+       if (pipe_ctx->plane_state->global_alpha)
+               blnd_cfg.global_alpha = 
pipe_ctx->plane_state->global_alpha_value;
+       else
+               blnd_cfg.global_alpha = 0xff;
+
        /* DCN1.0 has output CM before MPC which seems to screw with
         * pre-multiplied alpha.
         */
@@ -2064,11 +2068,13 @@ static void update_dchubp_dpp(
                update_dpp(dpp, plane_state);
 
        if (plane_state->update_flags.bits.full_update ||
-               plane_state->update_flags.bits.per_pixel_alpha_change)
+               plane_state->update_flags.bits.per_pixel_alpha_change ||
+               plane_state->update_flags.bits.global_alpha_change)
                dc->hwss.update_mpcc(dc, pipe_ctx);
 
        if (plane_state->update_flags.bits.full_update ||
                plane_state->update_flags.bits.per_pixel_alpha_change ||
+               plane_state->update_flags.bits.global_alpha_change ||
                plane_state->update_flags.bits.scaling_change ||
                plane_state->update_flags.bits.position_change) {
                update_scaler(pipe_ctx);
@@ -2620,15 +2626,15 @@ static void dcn10_set_cursor_position(struct pipe_ctx 
*pipe_ctx)
                .mirror = pipe_ctx->plane_state->horizontal_mirror
        };
 
+       pos_cpy.x -= pipe_ctx->plane_state->dst_rect.x;
+       pos_cpy.y -= pipe_ctx->plane_state->dst_rect.y;
+
        if (pipe_ctx->plane_state->address.type
                        == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
                pos_cpy.enable = false;
 
-       if (pipe_ctx->top_pipe && pipe_ctx->plane_state != 
pipe_ctx->top_pipe->plane_state)
-               pos_cpy.enable = false;
-
        hubp->funcs->set_cursor_position(hubp, &pos_cpy, &param);
-       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, 
hubp->curs_attr.width);
+       dpp->funcs->set_cursor_position(dpp, &pos_cpy, &param, 
hubp->curs_attr.width, hubp->curs_attr.height);
 }
 
 static void dcn10_set_cursor_attribute(struct pipe_ctx *pipe_ctx)
diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h 
b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
index 80a480b..e894e64 100644
--- a/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
+++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dpp.h
@@ -147,7 +147,8 @@ struct dpp_funcs {
                        struct dpp *dpp_base,
                        const struct dc_cursor_position *pos,
                        const struct dc_cursor_mi_param *param,
-                       uint32_t width
+                       uint32_t width,
+                       uint32_t height
                        );
        void (*dpp_set_hdr_multiplier)(
                        struct dpp *dpp_base,
-- 
2.7.4

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to