drm/amd/display: Optimize cursor position updates
authorAric Cyr <Aric.Cyr@amd.com>
Tue, 10 Dec 2024 23:38:15 +0000 (18:38 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 24 Jan 2025 14:56:28 +0000 (09:56 -0500)
[why]
Updating the cursor enablement register can be a slow operation and accumulates
when high polling rate cursors cause frequent updates asynchronously to the
cursor position.

[how]
Since the cursor enable bit is cached there is no need to update the
enablement register if there is no change to it.  This removes the
read-modify-write from the cursor position programming path in HUBP and
DPP, leaving only the register writes.

Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: Sung Lee <sung.lee@amd.com>
Signed-off-by: Aric Cyr <Aric.Cyr@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dpp/dcn10/dcn10_dpp.c
drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp_cm.c
drivers/gpu/drm/amd/display/dc/hubp/dcn20/dcn20_hubp.c
drivers/gpu/drm/amd/display/dc/hubp/dcn401/dcn401_hubp.c

index 961d8936150ab75fea169f6c701b094645233c93..75fb77bca83ba23f027d093645a928556aa17f37 100644 (file)
@@ -483,10 +483,11 @@ void dpp1_set_cursor_position(
        if (src_y_offset + cursor_height <= 0)
                cur_en = 0;  /* not visible beyond top edge*/
 
-       REG_UPDATE(CURSOR0_CONTROL,
-                       CUR0_ENABLE, cur_en);
+       if (dpp_base->pos.cur0_ctl.bits.cur0_enable != cur_en) {
+               REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en);
 
-       dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
+               dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
+       }
 }
 
 void dpp1_cnv_set_optional_cursor_attributes(
index 3b6ca7974e188df5ed8bd7579fd416acd12e950e..1236e0f9a2560cbf87894adddb5faac817da4292 100644 (file)
@@ -154,9 +154,11 @@ void dpp401_set_cursor_position(
        struct dcn401_dpp *dpp = TO_DCN401_DPP(dpp_base);
        uint32_t cur_en = pos->enable ? 1 : 0;
 
-       REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en);
+       if (dpp_base->pos.cur0_ctl.bits.cur0_enable != cur_en) {
+               REG_UPDATE(CURSOR0_CONTROL, CUR0_ENABLE, cur_en);
 
-       dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
+               dpp_base->pos.cur0_ctl.bits.cur0_enable = cur_en;
+       }
 }
 
 void dpp401_set_optional_cursor_attributes(
index a748e6ab9c82892e2b65414fb3946094e32e93bd..91259b896e0320884efedadbe5f36e1a63858f30 100644 (file)
@@ -1058,11 +1058,13 @@ void hubp2_cursor_set_position(
        if (src_y_offset + cursor_height <= 0)
                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);
+       if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) {
+               if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
+                       hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
 
-       REG_UPDATE(CURSOR_CONTROL,
+               REG_UPDATE(CURSOR_CONTROL,
                        CURSOR_ENABLE, cur_en);
+       }
 
        REG_SET_2(CURSOR_POSITION, 0,
                        CURSOR_X_POSITION, pos->x,
index d8b81ad69e35aee2f01248e81e2ce79a796f9b24..5ed195377a6ce0b02a5ccfd2c7283081df2a2c5a 100644 (file)
@@ -742,11 +742,13 @@ void hubp401_cursor_set_position(
                        dc_fixpt_from_int(dst_x_offset),
                        param->h_scale_ratio));
 
-       if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
-               hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
+       if (hubp->pos.cur_ctl.bits.cur_enable != cur_en) {
+               if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
+                       hubp->funcs->set_cursor_attributes(hubp, &hubp->curs_attr);
 
-       REG_UPDATE(CURSOR_CONTROL,
-               CURSOR_ENABLE, cur_en);
+               REG_UPDATE(CURSOR_CONTROL,
+                       CURSOR_ENABLE, cur_en);
+       }
 
        REG_SET_2(CURSOR_POSITION, 0,
                CURSOR_X_POSITION, x_pos,