Line data Source code
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 0 : static void dpp2_enable_cm_block(
51 : struct dpp *dpp_base)
52 : {
53 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
54 :
55 0 : unsigned int cm_bypass_mode = 0;
56 : //Temp, put CM in bypass mode
57 0 : if (dpp_base->ctx->dc->debug.cm_in_bypass)
58 0 : cm_bypass_mode = 1;
59 :
60 0 : REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode);
61 0 : }
62 :
63 :
64 0 : static bool dpp2_degamma_ram_inuse(
65 : struct dpp *dpp_base,
66 : bool *ram_a_inuse)
67 : {
68 0 : bool ret = false;
69 0 : uint32_t status_reg = 0;
70 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
71 :
72 0 : REG_GET(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_CONFIG_STATUS,
73 : &status_reg);
74 :
75 0 : if (status_reg == 3) {
76 0 : *ram_a_inuse = true;
77 0 : ret = true;
78 0 : } else if (status_reg == 4) {
79 0 : *ram_a_inuse = false;
80 0 : ret = true;
81 : }
82 0 : return ret;
83 : }
84 :
85 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
94 0 : REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
95 : CM_DGAM_LUT_WRITE_EN_MASK, 7);
96 0 : REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL,
97 : is_ram_a == true ? 0:1);
98 :
99 0 : REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0);
100 0 : for (i = 0 ; i < num; i++) {
101 0 : REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg);
102 0 : REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg);
103 0 : REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg);
104 :
105 0 : REG_SET(CM_DGAM_LUT_DATA, 0,
106 : CM_DGAM_LUT_DATA, rgb[i].delta_red_reg);
107 0 : REG_SET(CM_DGAM_LUT_DATA, 0,
108 : CM_DGAM_LUT_DATA, rgb[i].delta_green_reg);
109 0 : REG_SET(CM_DGAM_LUT_DATA, 0,
110 : CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg);
111 :
112 : }
113 :
114 0 : }
115 :
116 0 : void dpp2_set_degamma_pwl(
117 : struct dpp *dpp_base,
118 : const struct pwl_params *params)
119 : {
120 0 : bool is_ram_a = true;
121 :
122 0 : dpp1_power_on_degamma_lut(dpp_base, true);
123 0 : dpp2_enable_cm_block(dpp_base);
124 0 : dpp2_degamma_ram_inuse(dpp_base, &is_ram_a);
125 0 : if (is_ram_a == true)
126 0 : dpp1_program_degamma_lutb_settings(dpp_base, params);
127 : else
128 0 : dpp1_program_degamma_luta_settings(dpp_base, params);
129 :
130 0 : dpp2_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a);
131 0 : dpp1_degamma_ram_select(dpp_base, !is_ram_a);
132 0 : }
133 :
134 0 : void dpp2_set_degamma(
135 : struct dpp *dpp_base,
136 : enum ipp_degamma_mode mode)
137 : {
138 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
139 0 : dpp2_enable_cm_block(dpp_base);
140 :
141 0 : switch (mode) {
142 : case IPP_DEGAMMA_MODE_BYPASS:
143 : /* Setting de gamma bypass for now */
144 0 : REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0);
145 0 : break;
146 : case IPP_DEGAMMA_MODE_HW_sRGB:
147 0 : REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1);
148 0 : break;
149 : case IPP_DEGAMMA_MODE_HW_xvYCC:
150 0 : REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2);
151 0 : break;
152 : case IPP_DEGAMMA_MODE_USER_PWL:
153 0 : REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
154 0 : break;
155 : default:
156 0 : BREAK_TO_DEBUGGER();
157 0 : break;
158 : }
159 0 : }
160 :
161 0 : static void program_gamut_remap(
162 : struct dcn20_dpp *dpp,
163 : const uint16_t *regval,
164 : enum dcn20_gamut_remap_select select)
165 : {
166 0 : uint32_t cur_select = 0;
167 : struct color_matrices_reg gam_regs;
168 :
169 0 : if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) {
170 0 : REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
171 : CM_GAMUT_REMAP_MODE, 0);
172 0 : 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 0 : 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 0 : if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
185 : select = DCN2_GAMUT_REMAP_COEF_A;
186 : else
187 0 : select = DCN2_GAMUT_REMAP_COEF_B;
188 :
189 0 : gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
190 0 : gam_regs.masks.csc_c11 = dpp->tf_mask->CM_GAMUT_REMAP_C11;
191 0 : gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
192 0 : gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
193 :
194 0 : if (select == DCN2_GAMUT_REMAP_COEF_A) {
195 0 : gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12);
196 0 : gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
197 : } else {
198 0 : gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12);
199 0 : gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34);
200 : }
201 :
202 0 : cm_helper_program_color_matrices(
203 : dpp->base.ctx,
204 : regval,
205 : &gam_regs);
206 :
207 0 : REG_SET(
208 : CM_GAMUT_REMAP_CONTROL, 0,
209 : CM_GAMUT_REMAP_MODE, select);
210 :
211 : }
212 :
213 0 : void dpp2_cm_set_gamut_remap(
214 : struct dpp *dpp_base,
215 : const struct dpp_grph_csc_adjustment *adjust)
216 : {
217 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
218 0 : int i = 0;
219 :
220 0 : if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
221 : /* Bypass if type is bypass or hw */
222 0 : 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 0 : for (i = 0; i < 12; i++)
228 0 : arr_matrix[i] = adjust->temperature_matrix[i];
229 :
230 0 : convert_float_matrix(
231 : arr_reg_val, arr_matrix, 12);
232 :
233 0 : program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A);
234 : }
235 0 : }
236 :
237 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
244 : int i;
245 0 : int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
246 0 : const uint16_t *regval = NULL;
247 0 : uint32_t cur_select = 0;
248 : enum dcn20_input_csc_select select;
249 : struct color_matrices_reg icsc_regs;
250 :
251 0 : if (input_select == DCN2_ICSC_SELECT_BYPASS) {
252 0 : REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
253 0 : return;
254 : }
255 :
256 0 : if (tbl_entry == NULL) {
257 0 : for (i = 0; i < arr_size; i++)
258 0 : if (dpp_input_csc_matrix[i].color_space == color_space) {
259 0 : regval = dpp_input_csc_matrix[i].regval;
260 0 : break;
261 : }
262 :
263 0 : if (regval == NULL) {
264 0 : BREAK_TO_DEBUGGER();
265 0 : return;
266 : }
267 : } else {
268 0 : 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 0 : 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 0 : if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
280 : select = DCN2_ICSC_SELECT_ICSC_A;
281 : else
282 0 : select = DCN2_ICSC_SELECT_ICSC_B;
283 :
284 0 : icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
285 0 : icsc_regs.masks.csc_c11 = dpp->tf_mask->CM_ICSC_C11;
286 0 : icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
287 0 : icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
288 :
289 0 : if (select == DCN2_ICSC_SELECT_ICSC_A) {
290 :
291 0 : icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
292 0 : icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
293 :
294 : } else {
295 :
296 0 : icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
297 0 : icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
298 :
299 : }
300 :
301 0 : cm_helper_program_color_matrices(
302 : dpp->base.ctx,
303 : regval,
304 : &icsc_regs);
305 :
306 0 : REG_SET(CM_ICSC_CONTROL, 0,
307 : CM_ICSC_MODE, select);
308 : }
309 :
310 0 : static void dpp20_power_on_blnd_lut(
311 : struct dpp *dpp_base,
312 : bool power_on)
313 : {
314 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
315 :
316 0 : REG_SET(CM_MEM_PWR_CTRL, 0,
317 : BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
318 :
319 0 : }
320 :
321 0 : static void dpp20_configure_blnd_lut(
322 : struct dpp *dpp_base,
323 : bool is_ram_a)
324 : {
325 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
326 :
327 0 : REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
328 : CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
329 0 : REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
330 : CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
331 0 : REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
332 0 : }
333 :
334 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
341 :
342 0 : for (i = 0 ; i < num; i++) {
343 0 : REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
344 0 : REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
345 0 : REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
346 :
347 0 : REG_SET(CM_BLNDGAM_LUT_DATA, 0,
348 : CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
349 0 : REG_SET(CM_BLNDGAM_LUT_DATA, 0,
350 : CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
351 0 : REG_SET(CM_BLNDGAM_LUT_DATA, 0,
352 : CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
353 :
354 : }
355 :
356 0 : }
357 :
358 0 : static void dcn20_dpp_cm_get_reg_field(
359 : struct dcn20_dpp *dpp,
360 : struct xfer_func_reg *reg)
361 : {
362 0 : reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
363 0 : reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
364 0 : reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
365 0 : reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
366 0 : reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
367 0 : reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
368 0 : reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
369 0 : reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
370 :
371 0 : reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
372 0 : reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
373 0 : reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
374 0 : reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
375 0 : reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
376 0 : reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
377 0 : reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
378 0 : reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
379 0 : reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
380 0 : reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
381 0 : reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
382 0 : reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
383 0 : }
384 :
385 : /*program blnd lut RAM A*/
386 0 : static void dpp20_program_blnd_luta_settings(
387 : struct dpp *dpp_base,
388 : const struct pwl_params *params)
389 : {
390 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
391 : struct xfer_func_reg gam_regs;
392 :
393 0 : dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
394 :
395 0 : gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
396 0 : gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
397 0 : gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
398 0 : gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
399 0 : gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
400 0 : gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
401 0 : gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
402 0 : gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
403 0 : gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
404 0 : gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
405 0 : gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
406 0 : gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
407 0 : gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
408 0 : gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
409 :
410 0 : cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
411 0 : }
412 :
413 : /*program blnd lut RAM B*/
414 0 : static void dpp20_program_blnd_lutb_settings(
415 : struct dpp *dpp_base,
416 : const struct pwl_params *params)
417 : {
418 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
419 : struct xfer_func_reg gam_regs;
420 :
421 0 : dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
422 :
423 0 : gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
424 0 : gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
425 0 : gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
426 0 : gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
427 0 : gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
428 0 : gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
429 0 : gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
430 0 : gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
431 0 : gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
432 0 : gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
433 0 : gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
434 0 : gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
435 0 : gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
436 0 : gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
437 :
438 0 : cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
439 0 : }
440 :
441 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
446 :
447 0 : REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK, CM_BLNDGAM_CONFIG_STATUS, &state_mode);
448 :
449 0 : switch (state_mode) {
450 : case 0:
451 : mode = LUT_BYPASS;
452 : break;
453 : case 1:
454 0 : mode = LUT_RAM_A;
455 0 : break;
456 : case 2:
457 0 : mode = LUT_RAM_B;
458 0 : break;
459 : default:
460 : mode = LUT_BYPASS;
461 : break;
462 : }
463 :
464 0 : return mode;
465 : }
466 :
467 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
473 :
474 0 : if (params == NULL) {
475 0 : REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
476 0 : return false;
477 : }
478 0 : current_mode = dpp20_get_blndgam_current(dpp_base);
479 0 : if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
480 : next_mode = LUT_RAM_B;
481 : else
482 0 : next_mode = LUT_RAM_A;
483 :
484 0 : dpp20_power_on_blnd_lut(dpp_base, true);
485 0 : dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
486 :
487 0 : if (next_mode == LUT_RAM_A)
488 0 : dpp20_program_blnd_luta_settings(dpp_base, params);
489 : else
490 0 : dpp20_program_blnd_lutb_settings(dpp_base, params);
491 :
492 0 : dpp20_program_blnd_pwl(
493 0 : dpp_base, params->rgb_resulted, params->hw_points_num);
494 :
495 0 : REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
496 : next_mode == LUT_RAM_A ? 1:2);
497 :
498 0 : return true;
499 : }
500 :
501 :
502 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
512 :
513 0 : for (i = 0 ; i < num; i++) {
514 :
515 0 : red = rgb[i].red_reg;
516 0 : green = rgb[i].green_reg;
517 0 : blue = rgb[i].blue_reg;
518 :
519 0 : red_delta = rgb[i].delta_red_reg;
520 0 : green_delta = rgb[i].delta_green_reg;
521 0 : blue_delta = rgb[i].delta_blue_reg;
522 :
523 0 : red_value = ((red_delta & 0x3ff) << 14) | (red & 0x3fff);
524 0 : green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
525 0 : blue_value = ((blue_delta & 0x3ff) << 14) | (blue & 0x3fff);
526 :
527 0 : REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
528 0 : REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
529 0 : REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
530 : }
531 :
532 0 : }
533 :
534 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
539 :
540 0 : REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK, CM_SHAPER_CONFIG_STATUS, &state_mode);
541 :
542 0 : switch (state_mode) {
543 : case 0:
544 : mode = LUT_BYPASS;
545 : break;
546 : case 1:
547 0 : mode = LUT_RAM_A;
548 0 : break;
549 : case 2:
550 0 : mode = LUT_RAM_B;
551 0 : break;
552 : default:
553 : mode = LUT_BYPASS;
554 : break;
555 : }
556 :
557 0 : return mode;
558 : }
559 :
560 0 : static void dpp20_configure_shaper_lut(
561 : struct dpp *dpp_base,
562 : bool is_ram_a)
563 : {
564 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
565 :
566 0 : REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
567 : CM_SHAPER_LUT_WRITE_EN_MASK, 7);
568 0 : REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
569 : CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
570 0 : REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
571 0 : }
572 :
573 : /*program shaper RAM A*/
574 :
575 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
581 :
582 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : curve = params->arr_curve_points;
605 0 : 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 0 : curve += 2;
612 0 : 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 0 : curve += 2;
619 0 : 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 0 : curve += 2;
626 0 : 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 0 : curve += 2;
633 0 : 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 0 : curve += 2;
640 0 : 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 0 : curve += 2;
647 0 : 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 0 : curve += 2;
654 0 : 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 0 : curve += 2;
661 0 : 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 0 : curve += 2;
668 0 : 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 0 : curve += 2;
675 0 : 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 0 : curve += 2;
682 0 : 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 0 : curve += 2;
689 0 : 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 0 : curve += 2;
696 0 : 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 0 : curve += 2;
703 0 : 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 0 : curve += 2;
710 0 : 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 0 : curve += 2;
717 0 : 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 0 : }
723 :
724 : /*program shaper RAM B*/
725 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
731 :
732 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : 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 0 : curve = params->arr_curve_points;
755 0 : 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 0 : curve += 2;
762 0 : 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 0 : curve += 2;
769 0 : 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 0 : curve += 2;
776 0 : 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 0 : curve += 2;
783 0 : 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 0 : curve += 2;
790 0 : 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 0 : curve += 2;
797 0 : 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 0 : curve += 2;
804 0 : 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 0 : curve += 2;
811 0 : 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 0 : curve += 2;
818 0 : 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 0 : curve += 2;
825 0 : 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 0 : curve += 2;
832 0 : 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 0 : curve += 2;
839 0 : 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 0 : curve += 2;
846 0 : 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 0 : curve += 2;
853 0 : 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 0 : curve += 2;
860 0 : 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 0 : curve += 2;
867 0 : 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 0 : }
874 :
875 :
876 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
884 :
885 0 : if (params == NULL) {
886 0 : REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
887 0 : return false;
888 : }
889 0 : current_mode = dpp20_get_shaper_current(dpp_base);
890 :
891 0 : if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
892 : next_mode = LUT_RAM_B;
893 : else
894 0 : next_mode = LUT_RAM_A;
895 :
896 0 : dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
897 :
898 0 : if (next_mode == LUT_RAM_A)
899 0 : dpp20_program_shaper_luta_settings(dpp_base, params);
900 : else
901 0 : dpp20_program_shaper_lutb_settings(dpp_base, params);
902 :
903 0 : dpp20_program_shaper_lut(
904 0 : dpp_base, params->rgb_resulted, params->hw_points_num);
905 :
906 0 : REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
907 :
908 0 : return true;
909 :
910 : }
911 :
912 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
920 :
921 0 : 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 0 : switch (i_mode) {
926 : case 0:
927 : mode = LUT_BYPASS;
928 : break;
929 : case 1:
930 0 : mode = LUT_RAM_A;
931 0 : break;
932 : case 2:
933 0 : mode = LUT_RAM_B;
934 0 : break;
935 : default:
936 : mode = LUT_BYPASS;
937 : break;
938 : }
939 0 : if (i_enable_10bits > 0)
940 0 : *is_12bits_color_channel = false;
941 : else
942 0 : *is_12bits_color_channel = true;
943 :
944 0 : REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
945 :
946 0 : if (lut_size == 0)
947 0 : *is_17x17x17 = true;
948 : else
949 0 : *is_17x17x17 = false;
950 :
951 0 : 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 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
966 :
967 0 : if (mode == LUT_BYPASS)
968 : lut_mode = 0;
969 0 : else if (mode == LUT_RAM_A)
970 : lut_mode = 1;
971 : else
972 0 : lut_mode = 2;
973 :
974 0 : REG_UPDATE_2(CM_3DLUT_MODE,
975 : CM_3DLUT_MODE, lut_mode,
976 : CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
977 0 : }
978 :
979 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
985 :
986 0 : 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 0 : }
991 :
992 :
993 :
994 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1001 :
1002 0 : for (i = 0 ; i < entries; i += 2) {
1003 0 : red = lut[i].red<<4;
1004 0 : green = lut[i].green<<4;
1005 0 : blue = lut[i].blue<<4;
1006 0 : red1 = lut[i+1].red<<4;
1007 0 : green1 = lut[i+1].green<<4;
1008 0 : blue1 = lut[i+1].blue<<4;
1009 :
1010 0 : REG_SET_2(CM_3DLUT_DATA, 0,
1011 : CM_3DLUT_DATA0, red,
1012 : CM_3DLUT_DATA1, red1);
1013 :
1014 0 : REG_SET_2(CM_3DLUT_DATA, 0,
1015 : CM_3DLUT_DATA0, green,
1016 : CM_3DLUT_DATA1, green1);
1017 :
1018 0 : REG_SET_2(CM_3DLUT_DATA, 0,
1019 : CM_3DLUT_DATA0, blue,
1020 : CM_3DLUT_DATA1, blue1);
1021 :
1022 : }
1023 0 : }
1024 :
1025 : /*
1026 : * load selected lut with 10 bits color channels
1027 : */
1028 0 : 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 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1035 :
1036 0 : for (i = 0; i < entries; i++) {
1037 0 : red = lut[i].red;
1038 0 : green = lut[i].green;
1039 0 : blue = lut[i].blue;
1040 :
1041 0 : value = (red<<20) | (green<<10) | blue;
1042 :
1043 0 : REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
1044 : }
1045 :
1046 0 : }
1047 :
1048 :
1049 0 : static void dpp20_select_3dlut_ram_mask(
1050 : struct dpp *dpp_base,
1051 : uint32_t ram_selection_mask)
1052 : {
1053 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1054 :
1055 0 : REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
1056 : ram_selection_mask);
1057 0 : REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
1058 0 : }
1059 :
1060 0 : 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 0 : if (params == NULL) {
1075 0 : dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
1076 0 : return false;
1077 : }
1078 0 : mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
1079 :
1080 0 : if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1081 : mode = LUT_RAM_A;
1082 : else
1083 0 : mode = LUT_RAM_B;
1084 :
1085 0 : is_17x17x17 = !params->use_tetrahedral_9;
1086 0 : is_12bits_color_channel = params->use_12bits;
1087 0 : if (is_17x17x17) {
1088 0 : lut0 = params->tetrahedral_17.lut0;
1089 0 : lut1 = params->tetrahedral_17.lut1;
1090 0 : lut2 = params->tetrahedral_17.lut2;
1091 0 : lut3 = params->tetrahedral_17.lut3;
1092 0 : lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1093 : sizeof(params->tetrahedral_17.lut0[0]);
1094 0 : lut_size = sizeof(params->tetrahedral_17.lut1)/
1095 : sizeof(params->tetrahedral_17.lut1[0]);
1096 : } else {
1097 0 : lut0 = params->tetrahedral_9.lut0;
1098 0 : lut1 = params->tetrahedral_9.lut1;
1099 0 : lut2 = params->tetrahedral_9.lut2;
1100 0 : lut3 = params->tetrahedral_9.lut3;
1101 0 : lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1102 : sizeof(params->tetrahedral_9.lut0[0]);
1103 0 : lut_size = sizeof(params->tetrahedral_9.lut1)/
1104 : sizeof(params->tetrahedral_9.lut1[0]);
1105 : }
1106 :
1107 0 : dpp20_select_3dlut_ram(dpp_base, mode,
1108 : is_12bits_color_channel);
1109 0 : dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
1110 0 : if (is_12bits_color_channel)
1111 0 : dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
1112 : else
1113 0 : dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
1114 :
1115 0 : dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
1116 0 : if (is_12bits_color_channel)
1117 0 : dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
1118 : else
1119 0 : dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
1120 :
1121 0 : dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
1122 0 : if (is_12bits_color_channel)
1123 0 : dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
1124 : else
1125 0 : dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
1126 :
1127 0 : dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
1128 0 : if (is_12bits_color_channel)
1129 0 : dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
1130 : else
1131 0 : dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
1132 :
1133 :
1134 0 : dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
1135 : is_17x17x17);
1136 :
1137 0 : return true;
1138 : }
1139 :
1140 0 : void dpp2_set_hdr_multiplier(
1141 : struct dpp *dpp_base,
1142 : uint32_t multiplier)
1143 : {
1144 0 : struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
1145 :
1146 0 : REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
1147 0 : }
|