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