drm/amd/display: Fix Dynamic bpp issue with 8K30 with Navi 1X
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / display / dc / dcn20 / dcn20_dpp_cm.c
1 /*
2  * Copyright 2016 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
28 #include "core_types.h"
29
30 #include "reg_helper.h"
31 #include "dcn20_dpp.h"
32 #include "basics/conversion.h"
33
34 #include "dcn10/dcn10_cm_common.h"
35
36 #define REG(reg)\
37         dpp->tf_regs->reg
38
39 #define IND_REG(index) \
40         (index)
41
42 #define CTX \
43         dpp->base.ctx
44
45 #undef FN
46 #define FN(reg_name, field_name) \
47         dpp->tf_shift->field_name, dpp->tf_mask->field_name
48
49
50 static void dpp2_enable_cm_block(
51                 struct dpp *dpp_base)
52 {
53         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
54
55         unsigned int cm_bypass_mode = 0;
56         //Temp, put CM in bypass mode
57         if (dpp_base->ctx->dc->debug.cm_in_bypass)
58                 cm_bypass_mode = 1;
59
60         REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode);
61 }
62
63
64 static bool dpp2_degamma_ram_inuse(
65                 struct dpp *dpp_base,
66                 bool *ram_a_inuse)
67 {
68         bool ret = false;
69         uint32_t status_reg = 0;
70         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
71
72         REG_GET(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_CONFIG_STATUS,
73                         &status_reg);
74
75         if (status_reg == 3) {
76                 *ram_a_inuse = true;
77                 ret = true;
78         } else if (status_reg == 4) {
79                 *ram_a_inuse = false;
80                 ret = true;
81         }
82         return ret;
83 }
84
85 static void dpp2_program_degamma_lut(
86                 struct dpp *dpp_base,
87                 const struct pwl_result_data *rgb,
88                 uint32_t num,
89                 bool is_ram_a)
90 {
91         uint32_t i;
92
93         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
94         REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
95                                 CM_DGAM_LUT_WRITE_EN_MASK, 7);
96         REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL,
97                                         is_ram_a == true ? 0:1);
98
99         REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0);
100         for (i = 0 ; i < num; i++) {
101                 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg);
102                 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg);
103                 REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg);
104
105                 REG_SET(CM_DGAM_LUT_DATA, 0,
106                                 CM_DGAM_LUT_DATA, rgb[i].delta_red_reg);
107                 REG_SET(CM_DGAM_LUT_DATA, 0,
108                                 CM_DGAM_LUT_DATA, rgb[i].delta_green_reg);
109                 REG_SET(CM_DGAM_LUT_DATA, 0,
110                                 CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg);
111
112         }
113
114 }
115
116 void dpp2_set_degamma_pwl(
117                 struct dpp *dpp_base,
118                 const struct pwl_params *params)
119 {
120         bool is_ram_a = true;
121
122         dpp1_power_on_degamma_lut(dpp_base, true);
123         dpp2_enable_cm_block(dpp_base);
124         dpp2_degamma_ram_inuse(dpp_base, &is_ram_a);
125         if (is_ram_a == true)
126                 dpp1_program_degamma_lutb_settings(dpp_base, params);
127         else
128                 dpp1_program_degamma_luta_settings(dpp_base, params);
129
130         dpp2_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a);
131         dpp1_degamma_ram_select(dpp_base, !is_ram_a);
132 }
133
134 void dpp2_set_degamma(
135                 struct dpp *dpp_base,
136                 enum ipp_degamma_mode mode)
137 {
138         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
139         dpp2_enable_cm_block(dpp_base);
140
141         switch (mode) {
142         case IPP_DEGAMMA_MODE_BYPASS:
143                 /* Setting de gamma bypass for now */
144                 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0);
145                 break;
146         case IPP_DEGAMMA_MODE_HW_sRGB:
147                 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1);
148                 break;
149         case IPP_DEGAMMA_MODE_HW_xvYCC:
150                 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2);
151                         break;
152         case IPP_DEGAMMA_MODE_USER_PWL:
153                 REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
154                 break;
155         default:
156                 BREAK_TO_DEBUGGER();
157                 break;
158         }
159 }
160
161 static void program_gamut_remap(
162                 struct dcn20_dpp *dpp,
163                 const uint16_t *regval,
164                 enum dcn20_gamut_remap_select select)
165 {
166         uint32_t cur_select = 0;
167         struct color_matrices_reg gam_regs;
168
169         if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) {
170                 REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
171                                 CM_GAMUT_REMAP_MODE, 0);
172                 return;
173         }
174
175         /* determine which gamut_remap coefficients (A or B) we are using
176          * currently. select the alternate set to double buffer
177          * the update so gamut_remap is updated on frame boundary
178          */
179         IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
180                                         CM_TEST_DEBUG_DATA_STATUS_IDX,
181                                         CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select);
182
183         /* value stored in dbg reg will be 1 greater than mode we want */
184         if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
185                 select = DCN2_GAMUT_REMAP_COEF_A;
186         else
187                 select = DCN2_GAMUT_REMAP_COEF_B;
188
189         gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
190         gam_regs.masks.csc_c11  = dpp->tf_mask->CM_GAMUT_REMAP_C11;
191         gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
192         gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
193
194         if (select == DCN2_GAMUT_REMAP_COEF_A) {
195                 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12);
196                 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
197         } else {
198                 gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12);
199                 gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34);
200         }
201
202         cm_helper_program_color_matrices(
203                                 dpp->base.ctx,
204                                 regval,
205                                 &gam_regs);
206
207         REG_SET(
208                         CM_GAMUT_REMAP_CONTROL, 0,
209                         CM_GAMUT_REMAP_MODE, select);
210
211 }
212
213 void dpp2_cm_set_gamut_remap(
214         struct dpp *dpp_base,
215         const struct dpp_grph_csc_adjustment *adjust)
216 {
217         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
218         int i = 0;
219
220         if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
221                 /* Bypass if type is bypass or hw */
222                 program_gamut_remap(dpp, NULL, DCN2_GAMUT_REMAP_BYPASS);
223         else {
224                 struct fixed31_32 arr_matrix[12];
225                 uint16_t arr_reg_val[12];
226
227                 for (i = 0; i < 12; i++)
228                         arr_matrix[i] = adjust->temperature_matrix[i];
229
230                 convert_float_matrix(
231                         arr_reg_val, arr_matrix, 12);
232
233                 program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A);
234         }
235 }
236
237 void dpp2_program_input_csc(
238                 struct dpp *dpp_base,
239                 enum dc_color_space color_space,
240                 enum dcn20_input_csc_select input_select,
241                 const struct out_csc_color_matrix *tbl_entry)
242 {
243         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
244         int i;
245         int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
246         const uint16_t *regval = NULL;
247         uint32_t cur_select = 0;
248         enum dcn20_input_csc_select select;
249         struct color_matrices_reg icsc_regs;
250
251         if (input_select == DCN2_ICSC_SELECT_BYPASS) {
252                 REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
253                 return;
254         }
255
256         if (tbl_entry == NULL) {
257                 for (i = 0; i < arr_size; i++)
258                         if (dpp_input_csc_matrix[i].color_space == color_space) {
259                                 regval = dpp_input_csc_matrix[i].regval;
260                                 break;
261                         }
262
263                 if (regval == NULL) {
264                         BREAK_TO_DEBUGGER();
265                         return;
266                 }
267         } else {
268                 regval = tbl_entry->regval;
269         }
270
271         /* determine which CSC coefficients (A or B) we are using
272          * currently.  select the alternate set to double buffer
273          * the CSC update so CSC is updated on frame boundary
274          */
275         IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
276                                         CM_TEST_DEBUG_DATA_STATUS_IDX,
277                                         CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);
278
279         if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
280                 select = DCN2_ICSC_SELECT_ICSC_A;
281         else
282                 select = DCN2_ICSC_SELECT_ICSC_B;
283
284         icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
285         icsc_regs.masks.csc_c11  = dpp->tf_mask->CM_ICSC_C11;
286         icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
287         icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
288
289         if (select == DCN2_ICSC_SELECT_ICSC_A) {
290
291                 icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
292                 icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
293
294         } else {
295
296                 icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
297                 icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
298
299         }
300
301         cm_helper_program_color_matrices(
302                         dpp->base.ctx,
303                         regval,
304                         &icsc_regs);
305
306         REG_SET(CM_ICSC_CONTROL, 0,
307                                 CM_ICSC_MODE, select);
308 }
309
310 static void dpp20_power_on_blnd_lut(
311         struct dpp *dpp_base,
312         bool power_on)
313 {
314         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
315
316         REG_SET(CM_MEM_PWR_CTRL, 0,
317                         BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
318
319 }
320
321 static void dpp20_configure_blnd_lut(
322                 struct dpp *dpp_base,
323                 bool is_ram_a)
324 {
325         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
326
327         REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
328                         CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
329         REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
330                         CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
331         REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
332 }
333
334 static void dpp20_program_blnd_pwl(
335                 struct dpp *dpp_base,
336                 const struct pwl_result_data *rgb,
337                 uint32_t num)
338 {
339         uint32_t i;
340         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
341
342         for (i = 0 ; i < num; i++) {
343                 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
344                 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
345                 REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
346
347                 REG_SET(CM_BLNDGAM_LUT_DATA, 0,
348                                 CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
349                 REG_SET(CM_BLNDGAM_LUT_DATA, 0,
350                                 CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
351                 REG_SET(CM_BLNDGAM_LUT_DATA, 0,
352                                 CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
353
354         }
355
356 }
357
358 static void dcn20_dpp_cm_get_reg_field(
359                 struct dcn20_dpp *dpp,
360                 struct xfer_func_reg *reg)
361 {
362         reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
363         reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
364         reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
365         reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
366         reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
367         reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
368         reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
369         reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
370
371         reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
372         reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
373         reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
374         reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
375         reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
376         reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
377         reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
378         reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
379         reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
380         reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
381         reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
382         reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
383 }
384
385 /*program blnd lut RAM A*/
386 static void dpp20_program_blnd_luta_settings(
387                 struct dpp *dpp_base,
388                 const struct pwl_params *params)
389 {
390         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
391         struct xfer_func_reg gam_regs;
392
393         dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
394
395         gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
396         gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
397         gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
398         gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
399         gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
400         gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
401         gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
402         gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
403         gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
404         gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
405         gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
406         gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
407         gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
408         gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
409
410         cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
411 }
412
413 /*program blnd lut RAM B*/
414 static void dpp20_program_blnd_lutb_settings(
415                 struct dpp *dpp_base,
416                 const struct pwl_params *params)
417 {
418         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
419         struct xfer_func_reg gam_regs;
420
421         dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
422
423         gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
424         gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
425         gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
426         gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
427         gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
428         gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
429         gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
430         gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
431         gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
432         gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
433         gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
434         gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
435         gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
436         gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
437
438         cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
439 }
440
441 static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base)
442 {
443         enum dc_lut_mode mode;
444         uint32_t state_mode;
445         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
446
447         REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK,
448                                         CM_BLNDGAM_CONFIG_STATUS, &state_mode);
449
450                 switch (state_mode) {
451                 case 0:
452                         mode = LUT_BYPASS;
453                         break;
454                 case 1:
455                         mode = LUT_RAM_A;
456                         break;
457                 case 2:
458                         mode = LUT_RAM_B;
459                         break;
460                 default:
461                         mode = LUT_BYPASS;
462                         break;
463                 }
464                 return mode;
465 }
466
467 bool dpp20_program_blnd_lut(
468         struct dpp *dpp_base, const struct pwl_params *params)
469 {
470         enum dc_lut_mode current_mode;
471         enum dc_lut_mode next_mode;
472         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
473
474         if (params == NULL) {
475                 REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
476                 return false;
477         }
478         current_mode = dpp20_get_blndgam_current(dpp_base);
479         if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
480                 next_mode = LUT_RAM_B;
481         else
482                 next_mode = LUT_RAM_A;
483
484         dpp20_power_on_blnd_lut(dpp_base, true);
485         dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
486
487         if (next_mode == LUT_RAM_A)
488                 dpp20_program_blnd_luta_settings(dpp_base, params);
489         else
490                 dpp20_program_blnd_lutb_settings(dpp_base, params);
491
492         dpp20_program_blnd_pwl(
493                         dpp_base, params->rgb_resulted, params->hw_points_num);
494
495         REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
496                         next_mode == LUT_RAM_A ? 1:2);
497
498         return true;
499 }
500
501
502 static void dpp20_program_shaper_lut(
503                 struct dpp *dpp_base,
504                 const struct pwl_result_data *rgb,
505                 uint32_t num)
506 {
507         uint32_t i, red, green, blue;
508         uint32_t  red_delta, green_delta, blue_delta;
509         uint32_t  red_value, green_value, blue_value;
510
511         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
512
513         for (i = 0 ; i < num; i++) {
514
515                 red   = rgb[i].red_reg;
516                 green = rgb[i].green_reg;
517                 blue  = rgb[i].blue_reg;
518
519                 red_delta   = rgb[i].delta_red_reg;
520                 green_delta = rgb[i].delta_green_reg;
521                 blue_delta  = rgb[i].delta_blue_reg;
522
523                 red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
524                 green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
525                 blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
526
527                 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
528                 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
529                 REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
530         }
531
532 }
533
534 static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base)
535 {
536         enum dc_lut_mode mode;
537         uint32_t state_mode;
538         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
539
540         REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK,
541                         CM_SHAPER_CONFIG_STATUS, &state_mode);
542
543                 switch (state_mode) {
544                 case 0:
545                         mode = LUT_BYPASS;
546                         break;
547                 case 1:
548                         mode = LUT_RAM_A;
549                         break;
550                 case 2:
551                         mode = LUT_RAM_B;
552                         break;
553                 default:
554                         mode = LUT_BYPASS;
555                         break;
556                 }
557                 return mode;
558 }
559
560 static void dpp20_configure_shaper_lut(
561                 struct dpp *dpp_base,
562                 bool is_ram_a)
563 {
564         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
565
566         REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
567                         CM_SHAPER_LUT_WRITE_EN_MASK, 7);
568         REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
569                         CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
570         REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
571 }
572
573 /*program shaper RAM A*/
574
575 static void dpp20_program_shaper_luta_settings(
576                 struct dpp *dpp_base,
577                 const struct pwl_params *params)
578 {
579         const struct gamma_curve *curve;
580         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
581
582         REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
583                 CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
584                 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
585         REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
586                 CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
587                 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
588         REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
589                 CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
590                 CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
591
592         REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
593                 CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
594                 CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
595
596         REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
597                 CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
598                 CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
599
600         REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
601                 CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
602                 CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
603
604         curve = params->arr_curve_points;
605         REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
606                 CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
607                 CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
608                 CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
609                 CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
610
611         curve += 2;
612         REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
613                 CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
614                 CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
615                 CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
616                 CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
617
618         curve += 2;
619         REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
620                 CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
621                 CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
622                 CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
623                 CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
624
625         curve += 2;
626         REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
627                 CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
628                 CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
629                 CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
630                 CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
631
632         curve += 2;
633         REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
634                 CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
635                 CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
636                 CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
637                 CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
638
639         curve += 2;
640         REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
641                 CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
642                 CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
643                 CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
644                 CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
645
646         curve += 2;
647         REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
648                 CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
649                 CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
650                 CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
651                 CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
652
653         curve += 2;
654         REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
655                 CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
656                 CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
657                 CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
658                 CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
659
660         curve += 2;
661         REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
662                 CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
663                 CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
664                 CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
665                 CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
666
667         curve += 2;
668         REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
669                 CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
670                 CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
671                 CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
672                 CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
673
674         curve += 2;
675         REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
676                 CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
677                 CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
678                 CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
679                 CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
680
681         curve += 2;
682         REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
683                 CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
684                 CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
685                 CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
686                 CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
687
688         curve += 2;
689         REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
690                 CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
691                 CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
692                 CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
693                 CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
694
695         curve += 2;
696         REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
697                 CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
698                 CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
699                 CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
700                 CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
701
702         curve += 2;
703         REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
704                 CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
705                 CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
706                 CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
707                 CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
708
709         curve += 2;
710         REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
711                 CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
712                 CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
713                 CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
714                 CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
715
716         curve += 2;
717         REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
718                 CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
719                 CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
720                 CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
721                 CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
722 }
723
724 /*program shaper RAM B*/
725 static void dpp20_program_shaper_lutb_settings(
726                 struct dpp *dpp_base,
727                 const struct pwl_params *params)
728 {
729         const struct gamma_curve *curve;
730         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
731
732         REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
733                 CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
734                 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
735         REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
736                 CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
737                 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
738         REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
739                 CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
740                 CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
741
742         REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
743                 CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
744                 CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
745
746         REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
747                 CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
748                 CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
749
750         REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
751                 CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
752                 CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
753
754         curve = params->arr_curve_points;
755         REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
756                 CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
757                 CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
758                 CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
759                 CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
760
761         curve += 2;
762         REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
763                 CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
764                 CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
765                 CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
766                 CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
767
768         curve += 2;
769         REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
770                 CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
771                 CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
772                 CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
773                 CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
774
775         curve += 2;
776         REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
777                 CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
778                 CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
779                 CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
780                 CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
781
782         curve += 2;
783         REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
784                 CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
785                 CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
786                 CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
787                 CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
788
789         curve += 2;
790         REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
791                 CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
792                 CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
793                 CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
794                 CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
795
796         curve += 2;
797         REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
798                 CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
799                 CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
800                 CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
801                 CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
802
803         curve += 2;
804         REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
805                 CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
806                 CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
807                 CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
808                 CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
809
810         curve += 2;
811         REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
812                 CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
813                 CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
814                 CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
815                 CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
816
817         curve += 2;
818         REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
819                 CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
820                 CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
821                 CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
822                 CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
823
824         curve += 2;
825         REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
826                 CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
827                 CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
828                 CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
829                 CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
830
831         curve += 2;
832         REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
833                 CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
834                 CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
835                 CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
836                 CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
837
838         curve += 2;
839         REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
840                 CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
841                 CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
842                 CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
843                 CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
844
845         curve += 2;
846         REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
847                 CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
848                 CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
849                 CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
850                 CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
851
852         curve += 2;
853         REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
854                 CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
855                 CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
856                 CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
857                 CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
858
859         curve += 2;
860         REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
861                 CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
862                 CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
863                 CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
864                 CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
865
866         curve += 2;
867         REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
868                 CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
869                 CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
870                 CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
871                 CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
872
873 }
874
875
876 bool dpp20_program_shaper(
877                 struct dpp *dpp_base,
878                 const struct pwl_params *params)
879 {
880         enum dc_lut_mode current_mode;
881         enum dc_lut_mode next_mode;
882
883         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
884
885         if (params == NULL) {
886                 REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
887                 return false;
888         }
889         current_mode = dpp20_get_shaper_current(dpp_base);
890
891         if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
892                 next_mode = LUT_RAM_B;
893         else
894                 next_mode = LUT_RAM_A;
895
896         dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
897
898         if (next_mode == LUT_RAM_A)
899                 dpp20_program_shaper_luta_settings(dpp_base, params);
900         else
901                 dpp20_program_shaper_lutb_settings(dpp_base, params);
902
903         dpp20_program_shaper_lut(
904                         dpp_base, params->rgb_resulted, params->hw_points_num);
905
906         REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
907
908         return true;
909
910 }
911
912 static enum dc_lut_mode get3dlut_config(
913                         struct dpp *dpp_base,
914                         bool *is_17x17x17,
915                         bool *is_12bits_color_channel)
916 {
917         uint32_t i_mode, i_enable_10bits, lut_size;
918         enum dc_lut_mode mode;
919         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
920
921         REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL,
922                         CM_3DLUT_CONFIG_STATUS, &i_mode,
923                         CM_3DLUT_30BIT_EN, &i_enable_10bits);
924
925         switch (i_mode) {
926         case 0:
927                 mode = LUT_BYPASS;
928                 break;
929         case 1:
930                 mode = LUT_RAM_A;
931                 break;
932         case 2:
933                 mode = LUT_RAM_B;
934                 break;
935         default:
936                 mode = LUT_BYPASS;
937                 break;
938         }
939         if (i_enable_10bits > 0)
940                 *is_12bits_color_channel = false;
941         else
942                 *is_12bits_color_channel = true;
943
944         REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
945
946         if (lut_size == 0)
947                 *is_17x17x17 = true;
948         else
949                 *is_17x17x17 = false;
950
951         return mode;
952 }
953 /*
954  * select ramA or ramB, or bypass
955  * select color channel size 10 or 12 bits
956  * select 3dlut size 17x17x17 or 9x9x9
957  */
958 static void dpp20_set_3dlut_mode(
959                 struct dpp *dpp_base,
960                 enum dc_lut_mode mode,
961                 bool is_color_channel_12bits,
962                 bool is_lut_size17x17x17)
963 {
964         uint32_t lut_mode;
965         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
966
967         if (mode == LUT_BYPASS)
968                 lut_mode = 0;
969         else if (mode == LUT_RAM_A)
970                 lut_mode = 1;
971         else
972                 lut_mode = 2;
973
974         REG_UPDATE_2(CM_3DLUT_MODE,
975                         CM_3DLUT_MODE, lut_mode,
976                         CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
977 }
978
979 static void dpp20_select_3dlut_ram(
980                 struct dpp *dpp_base,
981                 enum dc_lut_mode mode,
982                 bool is_color_channel_12bits)
983 {
984         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
985
986         REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
987                         CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
988                         CM_3DLUT_30BIT_EN,
989                         is_color_channel_12bits == true ? 0:1);
990 }
991
992
993
994 static void dpp20_set3dlut_ram12(
995                 struct dpp *dpp_base,
996                 const struct dc_rgb *lut,
997                 uint32_t entries)
998 {
999         uint32_t i, red, green, blue, red1, green1, blue1;
1000         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1001
1002         for (i = 0 ; i < entries; i += 2) {
1003                 red   = lut[i].red<<4;
1004                 green = lut[i].green<<4;
1005                 blue  = lut[i].blue<<4;
1006                 red1   = lut[i+1].red<<4;
1007                 green1 = lut[i+1].green<<4;
1008                 blue1  = lut[i+1].blue<<4;
1009
1010                 REG_SET_2(CM_3DLUT_DATA, 0,
1011                                 CM_3DLUT_DATA0, red,
1012                                 CM_3DLUT_DATA1, red1);
1013
1014                 REG_SET_2(CM_3DLUT_DATA, 0,
1015                                 CM_3DLUT_DATA0, green,
1016                                 CM_3DLUT_DATA1, green1);
1017
1018                 REG_SET_2(CM_3DLUT_DATA, 0,
1019                                 CM_3DLUT_DATA0, blue,
1020                                 CM_3DLUT_DATA1, blue1);
1021
1022         }
1023 }
1024
1025 /*
1026  * load selected lut with 10 bits color channels
1027  */
1028 static void dpp20_set3dlut_ram10(
1029                 struct dpp *dpp_base,
1030                 const struct dc_rgb *lut,
1031                 uint32_t entries)
1032 {
1033         uint32_t i, red, green, blue, value;
1034         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1035
1036         for (i = 0; i < entries; i++) {
1037                 red   = lut[i].red;
1038                 green = lut[i].green;
1039                 blue  = lut[i].blue;
1040
1041                 value = (red<<20) | (green<<10) | blue;
1042
1043                 REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
1044         }
1045
1046 }
1047
1048
1049 static void dpp20_select_3dlut_ram_mask(
1050                 struct dpp *dpp_base,
1051                 uint32_t ram_selection_mask)
1052 {
1053         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1054
1055         REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
1056                         ram_selection_mask);
1057         REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
1058 }
1059
1060 bool dpp20_program_3dlut(
1061                 struct dpp *dpp_base,
1062                 struct tetrahedral_params *params)
1063 {
1064         enum dc_lut_mode mode;
1065         bool is_17x17x17;
1066         bool is_12bits_color_channel;
1067         struct dc_rgb *lut0;
1068         struct dc_rgb *lut1;
1069         struct dc_rgb *lut2;
1070         struct dc_rgb *lut3;
1071         int lut_size0;
1072         int lut_size;
1073
1074         if (params == NULL) {
1075                 dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
1076                 return false;
1077         }
1078         mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
1079
1080         if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1081                 mode = LUT_RAM_A;
1082         else
1083                 mode = LUT_RAM_B;
1084
1085         is_17x17x17 = !params->use_tetrahedral_9;
1086         is_12bits_color_channel = params->use_12bits;
1087         if (is_17x17x17) {
1088                 lut0 = params->tetrahedral_17.lut0;
1089                 lut1 = params->tetrahedral_17.lut1;
1090                 lut2 = params->tetrahedral_17.lut2;
1091                 lut3 = params->tetrahedral_17.lut3;
1092                 lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1093                                         sizeof(params->tetrahedral_17.lut0[0]);
1094                 lut_size  = sizeof(params->tetrahedral_17.lut1)/
1095                                         sizeof(params->tetrahedral_17.lut1[0]);
1096         } else {
1097                 lut0 = params->tetrahedral_9.lut0;
1098                 lut1 = params->tetrahedral_9.lut1;
1099                 lut2 = params->tetrahedral_9.lut2;
1100                 lut3 = params->tetrahedral_9.lut3;
1101                 lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1102                                 sizeof(params->tetrahedral_9.lut0[0]);
1103                 lut_size  = sizeof(params->tetrahedral_9.lut1)/
1104                                 sizeof(params->tetrahedral_9.lut1[0]);
1105                 }
1106
1107         dpp20_select_3dlut_ram(dpp_base, mode,
1108                                 is_12bits_color_channel);
1109         dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
1110         if (is_12bits_color_channel)
1111                 dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
1112         else
1113                 dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
1114
1115         dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
1116         if (is_12bits_color_channel)
1117                 dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
1118         else
1119                 dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
1120
1121         dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
1122         if (is_12bits_color_channel)
1123                 dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
1124         else
1125                 dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
1126
1127         dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
1128         if (is_12bits_color_channel)
1129                 dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
1130         else
1131                 dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
1132
1133
1134         dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
1135                                         is_17x17x17);
1136
1137         return true;
1138 }
1139
1140 void dpp2_set_hdr_multiplier(
1141                 struct dpp *dpp_base,
1142                 uint32_t multiplier)
1143 {
1144         struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1145
1146         REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
1147 }