Add plane lut_3d mode and lut_3d as blob properties. lut_3d mode is an enum property with values as blob_ids. Userspace can get supported modes and also set one of the modes. Note: A patchset "IGT tests for pre-blending 3D LUT interfaces" for this proposal is sent to IGT mailing list. Signed-off-by: Alex Hung <alex.hung@xxxxxxx> --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++ drivers/gpu/drm/drm_atomic_state_helper.c | 3 ++ drivers/gpu/drm/drm_atomic_uapi.c | 11 ++++++ drivers/gpu/drm/drm_color_mgmt.c | 37 +++++++++++++++++++ include/drm/drm_mode_object.h | 2 +- include/drm/drm_plane.h | 31 ++++++++++++++++ 6 files changed, 87 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index f546c1326db3..ee277f357140 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8006,6 +8006,10 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, drm_plane_attach_gamma_properties(plane); drm_plane_attach_ctm_property(plane); + /* TODO need to check ASICs */ + drm_plane_create_3d_lut_properties(plane->dev, plane, 1); + drm_plane_attach_3dlut_properties(plane); + /* Create (reset) the plane state */ if (plane->funcs->reset) plane->funcs->reset(plane); diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 7ddf6e4b956b..85900cd1bffe 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -318,6 +318,8 @@ void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane, drm_property_blob_get(state->ctm); if (state->gamma_lut) drm_property_blob_get(state->gamma_lut); + if (state->lut_3d) + drm_property_blob_get(state->lut_3d); state->color_mgmt_changed = false; } @@ -369,6 +371,7 @@ void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state) drm_property_blob_put(state->degamma_lut); drm_property_blob_put(state->ctm); drm_property_blob_put(state->gamma_lut); + drm_property_blob_put(state->lut_3d); } EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index ba3e64cb184a..66e59e7c194d 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -622,6 +622,13 @@ static int drm_atomic_plane_set_property(struct drm_plane *plane, &replaced); state->color_mgmt_changed |= replaced; return ret; + } else if (property == plane->lut_3d_property) { + ret = drm_atomic_replace_property_blob_from_id(dev, + &state->lut_3d, val, -1, 8, &replaced); + state->color_mgmt_changed |= replaced; + return 0; + } else if (property == plane->lut_3d_mode_property) { + state->lut_3d_mode = val; } else if (property == config->prop_fb_damage_clips) { ret = drm_atomic_replace_property_blob_from_id(dev, &state->fb_damage_clips, @@ -700,6 +707,10 @@ drm_atomic_plane_get_property(struct drm_plane *plane, } else if (property == plane->gamma_lut_property) { *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0; + } else if (property == plane->lut_3d_property) { + *val = (state->lut_3d) ? state->lut_3d->base.id : 0; + } else if (property == plane->lut_3d_mode_property) { + *val = state->lut_3d_mode; } else if (property == config->prop_fb_damage_clips) { *val = (state->fb_damage_clips) ? state->fb_damage_clips->base.id : 0; diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c index b5b3ff7f654d..4bfe5b5c9670 100644 --- a/drivers/gpu/drm/drm_color_mgmt.c +++ b/drivers/gpu/drm/drm_color_mgmt.c @@ -706,6 +706,43 @@ void drm_plane_attach_gamma_properties(struct drm_plane *plane) } EXPORT_SYMBOL(drm_plane_attach_gamma_properties); +int drm_plane_create_3d_lut_properties(struct drm_device *dev, + struct drm_plane *plane, + int num_values) +{ + struct drm_property *mode; + struct drm_property *blob; + + mode = drm_property_create(dev, DRM_MODE_PROP_ENUM, "PLANE_3D_LUT_MODE", num_values); + if (!mode) + return -ENOMEM; + + plane->lut_3d_mode_property = mode; + + blob = drm_property_create(dev, DRM_MODE_PROP_BLOB, "PLANE_3D_LUT", 0); + if (!blob) + return -ENOMEM; + + plane->lut_3d_property = blob; + + return 0; +} +EXPORT_SYMBOL(drm_plane_create_3d_lut_properties); + +void drm_plane_attach_3dlut_properties(struct drm_plane *plane) +{ + if (!plane->lut_3d_property) + return; + + drm_object_attach_property(&plane->base, plane->lut_3d_property, 0); + + if (!plane->lut_3d_mode_property) + return; + + drm_object_attach_property(&plane->base, plane->lut_3d_mode_property, 0); +} +EXPORT_SYMBOL(drm_plane_attach_3dlut_properties); + int drm_plane_color_add_gamma_degamma_mode_range(struct drm_plane *plane, const char *name, const struct drm_color_lut_range *ranges, diff --git a/include/drm/drm_mode_object.h b/include/drm/drm_mode_object.h index d4128c7daa08..c2b31dbf7325 100644 --- a/include/drm/drm_mode_object.h +++ b/include/drm/drm_mode_object.h @@ -60,7 +60,7 @@ struct drm_mode_object { void (*free_cb)(struct kref *kref); }; -#define DRM_OBJECT_MAX_PROPERTY 26 +#define DRM_OBJECT_MAX_PROPERTY 28 /** * struct drm_object_properties - property tracking for &drm_mode_object */ diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 8989bb1aa46c..4e272144170f 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -275,6 +275,21 @@ struct drm_plane_state { */ struct drm_property_blob *gamma_lut; + /** + * @lut_3d_mode: + * This is a blob_id and exposes the platform capabilities wrt + * various 3dlut. This also helps user select a 3dlut mode amongst + * the supported ones. + */ + u32 lut_3d_mode; + + /** + * @lut_3d: + * 3D lookup table blob. The blob data is laid out as defined by the + * FOURCC value in color_format in the drm_mode_3dlut_mode struct. + */ + struct drm_property_blob *lut_3d; + u8 color_mgmt_changed : 1; }; @@ -818,6 +833,18 @@ struct drm_plane { * used to convert the framebuffer's colors to non-linear gamma. */ struct drm_property *gamma_lut_property; + + /** + * @lut_3d_mode_property: Optional Plane property to set the 3DLUT mode + * used to convert the framebuffer's colors to non-linear gamma. + */ + struct drm_property *lut_3d_mode_property; + + /** + * @lut_3d_property: Optional Plane property to set the 3DLUT + * used to convert the framebuffer's colors to non-linear gamma. + */ + struct drm_property *lut_3d_property; }; #define obj_to_plane(x) container_of(x, struct drm_plane, base) @@ -915,6 +942,10 @@ int drm_plane_create_color_mgmt_properties(struct drm_device *dev, void drm_plane_attach_degamma_properties(struct drm_plane *plane); void drm_plane_attach_ctm_property(struct drm_plane *plane); void drm_plane_attach_gamma_properties(struct drm_plane *plane); +int drm_plane_create_3d_lut_properties(struct drm_device *dev, + struct drm_plane *plane, + int num_values); +void drm_plane_attach_3dlut_properties(struct drm_plane *plane); int drm_plane_color_add_gamma_degamma_mode_range(struct drm_plane *plane, const char *name, const struct drm_color_lut_range *ranges, -- 2.37.3