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