summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
diff options
context:
space:
mode:
authorJoshua Ashton <joshua@froggi.es>2023-11-16 18:57:51 -0100
committerAlex Deucher <alexander.deucher@amd.com>2023-12-13 16:08:00 -0500
commit0ef47454dc82358b62a424b37c7520a84f307edb (patch)
treecfcf6e4a702231eb1d426657a60e0c8db1a8e1df /drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
parentf545d82479b46368bf00d0bfecf33fa914bd5f8f (diff)
downloadlinux-0ef47454dc82358b62a424b37c7520a84f307edb.tar.gz
linux-0ef47454dc82358b62a424b37c7520a84f307edb.tar.bz2
linux-0ef47454dc82358b62a424b37c7520a84f307edb.zip
drm/amd/display: add plane blend LUT and TF driver-specific properties
Blend 1D LUT or a pre-defined transfer function (TF) can be set to linearize content before blending, so that it's positioned just before blending planes in the AMD color mgmt pipeline, and after 3D LUT (non-linear space). Shaper and Blend LUTs are 1D LUTs that sandwich 3D LUT. Drivers should advertize blend properties according to HW caps. There is no blend ROM for pre-defined TF. When setting blend TF (!= Identity) and LUT at the same time, the color module will combine the pre-defined TF and the custom LUT values into the LUT that's actually programmed. v3: - spell out TF+LUT behavior in the commit and comments (Harry) v5: - get blend blob correctly Reviewed-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Joshua Ashton <joshua@froggi.es> Signed-off-by: Melissa Wen <mwen@igalia.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c')
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index 7f0de29889f0..35a4732483ba 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -1344,6 +1344,7 @@ static void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane)
amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT;
amdgpu_state->shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
+ amdgpu_state->blend_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT;
}
static struct drm_plane_state *amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane)
@@ -1371,10 +1372,14 @@ static struct drm_plane_state *amdgpu_dm_plane_drm_plane_duplicate_state(struct
if (old_dm_plane_state->lut3d)
dm_plane_state->lut3d =
drm_property_blob_get(old_dm_plane_state->lut3d);
+ if (old_dm_plane_state->blend_lut)
+ dm_plane_state->blend_lut =
+ drm_property_blob_get(old_dm_plane_state->blend_lut);
dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf;
dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult;
dm_plane_state->shaper_tf = old_dm_plane_state->shaper_tf;
+ dm_plane_state->blend_tf = old_dm_plane_state->blend_tf;
return &dm_plane_state->base;
}
@@ -1449,6 +1454,8 @@ static void amdgpu_dm_plane_drm_plane_destroy_state(struct drm_plane *plane,
drm_property_blob_put(dm_plane_state->lut3d);
if (dm_plane_state->shaper_lut)
drm_property_blob_put(dm_plane_state->shaper_lut);
+ if (dm_plane_state->blend_lut)
+ drm_property_blob_put(dm_plane_state->blend_lut);
if (dm_plane_state->dc_state)
dc_plane_state_release(dm_plane_state->dc_state);
@@ -1498,6 +1505,17 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm,
mode_info.plane_lut3d_size_property,
MAX_COLOR_3DLUT_SIZE);
}
+
+ if (dpp_color_caps.ogam_ram) {
+ drm_object_attach_property(&plane->base,
+ mode_info.plane_blend_lut_property, 0);
+ drm_object_attach_property(&plane->base,
+ mode_info.plane_blend_lut_size_property,
+ MAX_COLOR_LUT_ENTRIES);
+ drm_object_attach_property(&plane->base,
+ mode_info.plane_blend_tf_property,
+ AMDGPU_TRANSFER_FUNCTION_DEFAULT);
+ }
}
static int
@@ -1550,6 +1568,19 @@ dm_atomic_plane_set_property(struct drm_plane *plane,
&replaced);
dm_plane_state->base.color_mgmt_changed |= replaced;
return ret;
+ } else if (property == adev->mode_info.plane_blend_lut_property) {
+ ret = drm_property_replace_blob_from_id(plane->dev,
+ &dm_plane_state->blend_lut,
+ val, -1,
+ sizeof(struct drm_color_lut),
+ &replaced);
+ dm_plane_state->base.color_mgmt_changed |= replaced;
+ return ret;
+ } else if (property == adev->mode_info.plane_blend_tf_property) {
+ if (dm_plane_state->blend_tf != val) {
+ dm_plane_state->blend_tf = val;
+ dm_plane_state->base.color_mgmt_changed = 1;
+ }
} else {
drm_dbg_atomic(plane->dev,
"[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n",
@@ -1585,6 +1616,12 @@ dm_atomic_plane_get_property(struct drm_plane *plane,
} else if (property == adev->mode_info.plane_lut3d_property) {
*val = (dm_plane_state->lut3d) ?
dm_plane_state->lut3d->base.id : 0;
+ } else if (property == adev->mode_info.plane_blend_lut_property) {
+ *val = (dm_plane_state->blend_lut) ?
+ dm_plane_state->blend_lut->base.id : 0;
+ } else if (property == adev->mode_info.plane_blend_tf_property) {
+ *val = dm_plane_state->blend_tf;
+
} else {
return -EINVAL;
}