|
@@ -231,18 +231,21 @@ void amdgpu_dm_set_ctm(struct dm_crtc_state *crtc)
|
|
* preparation for hardware commit. If no lut is specified by user, we default
|
|
* preparation for hardware commit. If no lut is specified by user, we default
|
|
* to SRGB degamma.
|
|
* to SRGB degamma.
|
|
*
|
|
*
|
|
- * Currently, we only support degamma bypass, or preprogrammed SRGB degamma.
|
|
|
|
- * Programmable degamma is not supported, and an attempt to do so will return
|
|
|
|
- * -EINVAL.
|
|
|
|
|
|
+ * We support degamma bypass, predefined SRGB, and custom degamma
|
|
*
|
|
*
|
|
* RETURNS:
|
|
* RETURNS:
|
|
- * 0 on success, -EINVAL if custom degamma curve is given.
|
|
|
|
|
|
+ * 0 on success
|
|
|
|
+ * -EINVAL if crtc_state has a degamma_lut of invalid size
|
|
|
|
+ * -ENOMEM if gamma allocation fails
|
|
*/
|
|
*/
|
|
int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state,
|
|
int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state,
|
|
struct dc_plane_state *dc_plane_state)
|
|
struct dc_plane_state *dc_plane_state)
|
|
{
|
|
{
|
|
struct drm_property_blob *blob = crtc_state->degamma_lut;
|
|
struct drm_property_blob *blob = crtc_state->degamma_lut;
|
|
struct drm_color_lut *lut;
|
|
struct drm_color_lut *lut;
|
|
|
|
+ uint32_t lut_size;
|
|
|
|
+ struct dc_gamma *gamma;
|
|
|
|
+ bool ret;
|
|
|
|
|
|
if (!blob) {
|
|
if (!blob) {
|
|
/* Default to SRGB */
|
|
/* Default to SRGB */
|
|
@@ -258,11 +261,30 @@ int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
- /* Otherwise, assume SRGB, since programmable degamma is not
|
|
|
|
- * supported.
|
|
|
|
- */
|
|
|
|
- dc_plane_state->in_transfer_func->type = TF_TYPE_PREDEFINED;
|
|
|
|
- dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
|
|
|
|
- return -EINVAL;
|
|
|
|
|
|
+ gamma = dc_create_gamma();
|
|
|
|
+ if (!gamma)
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+
|
|
|
|
+ lut_size = blob->length / sizeof(struct drm_color_lut);
|
|
|
|
+ gamma->num_entries = lut_size;
|
|
|
|
+ if (gamma->num_entries == MAX_COLOR_LUT_ENTRIES)
|
|
|
|
+ gamma->type = GAMMA_CUSTOM;
|
|
|
|
+ else {
|
|
|
|
+ dc_gamma_release(&gamma);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ __drm_lut_to_dc_gamma(lut, gamma, false);
|
|
|
|
+
|
|
|
|
+ dc_plane_state->in_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS;
|
|
|
|
+ ret = mod_color_calculate_degamma_params(dc_plane_state->in_transfer_func, gamma, true);
|
|
|
|
+ dc_gamma_release(&gamma);
|
|
|
|
+ if (!ret) {
|
|
|
|
+ dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS;
|
|
|
|
+ DRM_ERROR("Out of memory when calculating degamma params\n");
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|