Shaper 1D LUT delinearizes content before applying 3D LUT so that, it comes before 3D LUT. It's an optional property and drivers should attach it according to HW caps. Signed-off-by: Melissa Wen <mwen@xxxxxxxxxx> --- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 14 ++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 10 ++++++++++ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 5 +++++ .../amd/display/amdgpu_dm/amdgpu_dm_plane.c | 19 +++++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 8d4726978c6e..f41406ee96ad 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -1332,6 +1332,20 @@ amdgpu_display_create_color_properties(struct amdgpu_device *adev) return -ENOMEM; adev->mode_info.plane_hdr_mult_property = prop; + prop = drm_property_create(adev_to_drm(adev), + DRM_MODE_PROP_BLOB, + "AMD_PLANE_SHAPER_LUT", 0); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_shaper_lut_property = prop; + + prop = drm_property_create_range(adev_to_drm(adev), + DRM_MODE_PROP_IMMUTABLE, + "AMD_PLANE_SHAPER_LUT_SIZE", 0, UINT_MAX); + if (!prop) + return -ENOMEM; + adev->mode_info.plane_shaper_lut_size_property = prop; + prop = drm_property_create(adev_to_drm(adev), DRM_MODE_PROP_BLOB, "AMD_PLANE_LUT3D", 0); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index 9d9dac26edfc..756d5f70be0a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -391,6 +391,16 @@ struct amdgpu_mode_info { * @plane_hdr_mult_property: */ struct drm_property *plane_hdr_mult_property; + /** + * @shaper_lut_property: Plane property to set pre-blending shaper LUT + * that converts color content before 3D LUT. + */ + struct drm_property *plane_shaper_lut_property; + /** + * @shaper_lut_size_property: Plane property for the size of + * pre-blending shaper LUT as supported by the driver (read-only). + */ + struct drm_property *plane_shaper_lut_size_property; /** * @plane_lut3d_property: Plane property for gamma correction using a * 3D LUT (pre-blending). diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index b0ba0279dc25..d3ecc73129ff 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -748,6 +748,11 @@ struct dm_plane_state { * S31.32 sign-magnitude. */ __u64 hdr_mult; + /** + * @shaper_lut: shaper lookup table blob. The blob (if not NULL) is an + * array of &struct drm_color_lut. + */ + struct drm_property_blob *shaper_lut; /** * @lut3d: 3D lookup table blob. The blob (if not NULL) is an array of * &struct drm_color_lut. 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 0e418e161b0b..69e2f1f86cce 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 @@ -1347,6 +1347,8 @@ dm_drm_plane_duplicate_state(struct drm_plane *plane) #ifdef CONFIG_STEAM_DECK if (dm_plane_state->degamma_lut) drm_property_blob_get(dm_plane_state->degamma_lut); + if (dm_plane_state->shaper_lut) + drm_property_blob_get(dm_plane_state->shaper_lut); if (dm_plane_state->lut3d) drm_property_blob_get(dm_plane_state->lut3d); #endif @@ -1419,6 +1421,7 @@ static void dm_drm_plane_destroy_state(struct drm_plane *plane, struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); #ifdef CONFIG_STEAM_DECK drm_property_blob_put(dm_plane_state->degamma_lut); + drm_property_blob_put(dm_plane_state->shaper_lut); drm_property_blob_put(dm_plane_state->lut3d); #endif @@ -1495,6 +1498,11 @@ dm_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, AMDGPU_HDR_MULT_DEFAULT); if (dm->dc->caps.color.dpp.hw_3d_lut) { + drm_object_attach_property(&plane->base, + dm->adev->mode_info.plane_shaper_lut_property, 0); + drm_object_attach_property(&plane->base, + dm->adev->mode_info.plane_shaper_lut_size_property, + MAX_COLOR_LUT_ENTRIES); drm_object_attach_property(&plane->base, dm->adev->mode_info.plane_lut3d_property, 0); drm_object_attach_property(&plane->base, @@ -1531,6 +1539,14 @@ dm_atomic_plane_set_property(struct drm_plane *plane, dm_plane_state->hdr_mult = val; dm_plane_state->base.color_mgmt_changed = 1; } + } else if (property == adev->mode_info.plane_shaper_lut_property) { + ret = amdgpu_dm_replace_property_blob_from_id(plane->dev, + &dm_plane_state->shaper_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_lut3d_property) { ret = amdgpu_dm_replace_property_blob_from_id(plane->dev, &dm_plane_state->lut3d, @@ -1567,6 +1583,9 @@ dm_atomic_plane_get_property(struct drm_plane *plane, *val = dm_plane_state->degamma_tf; } else if (property == adev->mode_info.plane_hdr_mult_property) { *val = dm_plane_state->hdr_mult; + } else if (property == adev->mode_info.plane_shaper_lut_property) { + *val = (dm_plane_state->shaper_lut) ? + dm_plane_state->shaper_lut->base.id : 0; } else if (property == adev->mode_info.plane_lut3d_property) { *val = (dm_plane_state->lut3d) ? dm_plane_state->lut3d->base.id : 0; -- 2.39.2