@@ -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);
@@ -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);
@@ -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;
@@ -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,
@@ -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
*/
@@ -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,
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@amd.com> --- .../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(-)