diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3559-drm-amd-display-Implement-color-management.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3559-drm-amd-display-Implement-color-management.patch | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3559-drm-amd-display-Implement-color-management.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3559-drm-amd-display-Implement-color-management.patch new file mode 100644 index 00000000..443651a8 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3559-drm-amd-display-Implement-color-management.patch @@ -0,0 +1,275 @@ +From 33ff16dbf765fafcb0e8ccda269f55734e7d2bb8 Mon Sep 17 00:00:00 2001 +From: "Leo (Sunpeng) Li" <sunpeng.li@amd.com> +Date: Fri, 2 Feb 2018 10:18:05 -0500 +Subject: [PATCH 3559/4131] drm/amd/display: Implement color management + +Implement color management functionalities within amdgpu_dm_color, and +expose functions within amdgpu_dm.h. + +Change-Id: Iedc0761fcd1f14e08afeee502e3e0ae3aa6dd8d8 +Signed-off-by: Leo (Sunpeng) Li <sunpeng.li@amd.com> +Reviewed-by: Harry Wentland <Harry.Wentland@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/display/amdgpu_dm/Makefile | 2 +- + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 5 + + .../drm/amd/display/amdgpu_dm/amdgpu_dm_color.c | 218 +++++++++++++++++++++ + 3 files changed, 224 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c + +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile +index 0b41f3d..8af5ccc 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/Makefile +@@ -4,7 +4,7 @@ + + + +-AMDGPUDM = amdgpu_dm.o amdgpu_dm_irq.o amdgpu_dm_mst_types.o ++AMDGPUDM = amdgpu_dm.o amdgpu_dm_irq.o amdgpu_dm_mst_types.o amdgpu_dm_color.o + + ifneq ($(CONFIG_DRM_AMD_DC),) + AMDGPUDM += amdgpu_dm_services.o amdgpu_dm_helpers.o +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 1242036..9c556d8 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +@@ -269,6 +269,11 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc); + #define amdgpu_dm_crtc_handle_crc_irq(x) + #endif + ++int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state, ++ struct dc_plane_state *dc_plane_state); ++void amdgpu_dm_set_ctm(struct dm_crtc_state *crtc); ++int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc); ++ + extern const struct drm_encoder_helper_funcs amdgpu_dm_encoder_helper_funcs; + + #endif /* __AMDGPU_DM_H__ */ +diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +new file mode 100644 +index 0000000..cc3ee07 +--- /dev/null ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +@@ -0,0 +1,218 @@ ++/* ++ * Copyright 2018 Advanced Micro Devices, Inc. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: AMD ++ * ++ */ ++ ++#include "amdgpu_mode.h" ++#include "amdgpu_dm.h" ++#include "modules/color/color_gamma.h" ++ ++ ++#define MAX_LUT_ENTRIES 256 ++ ++/* ++ * Return true if the given lut is a linear mapping of values, i.e. it acts ++ * like a bypass LUT. ++ * ++ * It is considered linear if the lut represents: ++ * f(a) = (0xFF00/MAX_LUT_ENTRIES-1)a; for integer a in [0, MAX_LUT_ENTRIES) ++ */ ++static bool __is_lut_linear(struct drm_color_lut *lut) ++{ ++ int i; ++ uint32_t max_os = 0xFF00; ++ uint32_t expected; ++ int delta; ++ ++ for (i = 0; i < MAX_LUT_ENTRIES; i++) { ++ /* All color values should equal */ ++ if ((lut[i].red != lut[i].green) || (lut[i].green != lut[i].blue)) ++ return false; ++ ++ expected = i * max_os / (MAX_LUT_ENTRIES-1); ++ ++ /* Allow a +/-1 error. */ ++ delta = lut[i].red - expected; ++ if (delta < -1 || 1 < delta) ++ return false; ++ } ++ return true; ++} ++ ++/** ++ * amdgpu_dm_set_regamma_lut: Set regamma lut for the given CRTC. ++ * @crtc: amdgpu_dm crtc state ++ * ++ * Update the underlying dc_stream_state's output transfer function (OTF) in ++ * preparation for hardware commit. If no lut is specified by user, we default ++ * to SRGB. ++ * ++ * RETURNS: ++ * 0 on success, -ENOMEM if memory cannot be allocated to calculate the OTF. ++ */ ++int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc) ++{ ++ struct drm_property_blob *blob = crtc->base.gamma_lut; ++ struct dc_stream_state *stream = crtc->stream; ++ struct drm_color_lut *lut; ++ struct dc_gamma *gamma; ++ enum dc_transfer_func_type old_type = stream->out_transfer_func->type; ++ ++ uint32_t r, g, b; ++ int i; ++ bool ret; ++ ++ if (!blob) { ++ /* By default, use the SRGB predefined curve.*/ ++ stream->out_transfer_func->type = TF_TYPE_PREDEFINED; ++ stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; ++ return 0; ++ } ++ ++ lut = (struct drm_color_lut *)blob->data; ++ ++ if (__is_lut_linear(lut)) { ++ /* Set to bypass if lut is set to linear */ ++ stream->out_transfer_func->type = TF_TYPE_BYPASS; ++ stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; ++ return 0; ++ } ++ ++ gamma = dc_create_gamma(); ++ if (!gamma) ++ return -ENOMEM; ++ ++ gamma->num_entries = MAX_LUT_ENTRIES; ++ gamma->type = GAMMA_RGB_256; ++ ++ /* Truncate, and store in dc_gamma for output tf calculation */ ++ for (i = 0; i < gamma->num_entries; i++) { ++ r = drm_color_lut_extract(lut[i].red, 16); ++ g = drm_color_lut_extract(lut[i].green, 16); ++ b = drm_color_lut_extract(lut[i].blue, 16); ++ ++ gamma->entries.red[i] = dal_fixed31_32_from_int(r); ++ gamma->entries.green[i] = dal_fixed31_32_from_int(g); ++ gamma->entries.blue[i] = dal_fixed31_32_from_int(b); ++ } ++ ++ /* Call color module to translate into something DC understands. Namely ++ * a transfer function. ++ */ ++ stream->out_transfer_func->type = TF_TYPE_DISTRIBUTED_POINTS; ++ ret = mod_color_calculate_regamma_params(stream->out_transfer_func, ++ gamma, true); ++ dc_gamma_release(&gamma); ++ if (!ret) { ++ stream->out_transfer_func->type = old_type; ++ DRM_ERROR("Out of memory when calculating regamma params\n"); ++ return -ENOMEM; ++ } ++ ++ return 0; ++} ++ ++/** ++ * amdgpu_dm_set_ctm: Set the color transform matrix for the given CRTC. ++ * @crtc: amdgpu_dm crtc state ++ * ++ * Update the underlying dc_stream_state's gamut remap matrix in preparation ++ * for hardware commit. If no matrix is specified by user, gamut remap will be ++ * disabled. ++ */ ++void amdgpu_dm_set_ctm(struct dm_crtc_state *crtc) ++{ ++ ++ struct drm_property_blob *blob = crtc->base.ctm; ++ struct dc_stream_state *stream = crtc->stream; ++ struct drm_color_ctm *ctm; ++ int i; ++ ++ if (!blob) { ++ stream->gamut_remap_matrix.enable_remap = false; ++ return; ++ } ++ ++ stream->gamut_remap_matrix.enable_remap = true; ++ ctm = (struct drm_color_ctm *)blob->data; ++ /* ++ * DRM gives a 3x3 matrix, but DC wants 3x4. Assuming we're operating ++ * with homogeneous coordinates, augment the matrix with 0's. ++ * ++ * The format provided is S31.32, which is the same as our fixed31_32. ++ */ ++ for (i = 0; i < 12; i++) { ++ /* Skip 4th element */ ++ if (i % 4 == 3) { ++ stream->gamut_remap_matrix.matrix[i] = dal_fixed31_32_zero; ++ continue; ++ } ++ /* csc[i] = ctm[i - floor(i/4)] */ ++ stream->gamut_remap_matrix.matrix[i].value = ctm->matrix[i - (i/4)]; ++ } ++} ++ ++ ++/** ++ * amdgpu_dm_set_degamma_lut: Set degamma lut for the given CRTC. ++ * @crtc: amdgpu_dm crtc state ++ * ++ * Update the underlying dc_stream_state's input transfer function (ITF) in ++ * preparation for hardware commit. If no lut is specified by user, we default ++ * 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. ++ * ++ * RETURNS: ++ * 0 on success, -EINVAL if custom degamma curve is given. ++ */ ++int amdgpu_dm_set_degamma_lut(struct drm_crtc_state *crtc_state, ++ struct dc_plane_state *dc_plane_state) ++{ ++ struct drm_property_blob *blob = crtc_state->degamma_lut; ++ struct drm_color_lut *lut; ++ ++ if (!blob) { ++ /* Default to SRGB */ ++ dc_plane_state->in_transfer_func->type = TF_TYPE_PREDEFINED; ++ dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_SRGB; ++ return 0; ++ } ++ ++ lut = (struct drm_color_lut *)blob->data; ++ if (__is_lut_linear(lut)) { ++ dc_plane_state->in_transfer_func->type = TF_TYPE_BYPASS; ++ dc_plane_state->in_transfer_func->tf = TRANSFER_FUNCTION_LINEAR; ++ 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; ++} ++ +-- +2.7.4 + |