1 /*
2 * Copyright 2023 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 "reg_helper.h"
27 #include "dc.h"
28 #include "dcn401_mpc.h"
29 #include "dcn10/dcn10_cm_common.h"
30 #include "basics/conversion.h"
31 #include "mpc.h"
32
33 #define REG(reg)\
34 mpc401->mpc_regs->reg
35
36 #define CTX \
37 mpc401->base.ctx
38
39 #undef FN
40 #define FN(reg_name, field_name) \
41 mpc401->mpc_shift->field_name, mpc401->mpc_mask->field_name
42
mpc401_update_3dlut_fast_load_select(struct mpc * mpc,int mpcc_id,int hubp_idx)43 static void mpc401_update_3dlut_fast_load_select(struct mpc *mpc, int mpcc_id, int hubp_idx)
44 {
45 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
46
47 REG_SET(MPCC_MCM_3DLUT_FAST_LOAD_SELECT[mpcc_id], 0, MPCC_MCM_3DLUT_FL_SEL, hubp_idx);
48 }
49
mpc401_get_3dlut_fast_load_status(struct mpc * mpc,int mpcc_id,uint32_t * done,uint32_t * soft_underflow,uint32_t * hard_underflow)50 static void mpc401_get_3dlut_fast_load_status(struct mpc *mpc, int mpcc_id, uint32_t *done, uint32_t *soft_underflow, uint32_t *hard_underflow)
51 {
52 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
53
54 REG_GET_3(MPCC_MCM_3DLUT_FAST_LOAD_STATUS[mpcc_id],
55 MPCC_MCM_3DLUT_FL_DONE, done,
56 MPCC_MCM_3DLUT_FL_SOFT_UNDERFLOW, soft_underflow,
57 MPCC_MCM_3DLUT_FL_HARD_UNDERFLOW, hard_underflow);
58 }
59
mpc401_set_movable_cm_location(struct mpc * mpc,enum mpcc_movable_cm_location location,int mpcc_id)60 void mpc401_set_movable_cm_location(struct mpc *mpc, enum mpcc_movable_cm_location location, int mpcc_id)
61 {
62 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
63
64 switch (location) {
65 case MPCC_MOVABLE_CM_LOCATION_BEFORE:
66 REG_UPDATE(MPCC_MOVABLE_CM_LOCATION_CONTROL[mpcc_id],
67 MPCC_MOVABLE_CM_LOCATION_CNTL, 0);
68 break;
69 case MPCC_MOVABLE_CM_LOCATION_AFTER:
70 REG_UPDATE(MPCC_MOVABLE_CM_LOCATION_CONTROL[mpcc_id],
71 MPCC_MOVABLE_CM_LOCATION_CNTL, 1);
72 break;
73 }
74 }
75
get3dlut_config(struct mpc * mpc,bool * is_17x17x17,bool * is_12bits_color_channel,int mpcc_id)76 static enum dc_lut_mode get3dlut_config(
77 struct mpc *mpc,
78 bool *is_17x17x17,
79 bool *is_12bits_color_channel,
80 int mpcc_id)
81 {
82 uint32_t i_mode, i_enable_10bits, lut_size;
83 enum dc_lut_mode mode;
84 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
85
86 REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
87 MPCC_MCM_3DLUT_MODE_CURRENT, &i_mode);
88
89 REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
90 MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
91
92 switch (i_mode) {
93 case 0:
94 mode = LUT_BYPASS;
95 break;
96 case 1:
97 mode = LUT_RAM_A;
98 break;
99 case 2:
100 mode = LUT_RAM_B;
101 break;
102 default:
103 mode = LUT_BYPASS;
104 break;
105 }
106 if (i_enable_10bits > 0)
107 *is_12bits_color_channel = false;
108 else
109 *is_12bits_color_channel = true;
110
111 REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
112
113 if (lut_size == 0)
114 *is_17x17x17 = true;
115 else
116 *is_17x17x17 = false;
117
118 return mode;
119 }
120
mpc401_populate_lut(struct mpc * mpc,const enum MCM_LUT_ID id,const union mcm_lut_params params,bool lut_bank_a,int mpcc_id)121 void mpc401_populate_lut(struct mpc *mpc, const enum MCM_LUT_ID id, const union mcm_lut_params params, bool lut_bank_a, int mpcc_id)
122 {
123 const enum dc_lut_mode next_mode = lut_bank_a ? LUT_RAM_A : LUT_RAM_B;
124 const struct pwl_params *lut1d = params.pwl;
125 const struct pwl_params *lut_shaper = params.pwl;
126 bool is_17x17x17;
127 bool is_12bits_color_channel;
128 const struct dc_rgb *lut0;
129 const struct dc_rgb *lut1;
130 const struct dc_rgb *lut2;
131 const struct dc_rgb *lut3;
132 int lut_size0;
133 int lut_size;
134 const struct tetrahedral_params *lut3d = params.lut3d;
135
136 switch (id) {
137 case MCM_LUT_1DLUT:
138 if (lut1d == NULL)
139 return;
140
141 mpc32_power_on_blnd_lut(mpc, mpcc_id, true);
142 mpc32_configure_post1dlut(mpc, mpcc_id, next_mode == LUT_RAM_A);
143
144 if (next_mode == LUT_RAM_A)
145 mpc32_program_post1dluta_settings(mpc, mpcc_id, lut1d);
146 else
147 mpc32_program_post1dlutb_settings(mpc, mpcc_id, lut1d);
148
149 mpc32_program_post1dlut_pwl(
150 mpc, mpcc_id, lut1d->rgb_resulted, lut1d->hw_points_num);
151
152 break;
153 case MCM_LUT_SHAPER:
154 if (lut_shaper == NULL)
155 return;
156 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
157 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
158
159 mpc32_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id);
160
161 if (next_mode == LUT_RAM_A)
162 mpc32_program_shaper_luta_settings(mpc, lut_shaper, mpcc_id);
163 else
164 mpc32_program_shaper_lutb_settings(mpc, lut_shaper, mpcc_id);
165
166 mpc32_program_shaper_lut(
167 mpc, lut_shaper->rgb_resulted, lut_shaper->hw_points_num, mpcc_id);
168
169 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
170 break;
171 case MCM_LUT_3DLUT:
172 if (lut3d == NULL)
173 return;
174
175 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
176
177 get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id);
178
179 is_17x17x17 = !lut3d->use_tetrahedral_9;
180 is_12bits_color_channel = lut3d->use_12bits;
181 if (is_17x17x17) {
182 lut0 = lut3d->tetrahedral_17.lut0;
183 lut1 = lut3d->tetrahedral_17.lut1;
184 lut2 = lut3d->tetrahedral_17.lut2;
185 lut3 = lut3d->tetrahedral_17.lut3;
186 lut_size0 = sizeof(lut3d->tetrahedral_17.lut0)/
187 sizeof(lut3d->tetrahedral_17.lut0[0]);
188 lut_size = sizeof(lut3d->tetrahedral_17.lut1)/
189 sizeof(lut3d->tetrahedral_17.lut1[0]);
190 } else {
191 lut0 = lut3d->tetrahedral_9.lut0;
192 lut1 = lut3d->tetrahedral_9.lut1;
193 lut2 = lut3d->tetrahedral_9.lut2;
194 lut3 = lut3d->tetrahedral_9.lut3;
195 lut_size0 = sizeof(lut3d->tetrahedral_9.lut0)/
196 sizeof(lut3d->tetrahedral_9.lut0[0]);
197 lut_size = sizeof(lut3d->tetrahedral_9.lut1)/
198 sizeof(lut3d->tetrahedral_9.lut1[0]);
199 }
200
201 mpc32_select_3dlut_ram(mpc, next_mode,
202 is_12bits_color_channel, mpcc_id);
203 mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
204 if (is_12bits_color_channel)
205 mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
206 else
207 mpc32_set3dlut_ram10(mpc, lut0, lut_size0, mpcc_id);
208
209 mpc32_select_3dlut_ram_mask(mpc, 0x2, mpcc_id);
210 if (is_12bits_color_channel)
211 mpc32_set3dlut_ram12(mpc, lut1, lut_size, mpcc_id);
212 else
213 mpc32_set3dlut_ram10(mpc, lut1, lut_size, mpcc_id);
214
215 mpc32_select_3dlut_ram_mask(mpc, 0x4, mpcc_id);
216 if (is_12bits_color_channel)
217 mpc32_set3dlut_ram12(mpc, lut2, lut_size, mpcc_id);
218 else
219 mpc32_set3dlut_ram10(mpc, lut2, lut_size, mpcc_id);
220
221 mpc32_select_3dlut_ram_mask(mpc, 0x8, mpcc_id);
222 if (is_12bits_color_channel)
223 mpc32_set3dlut_ram12(mpc, lut3, lut_size, mpcc_id);
224 else
225 mpc32_set3dlut_ram10(mpc, lut3, lut_size, mpcc_id);
226
227 if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
228 mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
229
230 break;
231 }
232
233 }
234
mpc401_program_lut_mode(struct mpc * mpc,const enum MCM_LUT_ID id,const enum MCM_LUT_XABLE xable,bool lut_bank_a,int mpcc_id)235 void mpc401_program_lut_mode(
236 struct mpc *mpc,
237 const enum MCM_LUT_ID id,
238 const enum MCM_LUT_XABLE xable,
239 bool lut_bank_a,
240 int mpcc_id)
241 {
242 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
243
244 switch (id) {
245 case MCM_LUT_3DLUT:
246 switch (xable) {
247 case MCM_LUT_DISABLE:
248 REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, 0);
249 break;
250 case MCM_LUT_ENABLE:
251 REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_MODE, lut_bank_a ? 1 : 2);
252 break;
253 }
254 break;
255 case MCM_LUT_SHAPER:
256 switch (xable) {
257 case MCM_LUT_DISABLE:
258 REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, 0);
259 break;
260 case MCM_LUT_ENABLE:
261 REG_UPDATE(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_LUT_MODE, lut_bank_a ? 1 : 2);
262 break;
263 }
264 break;
265 case MCM_LUT_1DLUT:
266 switch (xable) {
267 case MCM_LUT_DISABLE:
268 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
269 MPCC_MCM_1DLUT_MODE, 0);
270 break;
271 case MCM_LUT_ENABLE:
272 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
273 MPCC_MCM_1DLUT_MODE, 2);
274 break;
275 }
276 REG_UPDATE(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
277 MPCC_MCM_1DLUT_SELECT, lut_bank_a ? 0 : 1);
278 break;
279 }
280 }
281
mpc401_program_lut_read_write_control(struct mpc * mpc,const enum MCM_LUT_ID id,bool lut_bank_a,int mpcc_id)282 void mpc401_program_lut_read_write_control(struct mpc *mpc, const enum MCM_LUT_ID id, bool lut_bank_a, int mpcc_id)
283 {
284 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
285
286 switch (id) {
287 case MCM_LUT_3DLUT:
288 mpc32_select_3dlut_ram_mask(mpc, 0xf, mpcc_id);
289 REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_RAM_SEL, lut_bank_a ? 0 : 1);
290 break;
291 case MCM_LUT_SHAPER:
292 mpc32_configure_shaper_lut(mpc, lut_bank_a, mpcc_id);
293 break;
294 case MCM_LUT_1DLUT:
295 mpc32_configure_post1dlut(mpc, lut_bank_a, mpcc_id);
296 break;
297 }
298 }
299
mpc401_program_3dlut_size(struct mpc * mpc,bool is_17x17x17,int mpcc_id)300 void mpc401_program_3dlut_size(struct mpc *mpc, bool is_17x17x17, int mpcc_id)
301 {
302 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
303
304 REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, is_17x17x17 ? 0 : 1);
305 }
306
program_gamut_remap(struct mpc * mpc,unsigned int mpcc_id,const uint16_t * regval,enum mpcc_gamut_remap_id gamut_remap_block_id,enum mpcc_gamut_remap_mode_select mode_select)307 static void program_gamut_remap(
308 struct mpc *mpc,
309 unsigned int mpcc_id,
310 const uint16_t *regval,
311 enum mpcc_gamut_remap_id gamut_remap_block_id,
312 enum mpcc_gamut_remap_mode_select mode_select)
313 {
314 struct color_matrices_reg gamut_regs;
315 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
316
317 switch (gamut_remap_block_id) {
318 case MPCC_OGAM_GAMUT_REMAP:
319
320 if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
321 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0,
322 MPCC_GAMUT_REMAP_MODE, mode_select);
323 return;
324 }
325
326 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
327 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
328 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
329 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
330
331 switch (mode_select) {
332 case MPCC_GAMUT_REMAP_MODE_SELECT_1:
333 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]);
334 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]);
335 break;
336 case MPCC_GAMUT_REMAP_MODE_SELECT_2:
337 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]);
338 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]);
339 break;
340 default:
341 break;
342 }
343
344 cm_helper_program_color_matrices(
345 mpc->ctx,
346 regval,
347 &gamut_regs);
348
349 //select coefficient set to use, set A (MODE_1) or set B (MODE_2)
350 REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, MPCC_GAMUT_REMAP_MODE, mode_select);
351 break;
352
353 case MPCC_MCM_FIRST_GAMUT_REMAP:
354 if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
355 REG_SET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 0,
356 MPCC_MCM_FIRST_GAMUT_REMAP_MODE, mode_select);
357 return;
358 }
359
360 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
361 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
362 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
363 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
364
365 switch (mode_select) {
366 case MPCC_GAMUT_REMAP_MODE_SELECT_1:
367 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_A[mpcc_id]);
368 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_A[mpcc_id]);
369 break;
370 case MPCC_GAMUT_REMAP_MODE_SELECT_2:
371 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_B[mpcc_id]);
372 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_B[mpcc_id]);
373 break;
374 default:
375 break;
376 }
377
378 cm_helper_program_color_matrices(
379 mpc->ctx,
380 regval,
381 &gamut_regs);
382
383 //select coefficient set to use, set A (MODE_1) or set B (MODE_2)
384 REG_SET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 0,
385 MPCC_MCM_FIRST_GAMUT_REMAP_MODE, mode_select);
386 break;
387
388 case MPCC_MCM_SECOND_GAMUT_REMAP:
389 if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
390 REG_SET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 0,
391 MPCC_MCM_SECOND_GAMUT_REMAP_MODE, mode_select);
392 return;
393 }
394
395 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
396 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
397 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
398 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
399
400 switch (mode_select) {
401 case MPCC_GAMUT_REMAP_MODE_SELECT_1:
402 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_A[mpcc_id]);
403 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_A[mpcc_id]);
404 break;
405 case MPCC_GAMUT_REMAP_MODE_SELECT_2:
406 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_B[mpcc_id]);
407 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[mpcc_id]);
408 break;
409 default:
410 break;
411 }
412
413 cm_helper_program_color_matrices(
414 mpc->ctx,
415 regval,
416 &gamut_regs);
417
418 //select coefficient set to use, set A (MODE_1) or set B (MODE_2)
419 REG_SET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 0,
420 MPCC_MCM_SECOND_GAMUT_REMAP_MODE, mode_select);
421 break;
422
423 default:
424 break;
425 }
426 }
427
mpc401_set_gamut_remap(struct mpc * mpc,int mpcc_id,const struct mpc_grph_gamut_adjustment * adjust)428 void mpc401_set_gamut_remap(
429 struct mpc *mpc,
430 int mpcc_id,
431 const struct mpc_grph_gamut_adjustment *adjust)
432 {
433 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
434 unsigned int i = 0;
435 uint32_t mode_select = 0;
436
437 if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) {
438 /* Bypass / Disable if type is bypass or hw */
439 program_gamut_remap(mpc, mpcc_id, NULL,
440 adjust->mpcc_gamut_remap_block_id, MPCC_GAMUT_REMAP_MODE_SELECT_0);
441 } else {
442 struct fixed31_32 arr_matrix[12];
443 uint16_t arr_reg_val[12];
444
445 for (i = 0; i < 12; i++)
446 arr_matrix[i] = adjust->temperature_matrix[i];
447
448 convert_float_matrix(arr_reg_val, arr_matrix, 12);
449
450 switch (adjust->mpcc_gamut_remap_block_id) {
451 case MPCC_OGAM_GAMUT_REMAP:
452 REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id],
453 MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select);
454 break;
455 case MPCC_MCM_FIRST_GAMUT_REMAP:
456 REG_GET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id],
457 MPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT, &mode_select);
458 break;
459 case MPCC_MCM_SECOND_GAMUT_REMAP:
460 REG_GET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id],
461 MPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT, &mode_select);
462 break;
463 default:
464 break;
465 }
466
467 //If current set in use not set A (MODE_1), then use set A, otherwise use set B
468 if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1)
469 mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1;
470 else
471 mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2;
472
473 program_gamut_remap(mpc, mpcc_id, arr_reg_val,
474 adjust->mpcc_gamut_remap_block_id, mode_select);
475 }
476 }
477
read_gamut_remap(struct mpc * mpc,int mpcc_id,uint16_t * regval,enum mpcc_gamut_remap_id gamut_remap_block_id,uint32_t * mode_select)478 static void read_gamut_remap(struct mpc *mpc,
479 int mpcc_id,
480 uint16_t *regval,
481 enum mpcc_gamut_remap_id gamut_remap_block_id,
482 uint32_t *mode_select)
483 {
484 struct color_matrices_reg gamut_regs = {0};
485 struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
486
487 switch (gamut_remap_block_id) {
488 case MPCC_OGAM_GAMUT_REMAP:
489 //current coefficient set in use
490 REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, mode_select);
491
492 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
493 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
494 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
495 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
496
497 switch (*mode_select) {
498 case MPCC_GAMUT_REMAP_MODE_SELECT_1:
499 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]);
500 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]);
501 break;
502 case MPCC_GAMUT_REMAP_MODE_SELECT_2:
503 gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]);
504 gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]);
505 break;
506 default:
507 break;
508 }
509 break;
510
511 case MPCC_MCM_FIRST_GAMUT_REMAP:
512 REG_GET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id],
513 MPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT, mode_select);
514
515 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
516 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
517 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
518 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
519
520 switch (*mode_select) {
521 case MPCC_GAMUT_REMAP_MODE_SELECT_1:
522 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_A[mpcc_id]);
523 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_A[mpcc_id]);
524 break;
525 case MPCC_GAMUT_REMAP_MODE_SELECT_2:
526 gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_B[mpcc_id]);
527 gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_B[mpcc_id]);
528 break;
529 default:
530 break;
531 }
532 break;
533
534 case MPCC_MCM_SECOND_GAMUT_REMAP:
535 REG_GET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id],
536 MPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT, mode_select);
537
538 gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
539 gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
540 gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
541 gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
542
543 switch (*mode_select) {
544 case MPCC_GAMUT_REMAP_MODE_SELECT_1:
545 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_A[mpcc_id]);
546 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_A[mpcc_id]);
547 break;
548 case MPCC_GAMUT_REMAP_MODE_SELECT_2:
549 gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_B[mpcc_id]);
550 gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[mpcc_id]);
551 break;
552 default:
553 break;
554 }
555 break;
556
557 default:
558 break;
559 }
560
561 if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) {
562 cm_helper_read_color_matrices(
563 mpc401->base.ctx,
564 regval,
565 &gamut_regs);
566 }
567 }
568
mpc401_get_gamut_remap(struct mpc * mpc,int mpcc_id,struct mpc_grph_gamut_adjustment * adjust)569 void mpc401_get_gamut_remap(struct mpc *mpc,
570 int mpcc_id,
571 struct mpc_grph_gamut_adjustment *adjust)
572 {
573 uint16_t arr_reg_val[12] = {0};
574 uint32_t mode_select;
575
576 read_gamut_remap(mpc, mpcc_id, arr_reg_val, adjust->mpcc_gamut_remap_block_id, &mode_select);
577
578 if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
579 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
580 return;
581 }
582
583 adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
584 convert_hw_matrix(adjust->temperature_matrix,
585 arr_reg_val, ARRAY_SIZE(arr_reg_val));
586 }
587
588 static const struct mpc_funcs dcn401_mpc_funcs = {
589 .read_mpcc_state = mpc1_read_mpcc_state,
590 .insert_plane = mpc1_insert_plane,
591 .remove_mpcc = mpc1_remove_mpcc,
592 .mpc_init = mpc32_mpc_init,
593 .mpc_init_single_inst = mpc3_mpc_init_single_inst,
594 .update_blending = mpc2_update_blending,
595 .cursor_lock = mpc1_cursor_lock,
596 .get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
597 .wait_for_idle = mpc2_assert_idle_mpcc,
598 .assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
599 .init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
600 .set_denorm = mpc3_set_denorm,
601 .set_denorm_clamp = mpc3_set_denorm_clamp,
602 .set_output_csc = mpc3_set_output_csc,
603 .set_ocsc_default = mpc3_set_ocsc_default,
604 .set_output_gamma = mpc3_set_output_gamma,
605 .insert_plane_to_secondary = NULL,
606 .remove_mpcc_from_secondary = NULL,
607 .set_dwb_mux = mpc3_set_dwb_mux,
608 .disable_dwb_mux = mpc3_disable_dwb_mux,
609 .is_dwb_idle = mpc3_is_dwb_idle,
610 .set_gamut_remap = mpc401_set_gamut_remap,
611 .program_shaper = mpc32_program_shaper,
612 .program_3dlut = mpc32_program_3dlut,
613 .program_1dlut = mpc32_program_post1dlut,
614 .acquire_rmu = NULL,
615 .release_rmu = NULL,
616 .power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
617 .get_mpc_out_mux = mpc1_get_mpc_out_mux,
618 .set_bg_color = mpc1_set_bg_color,
619 .set_movable_cm_location = mpc401_set_movable_cm_location,
620 .update_3dlut_fast_load_select = mpc401_update_3dlut_fast_load_select,
621 .get_3dlut_fast_load_status = mpc401_get_3dlut_fast_load_status,
622 .populate_lut = mpc401_populate_lut,
623 .program_lut_read_write_control = mpc401_program_lut_read_write_control,
624 .program_lut_mode = mpc401_program_lut_mode,
625 .program_3dlut_size = mpc401_program_3dlut_size,
626 };
627
628
dcn401_mpc_construct(struct dcn401_mpc * mpc401,struct dc_context * ctx,const struct dcn401_mpc_registers * mpc_regs,const struct dcn401_mpc_shift * mpc_shift,const struct dcn401_mpc_mask * mpc_mask,int num_mpcc,int num_rmu)629 void dcn401_mpc_construct(struct dcn401_mpc *mpc401,
630 struct dc_context *ctx,
631 const struct dcn401_mpc_registers *mpc_regs,
632 const struct dcn401_mpc_shift *mpc_shift,
633 const struct dcn401_mpc_mask *mpc_mask,
634 int num_mpcc,
635 int num_rmu)
636 {
637 int i;
638
639 mpc401->base.ctx = ctx;
640
641 mpc401->base.funcs = &dcn401_mpc_funcs;
642
643 mpc401->mpc_regs = mpc_regs;
644 mpc401->mpc_shift = mpc_shift;
645 mpc401->mpc_mask = mpc_mask;
646
647 mpc401->mpcc_in_use_mask = 0;
648 mpc401->num_mpcc = num_mpcc;
649 mpc401->num_rmu = num_rmu;
650
651 for (i = 0; i < MAX_MPCC; i++)
652 mpc3_init_mpcc(&mpc401->base.mpcc_array[i], i);
653 }
654