Skip to content

Commit 30ebe41

Browse files
effective-lightalexdeucher
authored andcommitted
drm/amd/display: add FB_DAMAGE_CLIPS support
Currently, userspace doesn't have a way to communicate selective updates to displays. So, enable support for FB_DAMAGE_CLIPS for DCN ASICs newer than DCN301, convert DRM damage clips to dc dirty rectangles and fill them into dirty_rects in fill_dc_dirty_rects(). Reviewed-by: Leo Li <[email protected]> Signed-off-by: Hamza Mahfooz <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent fed58c7 commit 30ebe41

File tree

2 files changed

+88
-46
lines changed

2 files changed

+88
-46
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

Lines changed: 84 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4869,6 +4869,35 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
48694869
return 0;
48704870
}
48714871

4872+
static inline void fill_dc_dirty_rect(struct drm_plane *plane,
4873+
struct rect *dirty_rect, int32_t x,
4874+
int32_t y, int32_t width, int32_t height,
4875+
int *i, bool ffu)
4876+
{
4877+
if (*i > DC_MAX_DIRTY_RECTS)
4878+
return;
4879+
4880+
if (*i == DC_MAX_DIRTY_RECTS)
4881+
goto out;
4882+
4883+
dirty_rect->x = x;
4884+
dirty_rect->y = y;
4885+
dirty_rect->width = width;
4886+
dirty_rect->height = height;
4887+
4888+
if (ffu)
4889+
drm_dbg(plane->dev,
4890+
"[PLANE:%d] PSR FFU dirty rect size (%d, %d)\n",
4891+
plane->base.id, width, height);
4892+
else
4893+
drm_dbg(plane->dev,
4894+
"[PLANE:%d] PSR SU dirty rect at (%d, %d) size (%d, %d)",
4895+
plane->base.id, x, y, width, height);
4896+
4897+
out:
4898+
(*i)++;
4899+
}
4900+
48724901
/**
48734902
* fill_dc_dirty_rects() - Fill DC dirty regions for PSR selective updates
48744903
*
@@ -4889,10 +4918,6 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
48894918
* addition, certain use cases - such as cursor and multi-plane overlay (MPO) -
48904919
* implicitly provide damage clips without any client support via the plane
48914920
* bounds.
4892-
*
4893-
* Today, amdgpu_dm only supports the MPO and cursor usecase.
4894-
*
4895-
* TODO: Also enable for FB_DAMAGE_CLIPS
48964921
*/
48974922
static void fill_dc_dirty_rects(struct drm_plane *plane,
48984923
struct drm_plane_state *old_plane_state,
@@ -4903,33 +4928,32 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
49034928
struct dm_crtc_state *dm_crtc_state = to_dm_crtc_state(crtc_state);
49044929
struct rect *dirty_rects = flip_addrs->dirty_rects;
49054930
uint32_t num_clips;
4931+
struct drm_mode_rect *clips;
49064932
bool bb_changed;
49074933
bool fb_changed;
49084934
uint32_t i = 0;
49094935

4910-
flip_addrs->dirty_rect_count = 0;
4911-
49124936
/*
49134937
* Cursor plane has it's own dirty rect update interface. See
49144938
* dcn10_dmub_update_cursor_data and dmub_cmd_update_cursor_info_data
49154939
*/
49164940
if (plane->type == DRM_PLANE_TYPE_CURSOR)
49174941
return;
49184942

4919-
/*
4920-
* Today, we only consider MPO use-case for PSR SU. If MPO not
4921-
* requested, and there is a plane update, do FFU.
4922-
*/
4943+
num_clips = drm_plane_get_damage_clips_count(new_plane_state);
4944+
clips = drm_plane_get_damage_clips(new_plane_state);
4945+
49234946
if (!dm_crtc_state->mpo_requested) {
4924-
dirty_rects[0].x = 0;
4925-
dirty_rects[0].y = 0;
4926-
dirty_rects[0].width = dm_crtc_state->base.mode.crtc_hdisplay;
4927-
dirty_rects[0].height = dm_crtc_state->base.mode.crtc_vdisplay;
4928-
flip_addrs->dirty_rect_count = 1;
4929-
DRM_DEBUG_DRIVER("[PLANE:%d] PSR FFU dirty rect size (%d, %d)\n",
4930-
new_plane_state->plane->base.id,
4931-
dm_crtc_state->base.mode.crtc_hdisplay,
4932-
dm_crtc_state->base.mode.crtc_vdisplay);
4947+
if (!num_clips || num_clips > DC_MAX_DIRTY_RECTS)
4948+
goto ffu;
4949+
4950+
for (; flip_addrs->dirty_rect_count < num_clips; clips++)
4951+
fill_dc_dirty_rect(new_plane_state->plane,
4952+
&dirty_rects[i], clips->x1,
4953+
clips->y1, clips->x2 - clips->x1,
4954+
clips->y2 - clips->y1,
4955+
&flip_addrs->dirty_rect_count,
4956+
false);
49334957
return;
49344958
}
49354959

@@ -4940,44 +4964,58 @@ static void fill_dc_dirty_rects(struct drm_plane *plane,
49404964
* If plane is moved or resized, also add old bounding box to dirty
49414965
* rects.
49424966
*/
4943-
num_clips = drm_plane_get_damage_clips_count(new_plane_state);
49444967
fb_changed = old_plane_state->fb->base.id !=
49454968
new_plane_state->fb->base.id;
49464969
bb_changed = (old_plane_state->crtc_x != new_plane_state->crtc_x ||
49474970
old_plane_state->crtc_y != new_plane_state->crtc_y ||
49484971
old_plane_state->crtc_w != new_plane_state->crtc_w ||
49494972
old_plane_state->crtc_h != new_plane_state->crtc_h);
49504973

4951-
DRM_DEBUG_DRIVER("[PLANE:%d] PSR bb_changed:%d fb_changed:%d num_clips:%d\n",
4952-
new_plane_state->plane->base.id,
4953-
bb_changed, fb_changed, num_clips);
4954-
4955-
if (num_clips || fb_changed || bb_changed) {
4956-
dirty_rects[i].x = new_plane_state->crtc_x;
4957-
dirty_rects[i].y = new_plane_state->crtc_y;
4958-
dirty_rects[i].width = new_plane_state->crtc_w;
4959-
dirty_rects[i].height = new_plane_state->crtc_h;
4960-
DRM_DEBUG_DRIVER("[PLANE:%d] PSR SU dirty rect at (%d, %d) size (%d, %d)\n",
4961-
new_plane_state->plane->base.id,
4962-
dirty_rects[i].x, dirty_rects[i].y,
4963-
dirty_rects[i].width, dirty_rects[i].height);
4964-
i += 1;
4965-
}
4974+
drm_dbg(plane->dev,
4975+
"[PLANE:%d] PSR bb_changed:%d fb_changed:%d num_clips:%d\n",
4976+
new_plane_state->plane->base.id,
4977+
bb_changed, fb_changed, num_clips);
49664978

4967-
/* Add old plane bounding-box if plane is moved or resized */
49684979
if (bb_changed) {
4969-
dirty_rects[i].x = old_plane_state->crtc_x;
4970-
dirty_rects[i].y = old_plane_state->crtc_y;
4971-
dirty_rects[i].width = old_plane_state->crtc_w;
4972-
dirty_rects[i].height = old_plane_state->crtc_h;
4973-
DRM_DEBUG_DRIVER("[PLANE:%d] PSR SU dirty rect at (%d, %d) size (%d, %d)\n",
4974-
old_plane_state->plane->base.id,
4975-
dirty_rects[i].x, dirty_rects[i].y,
4976-
dirty_rects[i].width, dirty_rects[i].height);
4977-
i += 1;
4978-
}
4980+
fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i],
4981+
new_plane_state->crtc_x,
4982+
new_plane_state->crtc_y,
4983+
new_plane_state->crtc_w,
4984+
new_plane_state->crtc_h, &i, false);
4985+
4986+
/* Add old plane bounding-box if plane is moved or resized */
4987+
fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i],
4988+
old_plane_state->crtc_x,
4989+
old_plane_state->crtc_y,
4990+
old_plane_state->crtc_w,
4991+
old_plane_state->crtc_h, &i, false);
4992+
}
4993+
4994+
if (num_clips) {
4995+
for (; i < num_clips; clips++)
4996+
fill_dc_dirty_rect(new_plane_state->plane,
4997+
&dirty_rects[i], clips->x1,
4998+
clips->y1, clips->x2 - clips->x1,
4999+
clips->y2 - clips->y1, &i, false);
5000+
} else if (fb_changed && !bb_changed) {
5001+
fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[i],
5002+
new_plane_state->crtc_x,
5003+
new_plane_state->crtc_y,
5004+
new_plane_state->crtc_w,
5005+
new_plane_state->crtc_h, &i, false);
5006+
}
5007+
5008+
if (i > DC_MAX_DIRTY_RECTS)
5009+
goto ffu;
49795010

49805011
flip_addrs->dirty_rect_count = i;
5012+
return;
5013+
5014+
ffu:
5015+
fill_dc_dirty_rect(new_plane_state->plane, &dirty_rects[0], 0, 0,
5016+
dm_crtc_state->base.mode.crtc_hdisplay,
5017+
dm_crtc_state->base.mode.crtc_vdisplay,
5018+
&flip_addrs->dirty_rect_count, true);
49815019
}
49825020

49835021
static void update_stream_scaling_settings(const struct drm_display_mode *mode,

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,6 +1600,10 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
16001600
drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
16011601
supported_rotations);
16021602

1603+
if (dm->adev->ip_versions[DCE_HWIP][0] > IP_VERSION(3, 0, 1) &&
1604+
plane->type != DRM_PLANE_TYPE_CURSOR)
1605+
drm_plane_enable_fb_damage_clips(plane);
1606+
16031607
drm_plane_helper_add(plane, &dm_plane_helper_funcs);
16041608

16051609
#ifdef CONFIG_DRM_AMD_DC_HDR

0 commit comments

Comments
 (0)