aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/files/0791-drm-amd-dal-opp-for-underlay.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/files/0791-drm-amd-dal-opp-for-underlay.patch')
-rw-r--r--common/recipes-kernel/linux/files/0791-drm-amd-dal-opp-for-underlay.patch1822
1 files changed, 1822 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0791-drm-amd-dal-opp-for-underlay.patch b/common/recipes-kernel/linux/files/0791-drm-amd-dal-opp-for-underlay.patch
new file mode 100644
index 00000000..21736168
--- /dev/null
+++ b/common/recipes-kernel/linux/files/0791-drm-amd-dal-opp-for-underlay.patch
@@ -0,0 +1,1822 @@
+From 4330564057ab3f66dd1d72284d99f15208b5c474 Mon Sep 17 00:00:00 2001
+From: Yongqiang Sun <yongqiang.sun@amd.com>
+Date: Tue, 9 Feb 2016 16:47:42 -0500
+Subject: [PATCH 0791/1110] drm/amd/dal: opp for underlay.
+
+Signed-off-by: Yongqiang Sun <yongqiang.sun@amd.com>
+Acked-by: Harry Wentland <harry.wentland@amd.com>
+---
+ drivers/gpu/drm/amd/dal/dc/dce110/Makefile | 2 +-
+ drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c | 3 +-
+ .../gpu/drm/amd/dal/dc/dce110/dce110_opp_csc_v.c | 1050 ++++++++++++++++++++
+ .../drm/amd/dal/dc/dce110/dce110_opp_regamma_v.c | 520 ++++++++++
+ drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.c | 75 ++
+ drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.h | 55 +
+ .../gpu/drm/amd/dal/dc/dce110/dce110_resource.c | 2 +-
+ drivers/gpu/drm/amd/dal/dc/inc/opp.h | 15 +
+ 8 files changed, 1719 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc_v.c
+ create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma_v.c
+ create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.c
+ create mode 100644 drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.h
+
+diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/Makefile b/drivers/gpu/drm/amd/dal/dc/dce110/Makefile
+index 71aa9d8..deae715 100644
+--- a/drivers/gpu/drm/amd/dal/dc/dce110/Makefile
++++ b/drivers/gpu/drm/amd/dal/dc/dce110/Makefile
+@@ -9,7 +9,7 @@ dce110_timing_generator.o dce110_transform.o dce110_transform_v.o \
+ dce110_transform_gamut.o dce110_transform_scl.o dce110_opp_csc.o\
+ dce110_compressor.o dce110_mem_input.o dce110_hw_sequencer.o \
+ dce110_resource.o dce110_transform_bit_depth.o dce110_clock_source.o \
+-dce110_timing_generator_v.o
++dce110_opp_regamma_v.o dce110_opp_csc_v.o dce110_timing_generator_v.o
+
+ AMD_DAL_DCE110 = $(addprefix $(AMDDALPATH)/dc/dce110/,$(DCE110))
+
+diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c
+index 394f187..86bf8c0 100644
+--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c
++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp.c
+@@ -49,7 +49,8 @@ struct opp_funcs funcs = {
+ .opp_set_csc_adjustment = dce110_opp_set_csc_adjustment,
+ .opp_set_csc_default = dce110_opp_set_csc_default,
+ .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
+- .opp_set_regamma = dce110_opp_set_regamma
++ .opp_set_regamma = dce110_opp_set_regamma,
++ .opp_destroy = dce110_opp_destroy,
+ };
+
+ bool dce110_opp_construct(struct dce110_opp *opp110,
+diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc_v.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc_v.c
+new file mode 100644
+index 0000000..6ca749e
+--- /dev/null
++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_csc_v.c
+@@ -0,0 +1,1050 @@
++/*
++ * Copyright 2012-15 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 "dm_services.h"
++#include "dce110_opp.h"
++#include "basics/conversion.h"
++#include "video_csc_types.h"
++
++/* include DCE11 register header files */
++#include "dce/dce_11_0_d.h"
++#include "dce/dce_11_0_sh_mask.h"
++#include "dce/dce_11_0_enum.h"
++
++enum {
++ OUTPUT_CSC_MATRIX_SIZE = 12
++};
++
++/* constrast:0 - 2.0, default 1.0 */
++#define UNDERLAY_CONTRAST_DEFAULT 100
++#define UNDERLAY_CONTRAST_MAX 200
++#define UNDERLAY_CONTRAST_MIN 0
++#define UNDERLAY_CONTRAST_STEP 1
++#define UNDERLAY_CONTRAST_DIVIDER 100
++
++/* Saturation: 0 - 2.0; default 1.0 */
++#define UNDERLAY_SATURATION_DEFAULT 100 /*1.00*/
++#define UNDERLAY_SATURATION_MIN 0
++#define UNDERLAY_SATURATION_MAX 200 /* 2.00 */
++#define UNDERLAY_SATURATION_STEP 1 /* 0.01 */
++/*actual max overlay saturation
++ * value = UNDERLAY_SATURATION_MAX /UNDERLAY_SATURATION_DIVIDER
++ */
++
++/* Hue */
++#define UNDERLAY_HUE_DEFAULT 0
++#define UNDERLAY_HUE_MIN -300
++#define UNDERLAY_HUE_MAX 300
++#define UNDERLAY_HUE_STEP 5
++#define UNDERLAY_HUE_DIVIDER 10 /* HW range: -30 ~ +30 */
++#define UNDERLAY_SATURATION_DIVIDER 100
++
++/* Brightness: in DAL usually -.25 ~ .25.
++ * In MMD is -100 to +100 in 16-235 range; which when scaled to full range is
++ * ~-116 to +116. When normalized this is about 0.4566.
++ * With 100 divider this becomes 46, but we may use another for better precision
++ * The ideal one is 100/219 ((100/255)*(255/219)),
++ * i.e. min/max = +-100, divider = 219
++ * default 0.0
++ */
++#define UNDERLAY_BRIGHTNESS_DEFAULT 0
++#define UNDERLAY_BRIGHTNESS_MIN -46 /* ~116/255 */
++#define UNDERLAY_BRIGHTNESS_MAX 46
++#define UNDERLAY_BRIGHTNESS_STEP 1 /* .01 */
++#define UNDERLAY_BRIGHTNESS_DIVIDER 100
++
++struct out_csc_color_matrix {
++ enum color_space color_space;
++ uint16_t regval[OUTPUT_CSC_MATRIX_SIZE];
++};
++
++static const struct out_csc_color_matrix global_color_matrix[] = {
++{ COLOR_SPACE_SRGB_FULL_RANGE,
++ { 0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} },
++{ COLOR_SPACE_SRGB_LIMITED_RANGE,
++ { 0x1B60, 0, 0, 0x200, 0, 0x1B60, 0, 0x200, 0, 0, 0x1B60, 0x200} },
++{ COLOR_SPACE_YCBCR601,
++ { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x82F, 0x1012, 0x31F, 0x200, 0xFB47,
++ 0xF6B9, 0xE00, 0x1000} },
++{ COLOR_SPACE_YCBCR709, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x5D2, 0x1394, 0x1FA,
++ 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} },
++/* YOnly same as YCbCr709 but Y in Full range -To do. */
++{ COLOR_SPACE_YCBCR601_YONLY, { 0xE00, 0xF447, 0xFDB9, 0x1000, 0x991,
++ 0x12C9, 0x3A6, 0x200, 0xFB47, 0xF6B9, 0xE00, 0x1000} },
++{ COLOR_SPACE_YCBCR709_YONLY, { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3,
++ 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }
++};
++
++enum csc_color_mode {
++ /* 00 - BITS2:0 Bypass */
++ CSC_COLOR_MODE_GRAPHICS_BYPASS,
++ /* 01 - hard coded coefficient TV RGB */
++ CSC_COLOR_MODE_GRAPHICS_PREDEFINED,
++ /* 04 - programmable OUTPUT CSC coefficient */
++ CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC,
++};
++
++static void program_color_matrix_v(
++ struct dce110_opp *opp110,
++ const struct out_csc_color_matrix *tbl_entry,
++ enum grph_color_adjust_option options)
++{
++ struct dc_context *ctx = opp110->base.ctx;
++ uint32_t cntl_value = dm_read_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL);
++ bool use_set_a = (get_reg_field_value(cntl_value,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE) != 4);
++
++ set_reg_field_value(
++ cntl_value,
++ 0,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++
++ if (use_set_a) {
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C11_C12_A;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[0],
++ OUTPUT_CSC_C11_C12_A,
++ OUTPUT_CSC_C11_A);
++
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[1],
++ OUTPUT_CSC_C11_C12_A,
++ OUTPUT_CSC_C12_A);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C13_C14_A;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[2],
++ OUTPUT_CSC_C13_C14_A,
++ OUTPUT_CSC_C13_A);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[3],
++ OUTPUT_CSC_C13_C14_A,
++ OUTPUT_CSC_C14_A);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C21_C22_A;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[4],
++ OUTPUT_CSC_C21_C22_A,
++ OUTPUT_CSC_C21_A);
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[5],
++ OUTPUT_CSC_C21_C22_A,
++ OUTPUT_CSC_C22_A);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C23_C24_A;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[6],
++ OUTPUT_CSC_C23_C24_A,
++ OUTPUT_CSC_C23_A);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[7],
++ OUTPUT_CSC_C23_C24_A,
++ OUTPUT_CSC_C24_A);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C31_C32_A;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[8],
++ OUTPUT_CSC_C31_C32_A,
++ OUTPUT_CSC_C31_A);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[9],
++ OUTPUT_CSC_C31_C32_A,
++ OUTPUT_CSC_C32_A);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C33_C34_A;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[10],
++ OUTPUT_CSC_C33_C34_A,
++ OUTPUT_CSC_C33_A);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[11],
++ OUTPUT_CSC_C33_C34_A,
++ OUTPUT_CSC_C34_A);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ set_reg_field_value(
++ cntl_value,
++ 4,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ } else {
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C11_C12_B;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[0],
++ OUTPUT_CSC_C11_C12_B,
++ OUTPUT_CSC_C11_B);
++
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[1],
++ OUTPUT_CSC_C11_C12_B,
++ OUTPUT_CSC_C12_B);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C13_C14_B;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[2],
++ OUTPUT_CSC_C13_C14_B,
++ OUTPUT_CSC_C13_B);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[3],
++ OUTPUT_CSC_C13_C14_B,
++ OUTPUT_CSC_C14_B);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C21_C22_B;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[4],
++ OUTPUT_CSC_C21_C22_B,
++ OUTPUT_CSC_C21_B);
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[5],
++ OUTPUT_CSC_C21_C22_B,
++ OUTPUT_CSC_C22_B);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C23_C24_B;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[6],
++ OUTPUT_CSC_C23_C24_B,
++ OUTPUT_CSC_C23_B);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[7],
++ OUTPUT_CSC_C23_C24_B,
++ OUTPUT_CSC_C24_B);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C31_C32_B;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[8],
++ OUTPUT_CSC_C31_C32_B,
++ OUTPUT_CSC_C31_B);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[9],
++ OUTPUT_CSC_C31_C32_B,
++ OUTPUT_CSC_C32_B);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ {
++ uint32_t value = 0;
++ uint32_t addr = mmOUTPUT_CSC_C33_C34_B;
++ /* fixed S2.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[10],
++ OUTPUT_CSC_C33_C34_B,
++ OUTPUT_CSC_C33_B);
++ /* fixed S0.13 format */
++ set_reg_field_value(
++ value,
++ tbl_entry->regval[11],
++ OUTPUT_CSC_C33_C34_B,
++ OUTPUT_CSC_C34_B);
++
++ dm_write_reg(ctx, addr, value);
++ }
++ set_reg_field_value(
++ cntl_value,
++ 5,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ }
++
++ dm_write_reg(ctx, mmCOL_MAN_OUTPUT_CSC_CONTROL, cntl_value);
++}
++
++/*
++ * initialize_color_float_adj_reference_values
++ * This initialize display color adjust input from API to HW range for later
++ * calculation use. This is shared by all the display color adjustment.
++ * @param :
++ * @return None
++ */
++static void initialize_color_float_adj_reference_values(
++ const struct grph_csc_adjustment *adjust,
++ struct fixed31_32 *grph_cont,
++ struct fixed31_32 *grph_sat,
++ struct fixed31_32 *grph_bright,
++ struct fixed31_32 *sin_grph_hue,
++ struct fixed31_32 *cos_grph_hue)
++{
++ /* Hue adjustment could be negative. -45 ~ +45 */
++ struct fixed31_32 hue =
++ dal_fixed31_32_mul(
++ dal_fixed31_32_from_fraction(adjust->grph_hue, 180),
++ dal_fixed31_32_pi);
++
++ *sin_grph_hue = dal_fixed31_32_sin(hue);
++ *cos_grph_hue = dal_fixed31_32_cos(hue);
++
++ if (adjust->adjust_divider) {
++ *grph_cont =
++ dal_fixed31_32_from_fraction(
++ adjust->grph_cont,
++ adjust->adjust_divider);
++ *grph_sat =
++ dal_fixed31_32_from_fraction(
++ adjust->grph_sat,
++ adjust->adjust_divider);
++ *grph_bright =
++ dal_fixed31_32_from_fraction(
++ adjust->grph_bright,
++ adjust->adjust_divider);
++ } else {
++ *grph_cont = dal_fixed31_32_from_int(adjust->grph_cont);
++ *grph_sat = dal_fixed31_32_from_int(adjust->grph_sat);
++ *grph_bright = dal_fixed31_32_from_int(adjust->grph_bright);
++ }
++}
++
++static inline struct fixed31_32 fixed31_32_clamp(
++ struct fixed31_32 value,
++ int32_t min_numerator,
++ int32_t max_numerator,
++ int32_t denominator)
++{
++ return dal_fixed31_32_clamp(
++ value,
++ dal_fixed31_32_from_fraction(
++ min_numerator,
++ denominator),
++ dal_fixed31_32_from_fraction(
++ max_numerator,
++ denominator));
++}
++
++static void setup_reg_format(
++ struct fixed31_32 *coefficients,
++ uint16_t *reg_values)
++{
++ enum {
++ LENGTH = 12,
++ DENOMINATOR = 10000
++ };
++
++ static const int32_t min_numerator[] = {
++ -3 * DENOMINATOR,
++ -DENOMINATOR
++ };
++
++ static const int32_t max_numerator[] = {
++ DENOMINATOR,
++ DENOMINATOR
++ };
++
++ static const uint8_t integer_bits[] = { 2, 0 };
++
++ uint32_t i = 0;
++
++ do {
++ const uint32_t index = (i % 4) == 3;
++
++ reg_values[i] = fixed_point_to_int_frac(
++ fixed31_32_clamp(coefficients[(i + 8) % LENGTH],
++ min_numerator[index],
++ max_numerator[index],
++ DENOMINATOR),
++ integer_bits[index], 13);
++
++ ++i;
++ } while (i != LENGTH);
++}
++
++/**
++ *****************************************************************************
++ * Function: setup_adjustments
++ * @note prepare to setup the values
++ *
++ * @see
++ *
++ *****************************************************************************
++ */
++static void setup_adjustments(const struct grph_csc_adjustment *adjust,
++ struct dc_csc_adjustments *adjustments)
++{
++ if (adjust->adjust_divider != 0) {
++ adjustments->brightness =
++ dal_fixed31_32_from_fraction(adjust->grph_bright,
++ adjust->adjust_divider);
++ adjustments->contrast =
++ dal_fixed31_32_from_fraction(adjust->grph_cont,
++ adjust->adjust_divider);
++ adjustments->saturation =
++ dal_fixed31_32_from_fraction(adjust->grph_sat,
++ adjust->adjust_divider);
++ } else {
++ adjustments->brightness =
++ dal_fixed31_32_from_fraction(adjust->grph_bright, 1);
++ adjustments->contrast =
++ dal_fixed31_32_from_fraction(adjust->grph_cont, 1);
++ adjustments->saturation =
++ dal_fixed31_32_from_fraction(adjust->grph_sat, 1);
++ }
++
++ /* convert degrees into radians */
++ adjustments->hue =
++ dal_fixed31_32_mul(
++ dal_fixed31_32_from_fraction(adjust->grph_hue, 180),
++ dal_fixed31_32_pi);
++}
++
++/**
++ *****************************************************************************
++ * Function: dal_transform_wide_gamut_set_rgb_adjustment_legacy
++ *
++ * @param [in] const struct grph_csc_adjustment *adjust
++ *
++ * @return
++ * void
++ *
++ * @note calculate and program color adjustments for sRGB color space
++ *
++ * @see
++ *
++ *****************************************************************************
++ */
++static void set_rgb_adjustment_legacy(
++ struct dce110_opp *opp110,
++ const struct grph_csc_adjustment *adjust)
++{
++ const struct fixed31_32 k1 =
++ dal_fixed31_32_from_fraction(701000, 1000000);
++ const struct fixed31_32 k2 =
++ dal_fixed31_32_from_fraction(236568, 1000000);
++ const struct fixed31_32 k3 =
++ dal_fixed31_32_from_fraction(-587000, 1000000);
++ const struct fixed31_32 k4 =
++ dal_fixed31_32_from_fraction(464432, 1000000);
++ const struct fixed31_32 k5 =
++ dal_fixed31_32_from_fraction(-114000, 1000000);
++ const struct fixed31_32 k6 =
++ dal_fixed31_32_from_fraction(-701000, 1000000);
++ const struct fixed31_32 k7 =
++ dal_fixed31_32_from_fraction(-299000, 1000000);
++ const struct fixed31_32 k8 =
++ dal_fixed31_32_from_fraction(-292569, 1000000);
++ const struct fixed31_32 k9 =
++ dal_fixed31_32_from_fraction(413000, 1000000);
++ const struct fixed31_32 k10 =
++ dal_fixed31_32_from_fraction(-92482, 1000000);
++ const struct fixed31_32 k11 =
++ dal_fixed31_32_from_fraction(-114000, 1000000);
++ const struct fixed31_32 k12 =
++ dal_fixed31_32_from_fraction(385051, 1000000);
++ const struct fixed31_32 k13 =
++ dal_fixed31_32_from_fraction(-299000, 1000000);
++ const struct fixed31_32 k14 =
++ dal_fixed31_32_from_fraction(886000, 1000000);
++ const struct fixed31_32 k15 =
++ dal_fixed31_32_from_fraction(-587000, 1000000);
++ const struct fixed31_32 k16 =
++ dal_fixed31_32_from_fraction(-741914, 1000000);
++ const struct fixed31_32 k17 =
++ dal_fixed31_32_from_fraction(886000, 1000000);
++ const struct fixed31_32 k18 =
++ dal_fixed31_32_from_fraction(-144086, 1000000);
++
++ const struct fixed31_32 luma_r =
++ dal_fixed31_32_from_fraction(299, 1000);
++ const struct fixed31_32 luma_g =
++ dal_fixed31_32_from_fraction(587, 1000);
++ const struct fixed31_32 luma_b =
++ dal_fixed31_32_from_fraction(114, 1000);
++
++ struct out_csc_color_matrix tbl_entry;
++ struct fixed31_32 matrix[OUTPUT_CSC_MATRIX_SIZE];
++
++ struct fixed31_32 grph_cont;
++ struct fixed31_32 grph_sat;
++ struct fixed31_32 grph_bright;
++ struct fixed31_32 sin_grph_hue;
++ struct fixed31_32 cos_grph_hue;
++
++ initialize_color_float_adj_reference_values(
++ adjust, &grph_cont, &grph_sat,
++ &grph_bright, &sin_grph_hue, &cos_grph_hue);
++
++ /* COEF_1_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 +
++ * Sin(GrphHue) * K2))
++ * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)
++ */
++ matrix[0] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k1),
++ dal_fixed31_32_mul(sin_grph_hue, k2));
++ /* GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2 */
++ matrix[0] = dal_fixed31_32_mul(grph_sat, matrix[0]);
++ /* (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) * K2)) */
++ matrix[0] = dal_fixed31_32_add(luma_r, matrix[0]);
++ /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K1 + Sin(GrphHue) *
++ * K2))
++ */
++ matrix[0] = dal_fixed31_32_mul(grph_cont, matrix[0]);
++
++ /* COEF_1_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 +
++ * Sin(GrphHue) * K4))
++ * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)
++ */
++ matrix[1] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k3),
++ dal_fixed31_32_mul(sin_grph_hue, k4));
++ /* GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4) */
++ matrix[1] = dal_fixed31_32_mul(grph_sat, matrix[1]);
++ /* (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) * K4)) */
++ matrix[1] = dal_fixed31_32_add(luma_g, matrix[1]);
++ /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K3 + Sin(GrphHue) *
++ * K4))
++ */
++ matrix[1] = dal_fixed31_32_mul(grph_cont, matrix[1]);
++
++ /* COEF_1_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 +
++ * Sin(GrphHue) * K6))
++ * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6)
++ */
++ matrix[2] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k5),
++ dal_fixed31_32_mul(sin_grph_hue, k6));
++ /* GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
++ matrix[2] = dal_fixed31_32_mul(grph_sat, matrix[2]);
++ /* LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) * K6) */
++ matrix[2] = dal_fixed31_32_add(luma_b, matrix[2]);
++ /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K5 + Sin(GrphHue) *
++ * K6))
++ */
++ matrix[2] = dal_fixed31_32_mul(grph_cont, matrix[2]);
++
++ /* COEF_1_4 = GrphBright */
++ matrix[3] = grph_bright;
++
++ /* COEF_2_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 +
++ * Sin(GrphHue) * K8))
++ * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)
++ */
++ matrix[4] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k7),
++ dal_fixed31_32_mul(sin_grph_hue, k8));
++ /* GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8) */
++ matrix[4] = dal_fixed31_32_mul(grph_sat, matrix[4]);
++ /* (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) * K8)) */
++ matrix[4] = dal_fixed31_32_add(luma_r, matrix[4]);
++ /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K7 + Sin(GrphHue) *
++ * K8))
++ */
++ matrix[4] = dal_fixed31_32_mul(grph_cont, matrix[4]);
++
++ /* COEF_2_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 +
++ * Sin(GrphHue) * K10))
++ * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10))
++ */
++ matrix[5] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k9),
++ dal_fixed31_32_mul(sin_grph_hue, k10));
++ /* GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
++ matrix[5] = dal_fixed31_32_mul(grph_sat, matrix[5]);
++ /* (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) * K10)) */
++ matrix[5] = dal_fixed31_32_add(luma_g, matrix[5]);
++ /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K9 + Sin(GrphHue) *
++ * K10))
++ */
++ matrix[5] = dal_fixed31_32_mul(grph_cont, matrix[5]);
++
++ /* COEF_2_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 +
++ * Sin(GrphHue) * K12))
++ * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12))
++ */
++ matrix[6] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k11),
++ dal_fixed31_32_mul(sin_grph_hue, k12));
++ /* GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
++ matrix[6] = dal_fixed31_32_mul(grph_sat, matrix[6]);
++ /* (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) * K12)) */
++ matrix[6] = dal_fixed31_32_add(luma_b, matrix[6]);
++ /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K11 + Sin(GrphHue) *
++ * K12))
++ */
++ matrix[6] = dal_fixed31_32_mul(grph_cont, matrix[6]);
++
++ /* COEF_2_4 = GrphBright */
++ matrix[7] = grph_bright;
++
++ /* COEF_3_1 = GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 +
++ * Sin(GrphHue) * K14))
++ * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14))
++ */
++ matrix[8] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k13),
++ dal_fixed31_32_mul(sin_grph_hue, k14));
++ /* GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
++ matrix[8] = dal_fixed31_32_mul(grph_sat, matrix[8]);
++ /* (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) * K14)) */
++ matrix[8] = dal_fixed31_32_add(luma_r, matrix[8]);
++ /* GrphCont * (LumaR + GrphSat * (Cos(GrphHue) * K13 + Sin(GrphHue) *
++ * K14))
++ */
++ matrix[8] = dal_fixed31_32_mul(grph_cont, matrix[8]);
++
++ /* COEF_3_2 = GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 +
++ * Sin(GrphHue) * K16))
++ * GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)
++ */
++ matrix[9] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k15),
++ dal_fixed31_32_mul(sin_grph_hue, k16));
++ /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
++ matrix[9] = dal_fixed31_32_mul(grph_sat, matrix[9]);
++ /* (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) * K16)) */
++ matrix[9] = dal_fixed31_32_add(luma_g, matrix[9]);
++ /* GrphCont * (LumaG + GrphSat * (Cos(GrphHue) * K15 + Sin(GrphHue) *
++ * K16))
++ */
++ matrix[9] = dal_fixed31_32_mul(grph_cont, matrix[9]);
++
++ /* COEF_3_3 = GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 +
++ * Sin(GrphHue) * K18))
++ * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18))
++ */
++ matrix[10] =
++ dal_fixed31_32_add(
++ dal_fixed31_32_mul(cos_grph_hue, k17),
++ dal_fixed31_32_mul(sin_grph_hue, k18));
++ /* GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
++ matrix[10] = dal_fixed31_32_mul(grph_sat, matrix[10]);
++ /* (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) * K18)) */
++ matrix[10] = dal_fixed31_32_add(luma_b, matrix[10]);
++ /* GrphCont * (LumaB + GrphSat * (Cos(GrphHue) * K17 + Sin(GrphHue) *
++ * K18))
++ */
++ matrix[10] = dal_fixed31_32_mul(grph_cont, matrix[10]);
++
++ /* COEF_3_4 = GrphBright */
++ matrix[11] = grph_bright;
++
++ tbl_entry.color_space = adjust->c_space;
++
++ convert_float_matrix(tbl_entry.regval, matrix, OUTPUT_CSC_MATRIX_SIZE);
++
++ program_color_matrix_v(
++ opp110, &tbl_entry, adjust->color_adjust_option);
++}
++
++static void prepare_yuv_ideal(
++ bool b601,
++ struct fixed31_32 *matrix)
++{
++ static const int32_t matrix_1[] = {
++ 25578516, 50216016, 9752344, 6250000,
++ -14764391, -28985609, 43750000, 50000000,
++ 43750000, -36635164, -7114836, 50000000
++ };
++
++ static const int32_t matrix_2[] = {
++ 18187266, 61183125, 6176484, 6250000,
++ -10025059, -33724941, 43750000, 50000000,
++ 43750000, -39738379, -4011621, 50000000
++ };
++
++ const int32_t *matrix_x = b601 ? matrix_1 : matrix_2;
++
++ uint32_t i = 0;
++
++ do {
++ matrix[i] = dal_fixed31_32_from_fraction(
++ matrix_x[i],
++ 100000000);
++ ++i;
++ } while (i != ARRAY_SIZE(matrix_1));
++}
++
++/**
++ *****************************************************************************
++ * Function: dal_transform_wide_gamut_set_yuv_adjustment
++ *
++ * @param [in] const struct grph_csc_adjustment *adjust
++ *
++ * @return
++ * void
++ *
++ * @note calculate and program color adjustments for YUV color spaces
++ *
++ * @see
++ *
++ *****************************************************************************
++ */
++static void set_yuv_adjustment(
++ struct dce110_opp *opp110,
++ const struct grph_csc_adjustment *adjust)
++{
++ bool b601 = (adjust->c_space == COLOR_SPACE_YPBPR601) ||
++ (adjust->c_space == COLOR_SPACE_YCBCR601) ||
++ (adjust->c_space == COLOR_SPACE_YCBCR601_YONLY);
++ struct out_csc_color_matrix reg_matrix;
++ struct fixed31_32 matrix[OUTPUT_CSC_MATRIX_SIZE];
++ struct dc_csc_adjustments adjustments;
++ struct fixed31_32 ideals[OUTPUT_CSC_MATRIX_SIZE];
++
++ prepare_yuv_ideal(b601, ideals);
++
++ setup_adjustments(adjust, &adjustments);
++
++ if ((adjust->c_space == COLOR_SPACE_YCBCR601_YONLY) ||
++ (adjust->c_space == COLOR_SPACE_YCBCR709_YONLY))
++ calculate_adjustments_y_only(
++ ideals, &adjustments, matrix);
++ else
++ calculate_adjustments(
++ ideals, &adjustments, matrix);
++
++ dm_memset(&reg_matrix, 0, sizeof(struct out_csc_color_matrix));
++
++ setup_reg_format(matrix, reg_matrix.regval);
++
++ program_color_matrix_v(opp110, &reg_matrix, GRPH_COLOR_MATRIX_SW);
++}
++
++static bool configure_graphics_mode_v(
++ struct dce110_opp *opp110,
++ enum csc_color_mode config,
++ enum graphics_csc_adjust_type csc_adjust_type,
++ enum color_space color_space)
++{
++ struct dc_context *ctx = opp110->base.ctx;
++ uint32_t addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
++ uint32_t value = dm_read_reg(ctx, addr);
++
++ set_reg_field_value(
++ value,
++ 0,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++
++ if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_SW) {
++ if (config == CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC)
++ return true;
++
++ switch (color_space) {
++ case COLOR_SPACE_SRGB_FULL_RANGE:
++ /* by pass */
++ set_reg_field_value(
++ value,
++ 0,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ break;
++ case COLOR_SPACE_SRGB_LIMITED_RANGE:
++ /* not supported for underlay on CZ */
++ return false;
++
++ case COLOR_SPACE_YCBCR601:
++ case COLOR_SPACE_YPBPR601:
++ case COLOR_SPACE_YCBCR601_YONLY:
++ /* YCbCr601 */
++ set_reg_field_value(
++ value,
++ 2,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ break;
++ case COLOR_SPACE_YCBCR709:
++ case COLOR_SPACE_YPBPR709:
++ case COLOR_SPACE_YCBCR709_YONLY:
++ /* YCbCr709 */
++ set_reg_field_value(
++ value,
++ 3,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ break;
++ default:
++ return false;
++ }
++
++ } else if (csc_adjust_type == GRAPHICS_CSC_ADJUST_TYPE_HW) {
++ switch (color_space) {
++ case COLOR_SPACE_SRGB_FULL_RANGE:
++ /* by pass */
++ set_reg_field_value(
++ value,
++ 0,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ break;
++ case COLOR_SPACE_SRGB_LIMITED_RANGE:
++ /* not supported for underlay on CZ */
++ return false;
++ case COLOR_SPACE_YCBCR601:
++ case COLOR_SPACE_YPBPR601:
++ case COLOR_SPACE_YCBCR601_YONLY:
++ /* YCbCr601 */
++ set_reg_field_value(
++ value,
++ 2,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ break;
++ case COLOR_SPACE_YCBCR709:
++ case COLOR_SPACE_YPBPR709:
++ case COLOR_SPACE_YCBCR709_YONLY:
++ /* YCbCr709 */
++ set_reg_field_value(
++ value,
++ 3,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++ break;
++ default:
++ return false;
++ }
++
++ } else
++ /* by pass */
++ set_reg_field_value(
++ value,
++ 0,
++ COL_MAN_OUTPUT_CSC_CONTROL,
++ OUTPUT_CSC_MODE);
++
++ addr = mmCOL_MAN_OUTPUT_CSC_CONTROL;
++ dm_write_reg(ctx, addr, value);
++
++ return true;
++}
++
++static void set_Denormalization(struct output_pixel_processor *opp,
++ enum dc_color_depth color_depth)
++{
++ uint32_t value = dm_read_reg(opp->ctx, mmDENORM_CLAMP_CONTROL);
++
++ switch (color_depth) {
++ case COLOR_DEPTH_888:
++ /* 255/256 for 8 bit output color depth */
++ set_reg_field_value(
++ value,
++ 1,
++ DENORM_CLAMP_CONTROL,
++ DENORM_MODE);
++ break;
++ case COLOR_DEPTH_101010:
++ /* 1023/1024 for 10 bit output color depth */
++ set_reg_field_value(
++ value,
++ 2,
++ DENORM_CLAMP_CONTROL,
++ DENORM_MODE);
++ break;
++ case COLOR_DEPTH_121212:
++ /* 4095/4096 for 12 bit output color depth */
++ set_reg_field_value(
++ value,
++ 3,
++ DENORM_CLAMP_CONTROL,
++ DENORM_MODE);
++ break;
++ default:
++ /* not valid case */
++ break;
++ }
++
++ set_reg_field_value(
++ value,
++ 1,
++ DENORM_CLAMP_CONTROL,
++ DENORM_10BIT_OUT);
++
++ dm_write_reg(opp->ctx, mmDENORM_CLAMP_CONTROL, value);
++}
++
++
++void dce110_opp_v_set_csc_default(
++ struct output_pixel_processor *opp,
++ const struct default_adjustment *default_adjust)
++{
++ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
++ enum csc_color_mode config =
++ CSC_COLOR_MODE_GRAPHICS_PREDEFINED;
++
++ if (default_adjust->force_hw_default == false) {
++ const struct out_csc_color_matrix *elm;
++ /* currently parameter not in use */
++ enum grph_color_adjust_option option =
++ GRPH_COLOR_MATRIX_HW_DEFAULT;
++ uint32_t i;
++ /*
++ * HW default false we program locally defined matrix
++ * HW default true we use predefined hw matrix and we
++ * do not need to program matrix
++ * OEM wants the HW default via runtime parameter.
++ */
++ option = GRPH_COLOR_MATRIX_SW;
++
++ for (i = 0; i < ARRAY_SIZE(global_color_matrix); ++i) {
++ elm = &global_color_matrix[i];
++ if (elm->color_space != default_adjust->color_space)
++ continue;
++ /* program the matrix with default values from this
++ * file
++ */
++ program_color_matrix_v(opp110, elm, option);
++ config = CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
++ break;
++ }
++ }
++
++ /* configure the what we programmed :
++ * 1. Default values from this file
++ * 2. Use hardware default from ROM_A and we do not need to program
++ * matrix
++ */
++
++ configure_graphics_mode_v(opp110, config,
++ default_adjust->csc_adjust_type,
++ default_adjust->color_space);
++
++ set_Denormalization(opp, default_adjust->color_depth);
++}
++
++void dce110_opp_v_set_csc_adjustment(
++ struct output_pixel_processor *opp,
++ const struct grph_csc_adjustment *adjust)
++{
++ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
++ enum csc_color_mode config =
++ CSC_COLOR_MODE_GRAPHICS_OUTPUT_CSC;
++
++ /* Apply color adjustments: brightness, saturation, hue, contrast and
++ * CSC. No need for different color space routine, color space defines
++ * the ideal values only, but keep original design to allow quick switch
++ * to the old legacy routines
++ */
++ switch (adjust->c_space) {
++ case COLOR_SPACE_SRGB_FULL_RANGE:
++ set_rgb_adjustment_legacy(opp110, adjust);
++ break;
++ case COLOR_SPACE_YCBCR601:
++ case COLOR_SPACE_YCBCR709:
++ case COLOR_SPACE_YCBCR601_YONLY:
++ case COLOR_SPACE_YCBCR709_YONLY:
++ case COLOR_SPACE_YPBPR601:
++ case COLOR_SPACE_YPBPR709:
++ set_yuv_adjustment(opp110, adjust);
++ break;
++ default:
++ set_rgb_adjustment_legacy(opp110, adjust);
++ break;
++ }
++
++ /* We did everything ,now program DxOUTPUT_CSC_CONTROL */
++ configure_graphics_mode_v(opp110, config, adjust->csc_adjust_type,
++ adjust->c_space);
++
++ set_Denormalization(opp, adjust->color_depth);
++}
+diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma_v.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma_v.c
+new file mode 100644
+index 0000000..4f6cc9c
+--- /dev/null
++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_regamma_v.c
+@@ -0,0 +1,520 @@
++/*
++ * Copyright 2012-15 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 "dm_services.h"
++
++/* include DCE11 register header files */
++#include "dce/dce_11_0_d.h"
++#include "dce/dce_11_0_sh_mask.h"
++
++#include "dce110_opp.h"
++#include "gamma_types.h"
++
++static void power_on_lut(struct output_pixel_processor *opp,
++ bool power_on, bool inputgamma, bool regamma)
++{
++ uint32_t value = dm_read_reg(opp->ctx, mmDCFEV_MEM_PWR_CTRL);
++ int i;
++
++ if (power_on) {
++ if (inputgamma)
++ set_reg_field_value(
++ value,
++ 1,
++ DCFEV_MEM_PWR_CTRL,
++ COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
++ if (regamma)
++ set_reg_field_value(
++ value,
++ 1,
++ DCFEV_MEM_PWR_CTRL,
++ COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
++ } else {
++ if (inputgamma)
++ set_reg_field_value(
++ value,
++ 0,
++ DCFEV_MEM_PWR_CTRL,
++ COL_MAN_INPUT_GAMMA_MEM_PWR_DIS);
++ if (regamma)
++ set_reg_field_value(
++ value,
++ 0,
++ DCFEV_MEM_PWR_CTRL,
++ COL_MAN_GAMMA_CORR_MEM_PWR_DIS);
++ }
++
++ dm_write_reg(opp->ctx, mmDCFEV_MEM_PWR_CTRL, value);
++
++ for (i = 0; i < 3; i++) {
++ value = dm_read_reg(opp->ctx, mmDCFEV_MEM_PWR_CTRL);
++ if (get_reg_field_value(value,
++ DCFEV_MEM_PWR_CTRL,
++ COL_MAN_INPUT_GAMMA_MEM_PWR_DIS) &&
++ get_reg_field_value(value,
++ DCFEV_MEM_PWR_CTRL,
++ COL_MAN_GAMMA_CORR_MEM_PWR_DIS))
++ break;
++
++ dm_delay_in_microseconds(opp->ctx, 2);
++ }
++}
++
++static void set_bypass_input_gamma(struct dce110_opp *opp110)
++{
++ uint32_t value;
++
++ value = dm_read_reg(opp110->base.ctx,
++ mmCOL_MAN_INPUT_GAMMA_CONTROL1);
++
++ set_reg_field_value(
++ value,
++ 0,
++ COL_MAN_INPUT_GAMMA_CONTROL1,
++ INPUT_GAMMA_MODE);
++
++ dm_write_reg(opp110->base.ctx,
++ mmCOL_MAN_INPUT_GAMMA_CONTROL1, value);
++}
++
++static void configure_regamma_mode(struct dce110_opp *opp110, uint32_t mode)
++{
++ uint32_t value = 0;
++
++ set_reg_field_value(
++ value,
++ mode,
++ GAMMA_CORR_CONTROL,
++ GAMMA_CORR_MODE);
++
++ dm_write_reg(opp110->base.ctx, mmGAMMA_CORR_CONTROL, 0);
++}
++
++/*
++ *****************************************************************************
++ * Function: regamma_config_regions_and_segments
++ *
++ * build regamma curve by using predefined hw points
++ * uses interface parameters ,like EDID coeff.
++ *
++ * @param : parameters interface parameters
++ * @return void
++ *
++ * @note
++ *
++ * @see
++ *
++ *****************************************************************************
++ */
++static void regamma_config_regions_and_segments(
++ struct dce110_opp *opp110, const struct regamma_params *params)
++{
++ const struct gamma_curve *curve;
++ uint32_t value = 0;
++
++ {
++ set_reg_field_value(
++ value,
++ params->arr_points[0].custom_float_x,
++ GAMMA_CORR_CNTLA_START_CNTL,
++ GAMMA_CORR_CNTLA_EXP_REGION_START);
++
++ set_reg_field_value(
++ value,
++ 0,
++ GAMMA_CORR_CNTLA_START_CNTL,
++ GAMMA_CORR_CNTLA_EXP_REGION_START_SEGMENT);
++
++ dm_write_reg(opp110->base.ctx, mmGAMMA_CORR_CNTLA_START_CNTL,
++ value);
++ }
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ params->arr_points[0].custom_float_slope,
++ GAMMA_CORR_CNTLA_SLOPE_CNTL,
++ GAMMA_CORR_CNTLA_EXP_REGION_LINEAR_SLOPE);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_SLOPE_CNTL, value);
++ }
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ params->arr_points[1].custom_float_x,
++ GAMMA_CORR_CNTLA_END_CNTL1,
++ GAMMA_CORR_CNTLA_EXP_REGION_END);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_END_CNTL1, value);
++ }
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ params->arr_points[2].custom_float_slope,
++ GAMMA_CORR_CNTLA_END_CNTL2,
++ GAMMA_CORR_CNTLA_EXP_REGION_END_BASE);
++
++ set_reg_field_value(
++ value,
++ params->arr_points[1].custom_float_y,
++ GAMMA_CORR_CNTLA_END_CNTL2,
++ GAMMA_CORR_CNTLA_EXP_REGION_END_SLOPE);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_END_CNTL2, value);
++ }
++
++ curve = params->arr_curve_points;
++
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_0_1,
++ GAMMA_CORR_CNTLA_EXP_REGION0_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_0_1,
++ GAMMA_CORR_CNTLA_EXP_REGION0_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_0_1,
++ GAMMA_CORR_CNTLA_EXP_REGION1_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_0_1,
++ GAMMA_CORR_CNTLA_EXP_REGION1_NUM_SEGMENTS);
++
++ dm_write_reg(
++ opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_0_1,
++ value);
++ }
++
++ curve += 2;
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_2_3,
++ GAMMA_CORR_CNTLA_EXP_REGION2_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_2_3,
++ GAMMA_CORR_CNTLA_EXP_REGION2_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_2_3,
++ GAMMA_CORR_CNTLA_EXP_REGION3_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_2_3,
++ GAMMA_CORR_CNTLA_EXP_REGION3_NUM_SEGMENTS);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_2_3,
++ value);
++ }
++
++ curve += 2;
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_4_5,
++ GAMMA_CORR_CNTLA_EXP_REGION4_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_4_5,
++ GAMMA_CORR_CNTLA_EXP_REGION4_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_4_5,
++ GAMMA_CORR_CNTLA_EXP_REGION5_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_4_5,
++ GAMMA_CORR_CNTLA_EXP_REGION5_NUM_SEGMENTS);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_4_5,
++ value);
++ }
++
++ curve += 2;
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_6_7,
++ GAMMA_CORR_CNTLA_EXP_REGION6_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_6_7,
++ GAMMA_CORR_CNTLA_EXP_REGION6_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_6_7,
++ GAMMA_CORR_CNTLA_EXP_REGION7_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_6_7,
++ GAMMA_CORR_CNTLA_EXP_REGION7_NUM_SEGMENTS);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_6_7,
++ value);
++ }
++
++ curve += 2;
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_8_9,
++ GAMMA_CORR_CNTLA_EXP_REGION8_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_8_9,
++ GAMMA_CORR_CNTLA_EXP_REGION8_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_8_9,
++ GAMMA_CORR_CNTLA_EXP_REGION9_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_8_9,
++ GAMMA_CORR_CNTLA_EXP_REGION9_NUM_SEGMENTS);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_8_9,
++ value);
++ }
++
++ curve += 2;
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_10_11,
++ GAMMA_CORR_CNTLA_EXP_REGION10_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_10_11,
++ GAMMA_CORR_CNTLA_EXP_REGION10_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_10_11,
++ GAMMA_CORR_CNTLA_EXP_REGION11_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_10_11,
++ GAMMA_CORR_CNTLA_EXP_REGION11_NUM_SEGMENTS);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_10_11,
++ value);
++ }
++
++ curve += 2;
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_12_13,
++ GAMMA_CORR_CNTLA_EXP_REGION12_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_12_13,
++ GAMMA_CORR_CNTLA_EXP_REGION12_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_12_13,
++ GAMMA_CORR_CNTLA_EXP_REGION13_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_12_13,
++ GAMMA_CORR_CNTLA_EXP_REGION13_NUM_SEGMENTS);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_12_13,
++ value);
++ }
++
++ curve += 2;
++ {
++ value = 0;
++ set_reg_field_value(
++ value,
++ curve[0].offset,
++ GAMMA_CORR_CNTLA_REGION_14_15,
++ GAMMA_CORR_CNTLA_EXP_REGION14_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[0].segments_num,
++ GAMMA_CORR_CNTLA_REGION_14_15,
++ GAMMA_CORR_CNTLA_EXP_REGION14_NUM_SEGMENTS);
++
++ set_reg_field_value(
++ value,
++ curve[1].offset,
++ GAMMA_CORR_CNTLA_REGION_14_15,
++ GAMMA_CORR_CNTLA_EXP_REGION15_LUT_OFFSET);
++
++ set_reg_field_value(
++ value,
++ curve[1].segments_num,
++ GAMMA_CORR_CNTLA_REGION_14_15,
++ GAMMA_CORR_CNTLA_EXP_REGION15_NUM_SEGMENTS);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_CNTLA_REGION_14_15,
++ value);
++ }
++}
++
++static void program_pwl(struct dce110_opp *opp110,
++ const struct regamma_params *params)
++{
++ uint32_t value = 0;
++
++ set_reg_field_value(
++ value,
++ 7,
++ GAMMA_CORR_LUT_WRITE_EN_MASK,
++ GAMMA_CORR_LUT_WRITE_EN_MASK);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_LUT_WRITE_EN_MASK, value);
++
++ dm_write_reg(opp110->base.ctx,
++ mmGAMMA_CORR_LUT_INDEX, 0);
++
++ /* Program REGAMMA_LUT_DATA */
++ {
++ const uint32_t addr = mmGAMMA_CORR_LUT_DATA;
++ uint32_t i = 0;
++ const struct pwl_result_data *rgb =
++ params->rgb_resulted;
++
++ while (i != params->hw_points_num) {
++ dm_write_reg(opp110->base.ctx, addr, rgb->red_reg);
++ dm_write_reg(opp110->base.ctx, addr, rgb->green_reg);
++ dm_write_reg(opp110->base.ctx, addr, rgb->blue_reg);
++
++ dm_write_reg(opp110->base.ctx, addr,
++ rgb->delta_red_reg);
++ dm_write_reg(opp110->base.ctx, addr,
++ rgb->delta_green_reg);
++ dm_write_reg(opp110->base.ctx, addr,
++ rgb->delta_blue_reg);
++
++ ++rgb;
++ ++i;
++ }
++ }
++}
++
++bool dce110_opp_set_regamma_v(
++ struct output_pixel_processor *opp,
++ const struct regamma_params *params)
++{
++ struct dce110_opp *opp110 = TO_DCE110_OPP(opp);
++
++ /* Setup regions */
++ regamma_config_regions_and_segments(opp110, params);
++
++ set_bypass_input_gamma(opp110);
++
++ /* Power on gamma LUT memory */
++ power_on_lut(opp, true, false, true);
++
++ /* Program PWL */
++ program_pwl(opp110, params);
++
++ /* program regamma config */
++ configure_regamma_mode(opp110, 1);
++
++ /* Power return to auto back */
++ power_on_lut(opp, false, false, true);
++
++ return true;
++}
++
++
+diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.c
+new file mode 100644
+index 0000000..9764940
+--- /dev/null
++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.c
+@@ -0,0 +1,75 @@
++/*
++ * Copyright 2012-15 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 "dm_services.h"
++
++/* include DCE11 register header files */
++#include "dce/dce_11_0_d.h"
++#include "dce/dce_11_0_sh_mask.h"
++
++#include "dce110_opp.h"
++#include "dce110_opp_v.h"
++
++#include "gamma_types.h"
++
++/*****************************************/
++/* Constructor, Destructor */
++/*****************************************/
++
++struct opp_funcs funcs = {
++ .opp_set_regamma = dce110_opp_set_regamma_v,
++
++ .opp_set_csc_default = dce110_opp_v_set_csc_default,
++
++ .opp_set_csc_adjustment = dce110_opp_v_set_csc_adjustment,
++
++ .opp_program_bit_depth_reduction =
++ dce110_opp_program_bit_depth_reduction,
++ .opp_program_clamping_and_pixel_encoding =
++ dce110_opp_program_clamping_and_pixel_encoding,
++
++ .opp_set_dyn_expansion = dce110_opp_set_dyn_expansion,
++ .opp_destroy = dce110_opp_destroy,
++};
++
++bool dce110_opp_v_construct(struct dce110_opp *opp110,
++ struct dc_context *ctx,
++ uint32_t inst,
++ const struct dce110_opp_reg_offsets *offsets)
++{
++ opp110->base.funcs = &funcs;
++
++ opp110->base.ctx = ctx;
++
++ opp110->base.inst = inst;
++
++ opp110->offsets = *offsets;
++
++ return true;
++}
++
++
++
++
+diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.h b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.h
+new file mode 100644
+index 0000000..56365aa
+--- /dev/null
++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_opp_v.h
+@@ -0,0 +1,55 @@
++/* Copyright 2012-15 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
++ *
++ */
++
++#ifndef __DC_OPP_DCE110_V_H__
++#define __DC_OPP_DCE110_V_H__
++
++#include "dc_types.h"
++#include "inc/opp.h"
++#include "core_types.h"
++
++#include "gamma_types.h" /* decprecated */
++
++struct gamma_parameters;
++
++bool dce110_opp_v_construct(struct dce110_opp *opp110,
++ struct dc_context *ctx,
++ uint32_t inst,
++ const struct dce110_opp_reg_offsets *offsets);
++
++/* underlay callbacks */
++void dce110_opp_v_set_csc_default(
++ struct output_pixel_processor *opp,
++ const struct default_adjustment *default_adjust);
++
++void dce110_opp_v_set_csc_adjustment(
++ struct output_pixel_processor *opp,
++ const struct grph_csc_adjustment *adjust);
++
++bool dce110_opp_set_regamma_v(
++ struct output_pixel_processor *opp,
++ const struct regamma_params *params);
++
++
++#endif /* __DC_OPP_DCE110_V_H__ */
+diff --git a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
+index 42e7306..c65f401 100644
+--- a/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
++++ b/drivers/gpu/drm/amd/dal/dc/dce110/dce110_resource.c
+@@ -1229,7 +1229,7 @@ audio_create_fail:
+ controller_create_fail:
+ for (i = 0; i < pool->pipe_count; i++) {
+ if (pool->opps[i] != NULL)
+- dce110_opp_destroy(&pool->opps[i]);
++ pool->opps[i]->funcs->opp_destroy(&pool->opps[i]);
+
+ if (pool->transforms[i] != NULL)
+ dce110_transform_destroy(&pool->transforms[i]);
+diff --git a/drivers/gpu/drm/amd/dal/dc/inc/opp.h b/drivers/gpu/drm/amd/dal/dc/inc/opp.h
+index 307184a..74dbea9 100644
+--- a/drivers/gpu/drm/amd/dal/dc/inc/opp.h
++++ b/drivers/gpu/drm/amd/dal/dc/inc/opp.h
+@@ -29,6 +29,8 @@
+ #include "dc_types.h"
+ #include "grph_object_id.h"
+ #include "grph_csc_types.h"
++#include "video_csc_types.h"
++#include "hw_sequencer_types.h"
+
+ struct fixed31_32;
+ struct gamma_parameters;
+@@ -303,6 +305,19 @@ struct opp_funcs {
+ enum color_space color_sp,
+ enum dc_color_depth color_dpth,
+ enum signal_type signal);
++
++ /* underlay related */
++ void (*opp_get_underlay_adjustment_range)(
++ struct output_pixel_processor *opp,
++ enum ovl_csc_adjust_item overlay_adjust_item,
++ struct hw_adjustment_range *range);
++
++ void (*opp_set_ovl_csc_adjustment)(
++ struct output_pixel_processor *opp,
++ const struct ovl_csc_adjustment *adjust,
++ enum color_space c_space);
++
++ void (*opp_destroy)(struct output_pixel_processor **opp);
+ };
+
+ #endif
+--
+2.7.4
+