It is to be used to enable HDR by allowing userpace to create and pass
3D LUTs to kernel and hardware.
new drm_colorop_type: DRM_COLOROP_3D_LUT.
Signed-off-by: Alex Hung <alex.h...@amd.com>
---
v8:
- Fix typo in subject (Simon Ser)
- Update documentation for DRM_COLOROP_3D_LUT (Simon Ser)
- Delete empty lines (Simon Ser)
v7:
- Simplify 3D LUT by removing lut_3d_modes and related functions (Simon Ser)
drivers/gpu/drm/drm_atomic.c | 6 +++
drivers/gpu/drm/drm_atomic_uapi.c | 6 +++
drivers/gpu/drm/drm_colorop.c | 72 +++++++++++++++++++++++++++++++
include/drm/drm_colorop.h | 21 +++++++++
include/uapi/drm/drm_mode.h | 33 ++++++++++++++
5 files changed, 138 insertions(+)
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 0efb0ead204a..ef47a06344f3 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -806,6 +806,12 @@ static void drm_atomic_colorop_print_state(struct
drm_printer *p,
case DRM_COLOROP_MULTIPLIER:
drm_printf(p, "\tmultiplier=%llu\n", state->multiplier);
break;
+ case DRM_COLOROP_3D_LUT:
+ drm_printf(p, "\tsize=%d\n", colorop->lut_size);
+ drm_printf(p, "\tinterpolation=%s\n",
+
drm_get_colorop_lut3d_interpolation_name(colorop->lut3d_interpolation));
+ drm_printf(p, "\tdata blob id=%d\n", state->data ?
state->data->base.id : 0);
+ break;
default:
break;
}
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c
b/drivers/gpu/drm/drm_atomic_uapi.c
index 947c18e8bf9b..d5d464b4d0f6 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -719,6 +719,10 @@ static int drm_atomic_color_set_data_property(struct
drm_colorop *colorop,
case DRM_COLOROP_CTM_3X4:
size = sizeof(struct drm_color_ctm_3x4);
break;
+ case DRM_COLOROP_3D_LUT:
+ size = colorop->lut_size * colorop->lut_size *
colorop->lut_size *
+ sizeof(struct drm_color_lut);
+ break;
default:
/* should never get here */
return -EINVAL;
@@ -771,6 +775,8 @@ drm_atomic_colorop_get_property(struct drm_colorop *colorop,
*val = state->multiplier;
} else if (property == colorop->lut_size_property) {
*val = colorop->lut_size;
+ } else if (property == colorop->lut3d_interpolation_property) {
+ *val = colorop->lut3d_interpolation;
} else if (property == colorop->data_property) {
*val = (state->data) ? state->data->base.id : 0;
} else {
diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c
index e03706e7179b..224c6be237d2 100644
--- a/drivers/gpu/drm/drm_colorop.c
+++ b/drivers/gpu/drm/drm_colorop.c
@@ -67,6 +67,7 @@ static const struct drm_prop_enum_list
drm_colorop_type_enum_list[] = {
{ DRM_COLOROP_1D_LUT, "1D LUT" },
{ DRM_COLOROP_CTM_3X4, "3x4 Matrix"},
{ DRM_COLOROP_MULTIPLIER, "Multiplier"},
+ { DRM_COLOROP_3D_LUT, "3D LUT"},
};
static const char * const colorop_curve_1d_type_names[] = {
@@ -82,6 +83,11 @@ static const struct drm_prop_enum_list
drm_colorop_lut1d_interpolation_list[] =
{ DRM_COLOROP_LUT1D_INTERPOLATION_LINEAR, "Linear" },
};
+
+static const struct drm_prop_enum_list drm_colorop_lut3d_interpolation_list[]
= {
+ { DRM_COLOROP_LUT3D_INTERPOLATION_TETRAHEDRAL, "Tetrahedral" },
+};
+
/* Init Helpers */
static int drm_colorop_init(struct drm_device *dev, struct drm_colorop
*colorop,
@@ -349,6 +355,51 @@ int drm_colorop_mult_init(struct drm_device *dev, struct
drm_colorop *colorop,
}
EXPORT_SYMBOL(drm_colorop_mult_init);
+int drm_colorop_3dlut_init(struct drm_device *dev, struct drm_colorop *colorop,
+ struct drm_plane *plane,
+ uint32_t lut_size,
+ enum drm_colorop_lut3d_interpolation_type
interpolation,
+ bool allow_bypass)
+{
+ struct drm_property *prop;
+ int ret;
+
+ ret = drm_colorop_init(dev, colorop, plane, DRM_COLOROP_3D_LUT,
allow_bypass);
+ if (ret)
+ return ret;
+
+ /* LUT size */
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE |
DRM_MODE_PROP_ATOMIC,
+ "SIZE", 0, UINT_MAX);
+ if (!prop)
+ return -ENOMEM;
+
+ colorop->lut_size_property = prop;
+ drm_object_attach_property(&colorop->base, colorop->lut_size_property,
lut_size);
+ colorop->lut_size = lut_size;
+
+ /* interpolation */
+ prop = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"LUT3D_INTERPOLATION",