LCOV - code coverage report
Current view: top level - drivers/gpu/drm/amd/display/dc/dcn30 - dcn30_dpp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 562 0.0 %
Date: 2022-12-09 01:23:36 Functions: 0 31 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright 2020 Advanced Micro Devices, Inc.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the "Software"),
       6             :  * to deal in the Software without restriction, including without limitation
       7             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       8             :  * and/or sell copies of the Software, and to permit persons to whom the
       9             :  * Software is furnished to do so, subject to the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included in
      12             :  * all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      15             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      16             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      17             :  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
      18             :  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      19             :  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
      20             :  * OTHER DEALINGS IN THE SOFTWARE.
      21             :  *
      22             :  * Authors: AMD
      23             :  *
      24             :  */
      25             : 
      26             : #include "dm_services.h"
      27             : #include "core_types.h"
      28             : #include "reg_helper.h"
      29             : #include "dcn30_dpp.h"
      30             : #include "basics/conversion.h"
      31             : #include "dcn30_cm_common.h"
      32             : 
      33             : #define REG(reg)\
      34             :         dpp->tf_regs->reg
      35             : 
      36             : #define CTX \
      37             :         dpp->base.ctx
      38             : 
      39             : #undef FN
      40             : #define FN(reg_name, field_name) \
      41             :         dpp->tf_shift->field_name, dpp->tf_mask->field_name
      42             : 
      43             : 
      44           0 : void dpp30_read_state(struct dpp *dpp_base, struct dcn_dpp_state *s)
      45             : {
      46           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
      47             : 
      48           0 :         REG_GET(DPP_CONTROL,
      49             :                         DPP_CLOCK_ENABLE, &s->is_enabled);
      50             : 
      51             :         // TODO: Implement for DCN3
      52           0 : }
      53             : /*program post scaler scs block in dpp CM*/
      54           0 : void dpp3_program_post_csc(
      55             :                 struct dpp *dpp_base,
      56             :                 enum dc_color_space color_space,
      57             :                 enum dcn10_input_csc_select input_select,
      58             :                 const struct out_csc_color_matrix *tbl_entry)
      59             : {
      60           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
      61             :         int i;
      62           0 :         int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
      63           0 :         const uint16_t *regval = NULL;
      64           0 :         uint32_t cur_select = 0;
      65             :         enum dcn10_input_csc_select select;
      66             :         struct color_matrices_reg gam_regs;
      67             : 
      68           0 :         if (input_select == INPUT_CSC_SELECT_BYPASS) {
      69           0 :                 REG_SET(CM_POST_CSC_CONTROL, 0, CM_POST_CSC_MODE, 0);
      70           0 :                 return;
      71             :         }
      72             : 
      73           0 :         if (tbl_entry == NULL) {
      74           0 :                 for (i = 0; i < arr_size; i++)
      75           0 :                         if (dpp_input_csc_matrix[i].color_space == color_space) {
      76           0 :                                 regval = dpp_input_csc_matrix[i].regval;
      77           0 :                                 break;
      78             :                         }
      79             : 
      80           0 :                 if (regval == NULL) {
      81           0 :                         BREAK_TO_DEBUGGER();
      82           0 :                         return;
      83             :                 }
      84             :         } else {
      85           0 :                 regval = tbl_entry->regval;
      86             :         }
      87             : 
      88             :         /* determine which CSC matrix (icsc or coma) we are using
      89             :          * currently.  select the alternate set to double buffer
      90             :          * the CSC update so CSC is updated on frame boundary
      91             :          */
      92           0 :         REG_GET(CM_POST_CSC_CONTROL,
      93             :                         CM_POST_CSC_MODE_CURRENT, &cur_select);
      94             : 
      95           0 :         if (cur_select != INPUT_CSC_SELECT_ICSC)
      96             :                 select = INPUT_CSC_SELECT_ICSC;
      97             :         else
      98           0 :                 select = INPUT_CSC_SELECT_COMA;
      99             : 
     100           0 :         gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_POST_CSC_C11;
     101           0 :         gam_regs.masks.csc_c11  = dpp->tf_mask->CM_POST_CSC_C11;
     102           0 :         gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_POST_CSC_C12;
     103           0 :         gam_regs.masks.csc_c12 = dpp->tf_mask->CM_POST_CSC_C12;
     104             : 
     105           0 :         if (select == INPUT_CSC_SELECT_ICSC) {
     106             : 
     107           0 :                 gam_regs.csc_c11_c12 = REG(CM_POST_CSC_C11_C12);
     108           0 :                 gam_regs.csc_c33_c34 = REG(CM_POST_CSC_C33_C34);
     109             : 
     110             :         } else {
     111             : 
     112           0 :                 gam_regs.csc_c11_c12 = REG(CM_POST_CSC_B_C11_C12);
     113           0 :                 gam_regs.csc_c33_c34 = REG(CM_POST_CSC_B_C33_C34);
     114             : 
     115             :         }
     116             : 
     117           0 :         cm_helper_program_color_matrices(
     118             :                         dpp->base.ctx,
     119             :                         regval,
     120             :                         &gam_regs);
     121             : 
     122           0 :         REG_SET(CM_POST_CSC_CONTROL, 0,
     123             :                         CM_POST_CSC_MODE, select);
     124             : }
     125             : 
     126             : 
     127             : /*CNVC degam unit has read only LUTs*/
     128           0 : void dpp3_set_pre_degam(struct dpp *dpp_base, enum dc_transfer_func_predefined tr)
     129             : {
     130           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     131           0 :         int pre_degam_en = 1;
     132           0 :         int degamma_lut_selection = 0;
     133             : 
     134             :         switch (tr) {
     135             :         case TRANSFER_FUNCTION_LINEAR:
     136             :         case TRANSFER_FUNCTION_UNITY:
     137             :                 pre_degam_en = 0; //bypass
     138             :                 break;
     139             :         case TRANSFER_FUNCTION_SRGB:
     140             :                 degamma_lut_selection = 0;
     141             :                 break;
     142             :         case TRANSFER_FUNCTION_BT709:
     143             :                 degamma_lut_selection = 4;
     144             :                 break;
     145             :         case TRANSFER_FUNCTION_PQ:
     146             :                 degamma_lut_selection = 5;
     147             :                 break;
     148             :         case TRANSFER_FUNCTION_HLG:
     149             :                 degamma_lut_selection = 6;
     150             :                 break;
     151             :         case TRANSFER_FUNCTION_GAMMA22:
     152             :                 degamma_lut_selection = 1;
     153             :                 break;
     154             :         case TRANSFER_FUNCTION_GAMMA24:
     155             :                 degamma_lut_selection = 2;
     156             :                 break;
     157             :         case TRANSFER_FUNCTION_GAMMA26:
     158             :                 degamma_lut_selection = 3;
     159             :                 break;
     160             :         default:
     161             :                 pre_degam_en = 0;
     162             :                 break;
     163             :         }
     164             : 
     165           0 :         REG_SET_2(PRE_DEGAM, 0,
     166             :                         PRE_DEGAM_MODE, pre_degam_en,
     167             :                         PRE_DEGAM_SELECT, degamma_lut_selection);
     168           0 : }
     169             : 
     170           0 : void dpp3_cnv_setup (
     171             :                 struct dpp *dpp_base,
     172             :                 enum surface_pixel_format format,
     173             :                 enum expansion_mode mode,
     174             :                 struct dc_csc_transform input_csc_color_matrix,
     175             :                 enum dc_color_space input_color_space,
     176             :                 struct cnv_alpha_2bit_lut *alpha_2bit_lut)
     177             : {
     178           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     179           0 :         uint32_t pixel_format = 0;
     180           0 :         uint32_t alpha_en = 1;
     181           0 :         enum dc_color_space color_space = COLOR_SPACE_SRGB;
     182           0 :         enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS;
     183           0 :         bool force_disable_cursor = false;
     184           0 :         uint32_t is_2bit = 0;
     185           0 :         uint32_t alpha_plane_enable = 0;
     186           0 :         uint32_t dealpha_en = 0, dealpha_ablnd_en = 0;
     187           0 :         uint32_t realpha_en = 0, realpha_ablnd_en = 0;
     188           0 :         uint32_t program_prealpha_dealpha = 0;
     189             :         struct out_csc_color_matrix tbl_entry;
     190             :         int i;
     191             : 
     192           0 :         REG_SET_2(FORMAT_CONTROL, 0,
     193             :                 CNVC_BYPASS, 0,
     194             :                 FORMAT_EXPANSION_MODE, mode);
     195             : 
     196           0 :         REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0);
     197           0 :         REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0);
     198           0 :         REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0);
     199           0 :         REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0);
     200             : 
     201           0 :         REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_R, 0);
     202           0 :         REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_G, 1);
     203           0 :         REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_B, 2);
     204             : 
     205             :         switch (format) {
     206             :         case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
     207             :                 pixel_format = 1;
     208             :                 break;
     209             :         case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
     210             :                 pixel_format = 3;
     211             :                 alpha_en = 0;
     212             :                 break;
     213             :         case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
     214             :         case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
     215             :                 pixel_format = 8;
     216             :                 break;
     217             :         case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
     218             :         case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
     219             :                 pixel_format = 10;
     220             :                 is_2bit = 1;
     221             :                 break;
     222             :         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
     223             :                 force_disable_cursor = false;
     224             :                 pixel_format = 65;
     225             :                 color_space = COLOR_SPACE_YCBCR709;
     226             :                 select = INPUT_CSC_SELECT_ICSC;
     227             :                 break;
     228             :         case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
     229             :                 force_disable_cursor = true;
     230             :                 pixel_format = 64;
     231             :                 color_space = COLOR_SPACE_YCBCR709;
     232             :                 select = INPUT_CSC_SELECT_ICSC;
     233             :                 break;
     234             :         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
     235             :                 force_disable_cursor = true;
     236             :                 pixel_format = 67;
     237             :                 color_space = COLOR_SPACE_YCBCR709;
     238             :                 select = INPUT_CSC_SELECT_ICSC;
     239             :                 break;
     240             :         case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
     241             :                 force_disable_cursor = true;
     242             :                 pixel_format = 66;
     243             :                 color_space = COLOR_SPACE_YCBCR709;
     244             :                 select = INPUT_CSC_SELECT_ICSC;
     245             :                 break;
     246             :         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
     247             :         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
     248             :                 pixel_format = 26; /* ARGB16161616_UNORM */
     249             :                 break;
     250             :         case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
     251             :                 pixel_format = 24;
     252             :                 break;
     253             :         case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
     254             :                 pixel_format = 25;
     255             :                 break;
     256             :         case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
     257             :                 pixel_format = 12;
     258             :                 color_space = COLOR_SPACE_YCBCR709;
     259             :                 select = INPUT_CSC_SELECT_ICSC;
     260             :                 break;
     261             :         case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
     262             :                 pixel_format = 112;
     263             :                 break;
     264             :         case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
     265             :                 pixel_format = 113;
     266             :                 break;
     267             :         case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
     268             :                 pixel_format = 114;
     269             :                 color_space = COLOR_SPACE_YCBCR709;
     270             :                 select = INPUT_CSC_SELECT_ICSC;
     271             :                 is_2bit = 1;
     272             :                 break;
     273             :         case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
     274             :                 pixel_format = 115;
     275             :                 color_space = COLOR_SPACE_YCBCR709;
     276             :                 select = INPUT_CSC_SELECT_ICSC;
     277             :                 is_2bit = 1;
     278             :                 break;
     279             :         case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
     280             :                 pixel_format = 116;
     281             :                 alpha_plane_enable = 0;
     282             :                 break;
     283             :         case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
     284             :                 pixel_format = 116;
     285             :                 alpha_plane_enable = 1;
     286             :                 break;
     287             :         case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
     288             :                 pixel_format = 118;
     289             :                 break;
     290             :         case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
     291             :                 pixel_format = 119;
     292             :                 break;
     293             :         default:
     294             :                 break;
     295             :         }
     296             : 
     297             :         /* Set default color space based on format if none is given. */
     298           0 :         color_space = input_color_space ? input_color_space : color_space;
     299             : 
     300           0 :         if (is_2bit == 1 && alpha_2bit_lut != NULL) {
     301           0 :                 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0);
     302           0 :                 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1);
     303           0 :                 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2);
     304           0 :                 REG_UPDATE(ALPHA_2BIT_LUT, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3);
     305             :         }
     306             : 
     307           0 :         REG_SET_2(CNVC_SURFACE_PIXEL_FORMAT, 0,
     308             :                         CNVC_SURFACE_PIXEL_FORMAT, pixel_format,
     309             :                         CNVC_ALPHA_PLANE_ENABLE, alpha_plane_enable);
     310           0 :         REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
     311             : 
     312             :         if (program_prealpha_dealpha) {
     313             :                 dealpha_en = 1;
     314             :                 realpha_en = 1;
     315             :         }
     316           0 :         REG_SET_2(PRE_DEALPHA, 0,
     317             :                         PRE_DEALPHA_EN, dealpha_en,
     318             :                         PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en);
     319           0 :         REG_SET_2(PRE_REALPHA, 0,
     320             :                         PRE_REALPHA_EN, realpha_en,
     321             :                         PRE_REALPHA_ABLND_EN, realpha_ablnd_en);
     322             : 
     323             :         /* If input adjustment exists, program the ICSC with those values. */
     324           0 :         if (input_csc_color_matrix.enable_adjustment == true) {
     325           0 :                 for (i = 0; i < 12; i++)
     326           0 :                         tbl_entry.regval[i] = input_csc_color_matrix.matrix[i];
     327             : 
     328           0 :                 tbl_entry.color_space = input_color_space;
     329             : 
     330           0 :                 if (color_space >= COLOR_SPACE_YCBCR601)
     331             :                         select = INPUT_CSC_SELECT_ICSC;
     332             :                 else
     333           0 :                         select = INPUT_CSC_SELECT_BYPASS;
     334             : 
     335           0 :                 dpp3_program_post_csc(dpp_base, color_space, select,
     336             :                                       &tbl_entry);
     337             :         } else {
     338           0 :                 dpp3_program_post_csc(dpp_base, color_space, select, NULL);
     339             :         }
     340             : 
     341           0 :         if (force_disable_cursor) {
     342           0 :                 REG_UPDATE(CURSOR_CONTROL,
     343             :                                 CURSOR_ENABLE, 0);
     344           0 :                 REG_UPDATE(CURSOR0_CONTROL,
     345             :                                 CUR0_ENABLE, 0);
     346             :         }
     347           0 : }
     348             : 
     349             : #define IDENTITY_RATIO(ratio) (dc_fixpt_u3d19(ratio) == (1 << 19))
     350             : 
     351           0 : void dpp3_set_cursor_attributes(
     352             :                 struct dpp *dpp_base,
     353             :                 struct dc_cursor_attributes *cursor_attributes)
     354             : {
     355           0 :         enum dc_cursor_color_format color_format = cursor_attributes->color_format;
     356           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     357           0 :         int cur_rom_en = 0;
     358             : 
     359           0 :         if (color_format == CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA ||
     360             :                 color_format == CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA)
     361           0 :                 cur_rom_en = 1;
     362             : 
     363           0 :         REG_UPDATE_3(CURSOR0_CONTROL,
     364             :                         CUR0_MODE, color_format,
     365             :                         CUR0_EXPANSION_MODE, 0,
     366             :                         CUR0_ROM_EN, cur_rom_en);
     367             : 
     368           0 :         if (color_format == CURSOR_MODE_MONO) {
     369             :                 /* todo: clarify what to program these to */
     370           0 :                 REG_UPDATE(CURSOR0_COLOR0,
     371             :                                 CUR0_COLOR0, 0x00000000);
     372           0 :                 REG_UPDATE(CURSOR0_COLOR1,
     373             :                                 CUR0_COLOR1, 0xFFFFFFFF);
     374             :         }
     375           0 : }
     376             : 
     377             : 
     378           0 : bool dpp3_get_optimal_number_of_taps(
     379             :                 struct dpp *dpp,
     380             :                 struct scaler_data *scl_data,
     381             :                 const struct scaling_taps *in_taps)
     382             : {
     383             :         int num_part_y, num_part_c;
     384             :         int max_taps_y, max_taps_c;
     385             :         int min_taps_y, min_taps_c;
     386             :         enum lb_memory_config lb_config;
     387             : 
     388           0 :         if (scl_data->viewport.width > scl_data->h_active &&
     389           0 :                 dpp->ctx->dc->debug.max_downscale_src_width != 0 &&
     390             :                 scl_data->viewport.width > dpp->ctx->dc->debug.max_downscale_src_width)
     391             :                 return false;
     392             : 
     393             :         /*
     394             :          * Set default taps if none are provided
     395             :          * From programming guide: taps = min{ ceil(2*H_RATIO,1), 8} for downscaling
     396             :          * taps = 4 for upscaling
     397             :          */
     398           0 :         if (in_taps->h_taps == 0) {
     399           0 :                 if (dc_fixpt_ceil(scl_data->ratios.horz) > 1)
     400           0 :                         scl_data->taps.h_taps = min(2 * dc_fixpt_ceil(scl_data->ratios.horz), 8);
     401             :                 else
     402           0 :                         scl_data->taps.h_taps = 4;
     403             :         } else
     404           0 :                 scl_data->taps.h_taps = in_taps->h_taps;
     405           0 :         if (in_taps->v_taps == 0) {
     406           0 :                 if (dc_fixpt_ceil(scl_data->ratios.vert) > 1)
     407           0 :                         scl_data->taps.v_taps = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert, 2)), 8);
     408             :                 else
     409           0 :                         scl_data->taps.v_taps = 4;
     410             :         } else
     411           0 :                 scl_data->taps.v_taps = in_taps->v_taps;
     412           0 :         if (in_taps->v_taps_c == 0) {
     413           0 :                 if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 1)
     414           0 :                         scl_data->taps.v_taps_c = min(dc_fixpt_ceil(dc_fixpt_mul_int(scl_data->ratios.vert_c, 2)), 8);
     415             :                 else
     416           0 :                         scl_data->taps.v_taps_c = 4;
     417             :         } else
     418           0 :                 scl_data->taps.v_taps_c = in_taps->v_taps_c;
     419           0 :         if (in_taps->h_taps_c == 0) {
     420           0 :                 if (dc_fixpt_ceil(scl_data->ratios.horz_c) > 1)
     421           0 :                         scl_data->taps.h_taps_c = min(2 * dc_fixpt_ceil(scl_data->ratios.horz_c), 8);
     422             :                 else
     423           0 :                         scl_data->taps.h_taps_c = 4;
     424           0 :         } else if ((in_taps->h_taps_c % 2) != 0 && in_taps->h_taps_c != 1)
     425             :                 /* Only 1 and even h_taps_c are supported by hw */
     426           0 :                 scl_data->taps.h_taps_c = in_taps->h_taps_c - 1;
     427             :         else
     428           0 :                 scl_data->taps.h_taps_c = in_taps->h_taps_c;
     429             : 
     430             :         /*Ensure we can support the requested number of vtaps*/
     431           0 :         min_taps_y = dc_fixpt_ceil(scl_data->ratios.vert);
     432           0 :         min_taps_c = dc_fixpt_ceil(scl_data->ratios.vert_c);
     433             : 
     434             :         /* Use LB_MEMORY_CONFIG_3 for 4:2:0 */
     435           0 :         if ((scl_data->format == PIXEL_FORMAT_420BPP8) || (scl_data->format == PIXEL_FORMAT_420BPP10))
     436             :                 lb_config = LB_MEMORY_CONFIG_3;
     437             :         else
     438           0 :                 lb_config = LB_MEMORY_CONFIG_0;
     439             : 
     440           0 :         dpp->caps->dscl_calc_lb_num_partitions(
     441             :                         scl_data, lb_config, &num_part_y, &num_part_c);
     442             : 
     443             :         /* MAX_V_TAPS = MIN (NUM_LINES - MAX(CEILING(V_RATIO,1)-2, 0), 8) */
     444           0 :         if (dc_fixpt_ceil(scl_data->ratios.vert) > 2)
     445           0 :                 max_taps_y = num_part_y - (dc_fixpt_ceil(scl_data->ratios.vert) - 2);
     446             :         else
     447           0 :                 max_taps_y = num_part_y;
     448             : 
     449           0 :         if (dc_fixpt_ceil(scl_data->ratios.vert_c) > 2)
     450           0 :                 max_taps_c = num_part_c - (dc_fixpt_ceil(scl_data->ratios.vert_c) - 2);
     451             :         else
     452           0 :                 max_taps_c = num_part_c;
     453             : 
     454           0 :         if (max_taps_y < min_taps_y)
     455             :                 return false;
     456           0 :         else if (max_taps_c < min_taps_c)
     457             :                 return false;
     458             : 
     459           0 :         if (scl_data->taps.v_taps > max_taps_y)
     460           0 :                 scl_data->taps.v_taps = max_taps_y;
     461             : 
     462           0 :         if (scl_data->taps.v_taps_c > max_taps_c)
     463           0 :                 scl_data->taps.v_taps_c = max_taps_c;
     464             : 
     465           0 :         if (!dpp->ctx->dc->debug.always_scale) {
     466           0 :                 if (IDENTITY_RATIO(scl_data->ratios.horz))
     467           0 :                         scl_data->taps.h_taps = 1;
     468           0 :                 if (IDENTITY_RATIO(scl_data->ratios.vert))
     469           0 :                         scl_data->taps.v_taps = 1;
     470           0 :                 if (IDENTITY_RATIO(scl_data->ratios.horz_c))
     471           0 :                         scl_data->taps.h_taps_c = 1;
     472           0 :                 if (IDENTITY_RATIO(scl_data->ratios.vert_c))
     473           0 :                         scl_data->taps.v_taps_c = 1;
     474             :         }
     475             : 
     476             :         return true;
     477             : }
     478             : 
     479           0 : static void dpp3_deferred_update(struct dpp *dpp_base)
     480             : {
     481             :         int bypass_state;
     482           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     483             : 
     484           0 :         if (dpp_base->deferred_reg_writes.bits.disable_dscl) {
     485           0 :                 REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3);
     486           0 :                 dpp_base->deferred_reg_writes.bits.disable_dscl = false;
     487             :         }
     488             : 
     489           0 :         if (dpp_base->deferred_reg_writes.bits.disable_gamcor) {
     490           0 :                 REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state);
     491           0 :                 if (bypass_state == 0) {        // only program if bypass was latched
     492           0 :                         REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3);
     493             :                 } else
     494           0 :                         ASSERT(0); // LUT select was updated again before vupdate
     495           0 :                 dpp_base->deferred_reg_writes.bits.disable_gamcor = false;
     496             :         }
     497             : 
     498           0 :         if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) {
     499           0 :                 REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state);
     500           0 :                 if (bypass_state == 0) {        // only program if bypass was latched
     501           0 :                         REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3);
     502             :                 } else
     503           0 :                         ASSERT(0); // LUT select was updated again before vupdate
     504           0 :                 dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false;
     505             :         }
     506             : 
     507           0 :         if (dpp_base->deferred_reg_writes.bits.disable_3dlut) {
     508           0 :                 REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state);
     509           0 :                 if (bypass_state == 0) {        // only program if bypass was latched
     510           0 :                         REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3);
     511             :                 } else
     512           0 :                         ASSERT(0); // LUT select was updated again before vupdate
     513           0 :                 dpp_base->deferred_reg_writes.bits.disable_3dlut = false;
     514             :         }
     515             : 
     516           0 :         if (dpp_base->deferred_reg_writes.bits.disable_shaper) {
     517           0 :                 REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state);
     518           0 :                 if (bypass_state == 0) {        // only program if bypass was latched
     519           0 :                         REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3);
     520             :                 } else
     521           0 :                         ASSERT(0); // LUT select was updated again before vupdate
     522           0 :                 dpp_base->deferred_reg_writes.bits.disable_shaper = false;
     523             :         }
     524           0 : }
     525             : 
     526           0 : static void dpp3_power_on_blnd_lut(
     527             :         struct dpp *dpp_base,
     528             :         bool power_on)
     529             : {
     530           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     531             : 
     532           0 :         if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
     533           0 :                 if (power_on) {
     534           0 :                         REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0);
     535           0 :                         REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5);
     536             :                 } else {
     537           0 :                         dpp_base->ctx->dc->optimized_required = true;
     538           0 :                         dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true;
     539             :                 }
     540             :         } else {
     541           0 :                 REG_SET(CM_MEM_PWR_CTRL, 0,
     542             :                                 BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1);
     543             :         }
     544           0 : }
     545             : 
     546           0 : static void dpp3_power_on_hdr3dlut(
     547             :         struct dpp *dpp_base,
     548             :         bool power_on)
     549             : {
     550           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     551             : 
     552           0 :         if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
     553           0 :                 if (power_on) {
     554           0 :                         REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0);
     555           0 :                         REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5);
     556             :                 } else {
     557           0 :                         dpp_base->ctx->dc->optimized_required = true;
     558           0 :                         dpp_base->deferred_reg_writes.bits.disable_3dlut = true;
     559             :                 }
     560             :         }
     561           0 : }
     562             : 
     563           0 : static void dpp3_power_on_shaper(
     564             :         struct dpp *dpp_base,
     565             :         bool power_on)
     566             : {
     567           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     568             : 
     569           0 :         if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) {
     570           0 :                 if (power_on) {
     571           0 :                         REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0);
     572           0 :                         REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5);
     573             :                 } else {
     574           0 :                         dpp_base->ctx->dc->optimized_required = true;
     575           0 :                         dpp_base->deferred_reg_writes.bits.disable_shaper = true;
     576             :                 }
     577             :         }
     578           0 : }
     579             : 
     580           0 : static void dpp3_configure_blnd_lut(
     581             :                 struct dpp *dpp_base,
     582             :                 bool is_ram_a)
     583             : {
     584           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     585             : 
     586           0 :         REG_UPDATE_2(CM_BLNDGAM_LUT_CONTROL,
     587             :                         CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 7,
     588             :                         CM_BLNDGAM_LUT_HOST_SEL, is_ram_a == true ? 0 : 1);
     589             : 
     590           0 :         REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
     591           0 : }
     592             : 
     593           0 : static void dpp3_program_blnd_pwl(
     594             :                 struct dpp *dpp_base,
     595             :                 const struct pwl_result_data *rgb,
     596             :                 uint32_t num)
     597             : {
     598             :         uint32_t i;
     599           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     600           0 :         uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg;
     601           0 :         uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg;
     602           0 :         uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg;
     603             : 
     604           0 :         if (is_rgb_equal(rgb, num)) {
     605           0 :                 for (i = 0 ; i < num; i++)
     606           0 :                         REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
     607           0 :                 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
     608             :         } else {
     609           0 :                 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 4);
     610           0 :                 for (i = 0 ; i < num; i++)
     611           0 :                         REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
     612           0 :                 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_red);
     613             : 
     614           0 :                 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 2);
     615           0 :                 for (i = 0 ; i < num; i++)
     616           0 :                         REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
     617           0 :                 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_green);
     618             : 
     619           0 :                 REG_UPDATE(CM_BLNDGAM_LUT_CONTROL, CM_BLNDGAM_LUT_WRITE_COLOR_MASK, 1);
     620           0 :                 for (i = 0 ; i < num; i++)
     621           0 :                         REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
     622           0 :                 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, last_base_value_blue);
     623             :         }
     624           0 : }
     625             : 
     626           0 : static void dcn3_dpp_cm_get_reg_field(
     627             :                 struct dcn3_dpp *dpp,
     628             :                 struct dcn3_xfer_func_reg *reg)
     629             : {
     630           0 :         reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
     631           0 :         reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
     632           0 :         reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
     633           0 :         reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
     634           0 :         reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
     635           0 :         reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
     636           0 :         reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
     637           0 :         reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
     638             : 
     639           0 :         reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
     640           0 :         reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
     641           0 :         reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
     642           0 :         reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
     643           0 :         reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
     644           0 :         reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
     645           0 :         reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B;
     646           0 :         reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SLOPE_B;
     647           0 :         reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
     648           0 :         reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
     649           0 :         reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
     650           0 :         reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
     651           0 : }
     652             : 
     653             : /*program blnd lut RAM A*/
     654           0 : static void dpp3_program_blnd_luta_settings(
     655             :                 struct dpp *dpp_base,
     656             :                 const struct pwl_params *params)
     657             : {
     658           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     659             :         struct dcn3_xfer_func_reg gam_regs;
     660             : 
     661           0 :         dcn3_dpp_cm_get_reg_field(dpp, &gam_regs);
     662             : 
     663           0 :         gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
     664           0 :         gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
     665           0 :         gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
     666           0 :         gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_B);
     667           0 :         gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_G);
     668           0 :         gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_START_SLOPE_CNTL_R);
     669           0 :         gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
     670           0 :         gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
     671           0 :         gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
     672           0 :         gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
     673           0 :         gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
     674           0 :         gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
     675           0 :         gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
     676           0 :         gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
     677             : 
     678           0 :         cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs);
     679           0 : }
     680             : 
     681             : /*program blnd lut RAM B*/
     682           0 : static void dpp3_program_blnd_lutb_settings(
     683             :                 struct dpp *dpp_base,
     684             :                 const struct pwl_params *params)
     685             : {
     686           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     687             :         struct dcn3_xfer_func_reg gam_regs;
     688             : 
     689           0 :         dcn3_dpp_cm_get_reg_field(dpp, &gam_regs);
     690             : 
     691           0 :         gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
     692           0 :         gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
     693           0 :         gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
     694           0 :         gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_B);
     695           0 :         gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_G);
     696           0 :         gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_START_SLOPE_CNTL_R);
     697           0 :         gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
     698           0 :         gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
     699           0 :         gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
     700           0 :         gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
     701           0 :         gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
     702           0 :         gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
     703           0 :         gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
     704           0 :         gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
     705             : 
     706           0 :         cm_helper_program_gamcor_xfer_func(dpp->base.ctx, params, &gam_regs);
     707           0 : }
     708             : 
     709           0 : static enum dc_lut_mode dpp3_get_blndgam_current(struct dpp *dpp_base)
     710             : {
     711             :         enum dc_lut_mode mode;
     712           0 :         uint32_t mode_current = 0;
     713           0 :         uint32_t in_use = 0;
     714             : 
     715           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     716             : 
     717           0 :         REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &mode_current);
     718           0 :         REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_SELECT_CURRENT, &in_use);
     719             : 
     720           0 :         switch (mode_current) {
     721             :         case 0:
     722             :         case 1:
     723             :                 mode = LUT_BYPASS;
     724             :                 break;
     725             : 
     726             :         case 2:
     727           0 :                 if (in_use == 0)
     728             :                         mode = LUT_RAM_A;
     729             :                 else
     730           0 :                         mode = LUT_RAM_B;
     731             :                 break;
     732             :         default:
     733             :                 mode = LUT_BYPASS;
     734             :                 break;
     735             :         }
     736             : 
     737           0 :         return mode;
     738             : }
     739             : 
     740           0 : static bool dpp3_program_blnd_lut(struct dpp *dpp_base,
     741             :                                   const struct pwl_params *params)
     742             : {
     743             :         enum dc_lut_mode current_mode;
     744             :         enum dc_lut_mode next_mode;
     745           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     746             : 
     747           0 :         if (params == NULL) {
     748           0 :                 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_MODE, 0);
     749           0 :                 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
     750           0 :                         dpp3_power_on_blnd_lut(dpp_base, false);
     751             :                 return false;
     752             :         }
     753             : 
     754           0 :         current_mode = dpp3_get_blndgam_current(dpp_base);
     755           0 :         if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_B)
     756             :                 next_mode = LUT_RAM_A;
     757             :         else
     758           0 :                 next_mode = LUT_RAM_B;
     759             : 
     760           0 :         dpp3_power_on_blnd_lut(dpp_base, true);
     761           0 :         dpp3_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
     762             : 
     763           0 :         if (next_mode == LUT_RAM_A)
     764           0 :                 dpp3_program_blnd_luta_settings(dpp_base, params);
     765             :         else
     766           0 :                 dpp3_program_blnd_lutb_settings(dpp_base, params);
     767             : 
     768           0 :         dpp3_program_blnd_pwl(
     769           0 :                         dpp_base, params->rgb_resulted, params->hw_points_num);
     770             : 
     771           0 :         REG_UPDATE_2(CM_BLNDGAM_CONTROL,
     772             :                         CM_BLNDGAM_MODE, 2,
     773             :                         CM_BLNDGAM_SELECT, next_mode == LUT_RAM_A ? 0 : 1);
     774             : 
     775           0 :         return true;
     776             : }
     777             : 
     778             : 
     779           0 : static void dpp3_program_shaper_lut(
     780             :                 struct dpp *dpp_base,
     781             :                 const struct pwl_result_data *rgb,
     782             :                 uint32_t num)
     783             : {
     784             :         uint32_t i, red, green, blue;
     785             :         uint32_t  red_delta, green_delta, blue_delta;
     786             :         uint32_t  red_value, green_value, blue_value;
     787             : 
     788           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     789             : 
     790           0 :         for (i = 0 ; i < num; i++) {
     791             : 
     792           0 :                 red   = rgb[i].red_reg;
     793           0 :                 green = rgb[i].green_reg;
     794           0 :                 blue  = rgb[i].blue_reg;
     795             : 
     796           0 :                 red_delta   = rgb[i].delta_red_reg;
     797           0 :                 green_delta = rgb[i].delta_green_reg;
     798           0 :                 blue_delta  = rgb[i].delta_blue_reg;
     799             : 
     800           0 :                 red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
     801           0 :                 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
     802           0 :                 blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
     803             : 
     804           0 :                 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
     805           0 :                 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
     806           0 :                 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
     807             :         }
     808             : 
     809           0 : }
     810             : 
     811           0 : static enum dc_lut_mode dpp3_get_shaper_current(struct dpp *dpp_base)
     812             : {
     813             :         enum dc_lut_mode mode;
     814             :         uint32_t state_mode;
     815           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     816             : 
     817           0 :         REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &state_mode);
     818             : 
     819           0 :         switch (state_mode) {
     820             :         case 0:
     821             :                 mode = LUT_BYPASS;
     822             :                 break;
     823             :         case 1:
     824           0 :                 mode = LUT_RAM_A;
     825           0 :                 break;
     826             :         case 2:
     827           0 :                 mode = LUT_RAM_B;
     828           0 :                 break;
     829             :         default:
     830             :                 mode = LUT_BYPASS;
     831             :                 break;
     832             :         }
     833             : 
     834           0 :         return mode;
     835             : }
     836             : 
     837           0 : static void dpp3_configure_shaper_lut(
     838             :                 struct dpp *dpp_base,
     839             :                 bool is_ram_a)
     840             : {
     841           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     842             : 
     843           0 :         REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
     844             :                         CM_SHAPER_LUT_WRITE_EN_MASK, 7);
     845           0 :         REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
     846             :                         CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
     847           0 :         REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
     848           0 : }
     849             : 
     850             : /*program shaper RAM A*/
     851             : 
     852           0 : static void dpp3_program_shaper_luta_settings(
     853             :                 struct dpp *dpp_base,
     854             :                 const struct pwl_params *params)
     855             : {
     856             :         const struct gamma_curve *curve;
     857           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
     858             : 
     859           0 :         REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
     860             :                 CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
     861             :                 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
     862           0 :         REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
     863             :                 CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
     864             :                 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
     865           0 :         REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
     866             :                 CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
     867             :                 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
     868             : 
     869           0 :         REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
     870             :                 CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
     871             :                 CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
     872             : 
     873           0 :         REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
     874             :                 CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
     875             :                 CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
     876             : 
     877           0 :         REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
     878             :                 CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
     879             :                 CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
     880             : 
     881           0 :         curve = params->arr_curve_points;
     882           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
     883             :                 CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
     884             :                 CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
     885             :                 CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
     886             :                 CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
     887             : 
     888           0 :         curve += 2;
     889           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
     890             :                 CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
     891             :                 CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
     892             :                 CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
     893             :                 CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
     894             : 
     895           0 :         curve += 2;
     896           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
     897             :                 CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
     898             :                 CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
     899             :                 CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
     900             :                 CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
     901             : 
     902           0 :         curve += 2;
     903           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
     904             :                 CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
     905             :                 CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
     906             :                 CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
     907             :                 CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
     908             : 
     909           0 :         curve += 2;
     910           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
     911             :                 CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
     912             :                 CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
     913             :                 CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
     914             :                 CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
     915             : 
     916           0 :         curve += 2;
     917           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
     918             :                 CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
     919             :                 CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
     920             :                 CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
     921             :                 CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
     922             : 
     923           0 :         curve += 2;
     924           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
     925             :                 CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
     926             :                 CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
     927             :                 CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
     928             :                 CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
     929             : 
     930           0 :         curve += 2;
     931           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
     932             :                 CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
     933             :                 CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
     934             :                 CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
     935             :                 CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
     936             : 
     937           0 :         curve += 2;
     938           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
     939             :                 CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
     940             :                 CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
     941             :                 CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
     942             :                 CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
     943             : 
     944           0 :         curve += 2;
     945           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
     946             :                 CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
     947             :                 CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
     948             :                 CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
     949             :                 CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
     950             : 
     951           0 :         curve += 2;
     952           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
     953             :                 CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
     954             :                 CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
     955             :                 CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
     956             :                 CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
     957             : 
     958           0 :         curve += 2;
     959           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
     960             :                 CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
     961             :                 CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
     962             :                 CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
     963             :                 CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
     964             : 
     965           0 :         curve += 2;
     966           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
     967             :                 CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
     968             :                 CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
     969             :                 CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
     970             :                 CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
     971             : 
     972           0 :         curve += 2;
     973           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
     974             :                 CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
     975             :                 CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
     976             :                 CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
     977             :                 CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
     978             : 
     979           0 :         curve += 2;
     980           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
     981             :                 CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
     982             :                 CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
     983             :                 CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
     984             :                 CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
     985             : 
     986           0 :         curve += 2;
     987           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
     988             :                 CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
     989             :                 CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
     990             :                 CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
     991             :                 CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
     992             : 
     993           0 :         curve += 2;
     994           0 :         REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
     995             :                 CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
     996             :                 CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
     997             :                 CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
     998             :                 CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
     999           0 : }
    1000             : 
    1001             : /*program shaper RAM B*/
    1002           0 : static void dpp3_program_shaper_lutb_settings(
    1003             :                 struct dpp *dpp_base,
    1004             :                 const struct pwl_params *params)
    1005             : {
    1006             :         const struct gamma_curve *curve;
    1007           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1008             : 
    1009           0 :         REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
    1010             :                 CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
    1011             :                 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
    1012           0 :         REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
    1013             :                 CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
    1014             :                 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
    1015           0 :         REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
    1016             :                 CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
    1017             :                 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
    1018             : 
    1019           0 :         REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
    1020             :                 CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
    1021             :                 CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
    1022             : 
    1023           0 :         REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
    1024             :                 CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
    1025             :                 CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
    1026             : 
    1027           0 :         REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
    1028             :                 CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
    1029             :                 CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
    1030             : 
    1031           0 :         curve = params->arr_curve_points;
    1032           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
    1033             :                 CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
    1034             :                 CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
    1035             :                 CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
    1036             :                 CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
    1037             : 
    1038           0 :         curve += 2;
    1039           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
    1040             :                 CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
    1041             :                 CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
    1042             :                 CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
    1043             :                 CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
    1044             : 
    1045           0 :         curve += 2;
    1046           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
    1047             :                 CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
    1048             :                 CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
    1049             :                 CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
    1050             :                 CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
    1051             : 
    1052           0 :         curve += 2;
    1053           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
    1054             :                 CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
    1055             :                 CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
    1056             :                 CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
    1057             :                 CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
    1058             : 
    1059           0 :         curve += 2;
    1060           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
    1061             :                 CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
    1062             :                 CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
    1063             :                 CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
    1064             :                 CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
    1065             : 
    1066           0 :         curve += 2;
    1067           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
    1068             :                 CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
    1069             :                 CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
    1070             :                 CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
    1071             :                 CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
    1072             : 
    1073           0 :         curve += 2;
    1074           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
    1075             :                 CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
    1076             :                 CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
    1077             :                 CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
    1078             :                 CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
    1079             : 
    1080           0 :         curve += 2;
    1081           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
    1082             :                 CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
    1083             :                 CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
    1084             :                 CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
    1085             :                 CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
    1086             : 
    1087           0 :         curve += 2;
    1088           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
    1089             :                 CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
    1090             :                 CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
    1091             :                 CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
    1092             :                 CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
    1093             : 
    1094           0 :         curve += 2;
    1095           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
    1096             :                 CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
    1097             :                 CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
    1098             :                 CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
    1099             :                 CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
    1100             : 
    1101           0 :         curve += 2;
    1102           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
    1103             :                 CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
    1104             :                 CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
    1105             :                 CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
    1106             :                 CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
    1107             : 
    1108           0 :         curve += 2;
    1109           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
    1110             :                 CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
    1111             :                 CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
    1112             :                 CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
    1113             :                 CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
    1114             : 
    1115           0 :         curve += 2;
    1116           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
    1117             :                 CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
    1118             :                 CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
    1119             :                 CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
    1120             :                 CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
    1121             : 
    1122           0 :         curve += 2;
    1123           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
    1124             :                 CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
    1125             :                 CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
    1126             :                 CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
    1127             :                 CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
    1128             : 
    1129           0 :         curve += 2;
    1130           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
    1131             :                 CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
    1132             :                 CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
    1133             :                 CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
    1134             :                 CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
    1135             : 
    1136           0 :         curve += 2;
    1137           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
    1138             :                 CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
    1139             :                 CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
    1140             :                 CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
    1141             :                 CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
    1142             : 
    1143           0 :         curve += 2;
    1144           0 :         REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
    1145             :                 CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
    1146             :                 CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
    1147             :                 CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
    1148             :                 CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
    1149             : 
    1150           0 : }
    1151             : 
    1152             : 
    1153           0 : static bool dpp3_program_shaper(struct dpp *dpp_base,
    1154             :                                 const struct pwl_params *params)
    1155             : {
    1156             :         enum dc_lut_mode current_mode;
    1157             :         enum dc_lut_mode next_mode;
    1158             : 
    1159           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1160             : 
    1161           0 :         if (params == NULL) {
    1162           0 :                 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
    1163           0 :                 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
    1164           0 :                         dpp3_power_on_shaper(dpp_base, false);
    1165             :                 return false;
    1166             :         }
    1167             : 
    1168           0 :         if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
    1169           0 :                 dpp3_power_on_shaper(dpp_base, true);
    1170             : 
    1171           0 :         current_mode = dpp3_get_shaper_current(dpp_base);
    1172             : 
    1173           0 :         if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
    1174             :                 next_mode = LUT_RAM_B;
    1175             :         else
    1176           0 :                 next_mode = LUT_RAM_A;
    1177             : 
    1178           0 :         dpp3_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
    1179             : 
    1180           0 :         if (next_mode == LUT_RAM_A)
    1181           0 :                 dpp3_program_shaper_luta_settings(dpp_base, params);
    1182             :         else
    1183           0 :                 dpp3_program_shaper_lutb_settings(dpp_base, params);
    1184             : 
    1185           0 :         dpp3_program_shaper_lut(
    1186           0 :                         dpp_base, params->rgb_resulted, params->hw_points_num);
    1187             : 
    1188           0 :         REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
    1189             : 
    1190           0 :         return true;
    1191             : 
    1192             : }
    1193             : 
    1194           0 : static enum dc_lut_mode get3dlut_config(
    1195             :                         struct dpp *dpp_base,
    1196             :                         bool *is_17x17x17,
    1197             :                         bool *is_12bits_color_channel)
    1198             : {
    1199             :         uint32_t i_mode, i_enable_10bits, lut_size;
    1200             :         enum dc_lut_mode mode;
    1201           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1202             : 
    1203           0 :         REG_GET(CM_3DLUT_READ_WRITE_CONTROL,
    1204             :                         CM_3DLUT_30BIT_EN, &i_enable_10bits);
    1205           0 :         REG_GET(CM_3DLUT_MODE,
    1206             :                         CM_3DLUT_MODE_CURRENT, &i_mode);
    1207             : 
    1208           0 :         switch (i_mode) {
    1209             :         case 0:
    1210             :                 mode = LUT_BYPASS;
    1211             :                 break;
    1212             :         case 1:
    1213           0 :                 mode = LUT_RAM_A;
    1214           0 :                 break;
    1215             :         case 2:
    1216           0 :                 mode = LUT_RAM_B;
    1217           0 :                 break;
    1218             :         default:
    1219             :                 mode = LUT_BYPASS;
    1220             :                 break;
    1221             :         }
    1222           0 :         if (i_enable_10bits > 0)
    1223           0 :                 *is_12bits_color_channel = false;
    1224             :         else
    1225           0 :                 *is_12bits_color_channel = true;
    1226             : 
    1227           0 :         REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
    1228             : 
    1229           0 :         if (lut_size == 0)
    1230           0 :                 *is_17x17x17 = true;
    1231             :         else
    1232           0 :                 *is_17x17x17 = false;
    1233             : 
    1234           0 :         return mode;
    1235             : }
    1236             : /*
    1237             :  * select ramA or ramB, or bypass
    1238             :  * select color channel size 10 or 12 bits
    1239             :  * select 3dlut size 17x17x17 or 9x9x9
    1240             :  */
    1241           0 : static void dpp3_set_3dlut_mode(
    1242             :                 struct dpp *dpp_base,
    1243             :                 enum dc_lut_mode mode,
    1244             :                 bool is_color_channel_12bits,
    1245             :                 bool is_lut_size17x17x17)
    1246             : {
    1247             :         uint32_t lut_mode;
    1248           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1249             : 
    1250           0 :         if (mode == LUT_BYPASS)
    1251             :                 lut_mode = 0;
    1252           0 :         else if (mode == LUT_RAM_A)
    1253             :                 lut_mode = 1;
    1254             :         else
    1255           0 :                 lut_mode = 2;
    1256             : 
    1257           0 :         REG_UPDATE_2(CM_3DLUT_MODE,
    1258             :                         CM_3DLUT_MODE, lut_mode,
    1259             :                         CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
    1260           0 : }
    1261             : 
    1262           0 : static void dpp3_select_3dlut_ram(
    1263             :                 struct dpp *dpp_base,
    1264             :                 enum dc_lut_mode mode,
    1265             :                 bool is_color_channel_12bits)
    1266             : {
    1267           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1268             : 
    1269           0 :         REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
    1270             :                         CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
    1271             :                         CM_3DLUT_30BIT_EN,
    1272             :                         is_color_channel_12bits == true ? 0:1);
    1273           0 : }
    1274             : 
    1275             : 
    1276             : 
    1277           0 : static void dpp3_set3dlut_ram12(
    1278             :                 struct dpp *dpp_base,
    1279             :                 const struct dc_rgb *lut,
    1280             :                 uint32_t entries)
    1281             : {
    1282             :         uint32_t i, red, green, blue, red1, green1, blue1;
    1283           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1284             : 
    1285           0 :         for (i = 0 ; i < entries; i += 2) {
    1286           0 :                 red   = lut[i].red<<4;
    1287           0 :                 green = lut[i].green<<4;
    1288           0 :                 blue  = lut[i].blue<<4;
    1289           0 :                 red1   = lut[i+1].red<<4;
    1290           0 :                 green1 = lut[i+1].green<<4;
    1291           0 :                 blue1  = lut[i+1].blue<<4;
    1292             : 
    1293           0 :                 REG_SET_2(CM_3DLUT_DATA, 0,
    1294             :                                 CM_3DLUT_DATA0, red,
    1295             :                                 CM_3DLUT_DATA1, red1);
    1296             : 
    1297           0 :                 REG_SET_2(CM_3DLUT_DATA, 0,
    1298             :                                 CM_3DLUT_DATA0, green,
    1299             :                                 CM_3DLUT_DATA1, green1);
    1300             : 
    1301           0 :                 REG_SET_2(CM_3DLUT_DATA, 0,
    1302             :                                 CM_3DLUT_DATA0, blue,
    1303             :                                 CM_3DLUT_DATA1, blue1);
    1304             : 
    1305             :         }
    1306           0 : }
    1307             : 
    1308             : /*
    1309             :  * load selected lut with 10 bits color channels
    1310             :  */
    1311           0 : static void dpp3_set3dlut_ram10(
    1312             :                 struct dpp *dpp_base,
    1313             :                 const struct dc_rgb *lut,
    1314             :                 uint32_t entries)
    1315             : {
    1316             :         uint32_t i, red, green, blue, value;
    1317           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1318             : 
    1319           0 :         for (i = 0; i < entries; i++) {
    1320           0 :                 red   = lut[i].red;
    1321           0 :                 green = lut[i].green;
    1322           0 :                 blue  = lut[i].blue;
    1323             : 
    1324           0 :                 value = (red<<20) | (green<<10) | blue;
    1325             : 
    1326           0 :                 REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
    1327             :         }
    1328             : 
    1329           0 : }
    1330             : 
    1331             : 
    1332           0 : static void dpp3_select_3dlut_ram_mask(
    1333             :                 struct dpp *dpp_base,
    1334             :                 uint32_t ram_selection_mask)
    1335             : {
    1336           0 :         struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);
    1337             : 
    1338           0 :         REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
    1339             :                         ram_selection_mask);
    1340           0 :         REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
    1341           0 : }
    1342             : 
    1343           0 : static bool dpp3_program_3dlut(struct dpp *dpp_base,
    1344             :                                struct tetrahedral_params *params)
    1345             : {
    1346             :         enum dc_lut_mode mode;
    1347             :         bool is_17x17x17;
    1348             :         bool is_12bits_color_channel;
    1349             :         struct dc_rgb *lut0;
    1350             :         struct dc_rgb *lut1;
    1351             :         struct dc_rgb *lut2;
    1352             :         struct dc_rgb *lut3;
    1353             :         int lut_size0;
    1354             :         int lut_size;
    1355             : 
    1356           0 :         if (params == NULL) {
    1357           0 :                 dpp3_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
    1358           0 :                 if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
    1359           0 :                         dpp3_power_on_hdr3dlut(dpp_base, false);
    1360             :                 return false;
    1361             :         }
    1362             : 
    1363           0 :         if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm)
    1364           0 :                 dpp3_power_on_hdr3dlut(dpp_base, true);
    1365             : 
    1366           0 :         mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
    1367             : 
    1368           0 :         if (mode == LUT_BYPASS || mode == LUT_RAM_B)
    1369             :                 mode = LUT_RAM_A;
    1370             :         else
    1371           0 :                 mode = LUT_RAM_B;
    1372             : 
    1373           0 :         is_17x17x17 = !params->use_tetrahedral_9;
    1374           0 :         is_12bits_color_channel = params->use_12bits;
    1375           0 :         if (is_17x17x17) {
    1376           0 :                 lut0 = params->tetrahedral_17.lut0;
    1377           0 :                 lut1 = params->tetrahedral_17.lut1;
    1378           0 :                 lut2 = params->tetrahedral_17.lut2;
    1379           0 :                 lut3 = params->tetrahedral_17.lut3;
    1380           0 :                 lut_size0 = sizeof(params->tetrahedral_17.lut0)/
    1381             :                                         sizeof(params->tetrahedral_17.lut0[0]);
    1382           0 :                 lut_size  = sizeof(params->tetrahedral_17.lut1)/
    1383             :                                         sizeof(params->tetrahedral_17.lut1[0]);
    1384             :         } else {
    1385           0 :                 lut0 = params->tetrahedral_9.lut0;
    1386           0 :                 lut1 = params->tetrahedral_9.lut1;
    1387           0 :                 lut2 = params->tetrahedral_9.lut2;
    1388           0 :                 lut3 = params->tetrahedral_9.lut3;
    1389           0 :                 lut_size0 = sizeof(params->tetrahedral_9.lut0)/
    1390             :                                 sizeof(params->tetrahedral_9.lut0[0]);
    1391           0 :                 lut_size  = sizeof(params->tetrahedral_9.lut1)/
    1392             :                                 sizeof(params->tetrahedral_9.lut1[0]);
    1393             :                 }
    1394             : 
    1395           0 :         dpp3_select_3dlut_ram(dpp_base, mode,
    1396             :                                 is_12bits_color_channel);
    1397           0 :         dpp3_select_3dlut_ram_mask(dpp_base, 0x1);
    1398           0 :         if (is_12bits_color_channel)
    1399           0 :                 dpp3_set3dlut_ram12(dpp_base, lut0, lut_size0);
    1400             :         else
    1401           0 :                 dpp3_set3dlut_ram10(dpp_base, lut0, lut_size0);
    1402             : 
    1403           0 :         dpp3_select_3dlut_ram_mask(dpp_base, 0x2);
    1404           0 :         if (is_12bits_color_channel)
    1405           0 :                 dpp3_set3dlut_ram12(dpp_base, lut1, lut_size);
    1406             :         else
    1407           0 :                 dpp3_set3dlut_ram10(dpp_base, lut1, lut_size);
    1408             : 
    1409           0 :         dpp3_select_3dlut_ram_mask(dpp_base, 0x4);
    1410           0 :         if (is_12bits_color_channel)
    1411           0 :                 dpp3_set3dlut_ram12(dpp_base, lut2, lut_size);
    1412             :         else
    1413           0 :                 dpp3_set3dlut_ram10(dpp_base, lut2, lut_size);
    1414             : 
    1415           0 :         dpp3_select_3dlut_ram_mask(dpp_base, 0x8);
    1416           0 :         if (is_12bits_color_channel)
    1417           0 :                 dpp3_set3dlut_ram12(dpp_base, lut3, lut_size);
    1418             :         else
    1419           0 :                 dpp3_set3dlut_ram10(dpp_base, lut3, lut_size);
    1420             : 
    1421             : 
    1422           0 :         dpp3_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
    1423             :                                         is_17x17x17);
    1424             : 
    1425           0 :         return true;
    1426             : }
    1427             : static struct dpp_funcs dcn30_dpp_funcs = {
    1428             :         .dpp_program_gamcor_lut = dpp3_program_gamcor_lut,
    1429             :         .dpp_read_state                 = dpp30_read_state,
    1430             :         .dpp_reset                      = dpp_reset,
    1431             :         .dpp_set_scaler                 = dpp1_dscl_set_scaler_manual_scale,
    1432             :         .dpp_get_optimal_number_of_taps = dpp3_get_optimal_number_of_taps,
    1433             :         .dpp_set_gamut_remap            = dpp3_cm_set_gamut_remap,
    1434             :         .dpp_set_csc_adjustment         = NULL,
    1435             :         .dpp_set_csc_default            = NULL,
    1436             :         .dpp_program_regamma_pwl        = NULL,
    1437             :         .dpp_set_pre_degam              = dpp3_set_pre_degam,
    1438             :         .dpp_program_input_lut          = NULL,
    1439             :         .dpp_full_bypass                = dpp1_full_bypass,
    1440             :         .dpp_setup                      = dpp3_cnv_setup,
    1441             :         .dpp_program_degamma_pwl        = NULL,
    1442             :         .dpp_program_cm_dealpha = dpp3_program_cm_dealpha,
    1443             :         .dpp_program_cm_bias = dpp3_program_cm_bias,
    1444             :         .dpp_program_blnd_lut = dpp3_program_blnd_lut,
    1445             :         .dpp_program_shaper_lut = dpp3_program_shaper,
    1446             :         .dpp_program_3dlut = dpp3_program_3dlut,
    1447             :         .dpp_deferred_update = dpp3_deferred_update,
    1448             :         .dpp_program_bias_and_scale     = NULL,
    1449             :         .dpp_cnv_set_alpha_keyer        = dpp2_cnv_set_alpha_keyer,
    1450             :         .set_cursor_attributes          = dpp3_set_cursor_attributes,
    1451             :         .set_cursor_position            = dpp1_set_cursor_position,
    1452             :         .set_optional_cursor_attributes = dpp1_cnv_set_optional_cursor_attributes,
    1453             :         .dpp_dppclk_control             = dpp1_dppclk_control,
    1454             :         .dpp_set_hdr_multiplier         = dpp3_set_hdr_multiplier,
    1455             : };
    1456             : 
    1457             : 
    1458             : static struct dpp_caps dcn30_dpp_cap = {
    1459             :         .dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT,
    1460             :         .dscl_calc_lb_num_partitions = dscl2_calc_lb_num_partitions,
    1461             : };
    1462             : 
    1463           0 : bool dpp3_construct(
    1464             :         struct dcn3_dpp *dpp,
    1465             :         struct dc_context *ctx,
    1466             :         uint32_t inst,
    1467             :         const struct dcn3_dpp_registers *tf_regs,
    1468             :         const struct dcn3_dpp_shift *tf_shift,
    1469             :         const struct dcn3_dpp_mask *tf_mask)
    1470             : {
    1471           0 :         dpp->base.ctx = ctx;
    1472             : 
    1473           0 :         dpp->base.inst = inst;
    1474           0 :         dpp->base.funcs = &dcn30_dpp_funcs;
    1475           0 :         dpp->base.caps = &dcn30_dpp_cap;
    1476             : 
    1477           0 :         dpp->tf_regs = tf_regs;
    1478           0 :         dpp->tf_shift = tf_shift;
    1479           0 :         dpp->tf_mask = tf_mask;
    1480             : 
    1481           0 :         return true;
    1482             : }
    1483             : 

Generated by: LCOV version 1.14