aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/3559-drm-amd-display-Implement-color-management.patch
diff options
context:
space:
mode:
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.patch275
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
+