xref: /linux/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c (revision ab93e0dd72c37d378dd936f031ffb83ff2bd87ce)
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 
mpc401_program_3dlut_size(struct mpc * mpc,bool is_17x17x17,int mpcc_id)290 void mpc401_program_3dlut_size(struct mpc *mpc, bool is_17x17x17, int mpcc_id)
291 {
292 	struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
293 
294 	REG_UPDATE(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, is_17x17x17 ? 0 : 1);
295 }
296 
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)297 void mpc_program_gamut_remap(
298 	struct mpc *mpc,
299 	unsigned int mpcc_id,
300 	const uint16_t *regval,
301 	enum mpcc_gamut_remap_id gamut_remap_block_id,
302 	enum mpcc_gamut_remap_mode_select mode_select)
303 {
304 	struct color_matrices_reg gamut_regs;
305 	struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
306 
307 	switch (gamut_remap_block_id) {
308 	case MPCC_OGAM_GAMUT_REMAP:
309 
310 		if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
311 			REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0,
312 				MPCC_GAMUT_REMAP_MODE, mode_select);
313 			return;
314 		}
315 
316 		gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
317 		gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
318 		gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
319 		gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
320 
321 		switch (mode_select) {
322 		case MPCC_GAMUT_REMAP_MODE_SELECT_1:
323 			gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]);
324 			gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]);
325 			break;
326 		case MPCC_GAMUT_REMAP_MODE_SELECT_2:
327 			gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]);
328 			gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]);
329 			break;
330 		default:
331 			break;
332 		}
333 
334 		cm_helper_program_color_matrices(
335 			mpc->ctx,
336 			regval,
337 			&gamut_regs);
338 
339 		//select coefficient set to use, set A (MODE_1) or set B (MODE_2)
340 		REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0, MPCC_GAMUT_REMAP_MODE, mode_select);
341 		break;
342 
343 	case MPCC_MCM_FIRST_GAMUT_REMAP:
344 		if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
345 			REG_SET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 0,
346 				MPCC_MCM_FIRST_GAMUT_REMAP_MODE, mode_select);
347 			return;
348 		}
349 
350 		gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
351 		gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
352 		gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
353 		gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
354 
355 		switch (mode_select) {
356 		case MPCC_GAMUT_REMAP_MODE_SELECT_1:
357 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_A[mpcc_id]);
358 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_A[mpcc_id]);
359 			break;
360 		case MPCC_GAMUT_REMAP_MODE_SELECT_2:
361 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_B[mpcc_id]);
362 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_B[mpcc_id]);
363 			break;
364 		default:
365 			break;
366 		}
367 
368 		cm_helper_program_color_matrices(
369 			mpc->ctx,
370 			regval,
371 			&gamut_regs);
372 
373 		//select coefficient set to use, set A (MODE_1) or set B (MODE_2)
374 		REG_SET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id], 0,
375 			MPCC_MCM_FIRST_GAMUT_REMAP_MODE, mode_select);
376 		break;
377 
378 	case MPCC_MCM_SECOND_GAMUT_REMAP:
379 		if (regval == NULL || mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
380 			REG_SET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 0,
381 				MPCC_MCM_SECOND_GAMUT_REMAP_MODE, mode_select);
382 			return;
383 		}
384 
385 		gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
386 		gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
387 		gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
388 		gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
389 
390 		switch (mode_select) {
391 		case MPCC_GAMUT_REMAP_MODE_SELECT_1:
392 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_A[mpcc_id]);
393 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_A[mpcc_id]);
394 			break;
395 		case MPCC_GAMUT_REMAP_MODE_SELECT_2:
396 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_B[mpcc_id]);
397 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[mpcc_id]);
398 			break;
399 		default:
400 			break;
401 		}
402 
403 		cm_helper_program_color_matrices(
404 			mpc->ctx,
405 			regval,
406 			&gamut_regs);
407 
408 		//select coefficient set to use, set A (MODE_1) or set B (MODE_2)
409 		REG_SET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id], 0,
410 			MPCC_MCM_SECOND_GAMUT_REMAP_MODE, mode_select);
411 		break;
412 
413 	default:
414 		break;
415 	}
416 }
417 
mpc401_set_gamut_remap(struct mpc * mpc,int mpcc_id,const struct mpc_grph_gamut_adjustment * adjust)418 void mpc401_set_gamut_remap(
419 	struct mpc *mpc,
420 	int mpcc_id,
421 	const struct mpc_grph_gamut_adjustment *adjust)
422 {
423 	struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
424 	unsigned int i = 0;
425 	uint32_t mode_select = 0;
426 
427 	if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW) {
428 		/* Bypass / Disable if type is bypass or hw */
429 		mpc_program_gamut_remap(mpc, mpcc_id, NULL,
430 			adjust->mpcc_gamut_remap_block_id, MPCC_GAMUT_REMAP_MODE_SELECT_0);
431 	} else {
432 		struct fixed31_32 arr_matrix[12];
433 		uint16_t arr_reg_val[12];
434 
435 		for (i = 0; i < 12; i++)
436 			arr_matrix[i] = adjust->temperature_matrix[i];
437 
438 		convert_float_matrix(arr_reg_val, arr_matrix, 12);
439 
440 		switch (adjust->mpcc_gamut_remap_block_id) {
441 		case MPCC_OGAM_GAMUT_REMAP:
442 			REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id],
443 				MPCC_GAMUT_REMAP_MODE_CURRENT, &mode_select);
444 			break;
445 		case MPCC_MCM_FIRST_GAMUT_REMAP:
446 			REG_GET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id],
447 				MPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT, &mode_select);
448 			break;
449 		case MPCC_MCM_SECOND_GAMUT_REMAP:
450 			REG_GET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id],
451 				MPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT, &mode_select);
452 			break;
453 		default:
454 			break;
455 		}
456 
457 		//If current set in use not set A (MODE_1), then use set A, otherwise use set B
458 		if (mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_1)
459 			mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_1;
460 		else
461 			mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_2;
462 
463 		mpc_program_gamut_remap(mpc, mpcc_id, arr_reg_val,
464 			adjust->mpcc_gamut_remap_block_id, mode_select);
465 	}
466 }
467 
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)468 void mpc_read_gamut_remap(struct mpc *mpc,
469 	int mpcc_id,
470 	uint16_t *regval,
471 	enum mpcc_gamut_remap_id gamut_remap_block_id,
472 	uint32_t *mode_select)
473 {
474 	struct color_matrices_reg gamut_regs = {0};
475 	struct dcn401_mpc *mpc401 = TO_DCN401_MPC(mpc);
476 
477 	switch (gamut_remap_block_id) {
478 	case MPCC_OGAM_GAMUT_REMAP:
479 		//current coefficient set in use
480 		REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, mode_select);
481 
482 		gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
483 		gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
484 		gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
485 		gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
486 
487 		switch (*mode_select) {
488 		case MPCC_GAMUT_REMAP_MODE_SELECT_1:
489 			gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]);
490 			gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]);
491 			break;
492 		case MPCC_GAMUT_REMAP_MODE_SELECT_2:
493 			gamut_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]);
494 			gamut_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]);
495 			break;
496 		default:
497 			break;
498 		}
499 		break;
500 
501 	case MPCC_MCM_FIRST_GAMUT_REMAP:
502 		REG_GET(MPCC_MCM_FIRST_GAMUT_REMAP_MODE[mpcc_id],
503 				MPCC_MCM_FIRST_GAMUT_REMAP_MODE_CURRENT, mode_select);
504 
505 		gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
506 		gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C11_A;
507 		gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
508 		gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_FIRST_GAMUT_REMAP_C12_A;
509 
510 		switch (*mode_select) {
511 		case MPCC_GAMUT_REMAP_MODE_SELECT_1:
512 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_A[mpcc_id]);
513 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_A[mpcc_id]);
514 			break;
515 		case MPCC_GAMUT_REMAP_MODE_SELECT_2:
516 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C11_C12_B[mpcc_id]);
517 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_FIRST_GAMUT_REMAP_C33_C34_B[mpcc_id]);
518 			break;
519 		default:
520 			break;
521 		}
522 		break;
523 
524 	case MPCC_MCM_SECOND_GAMUT_REMAP:
525 		REG_GET(MPCC_MCM_SECOND_GAMUT_REMAP_MODE[mpcc_id],
526 				MPCC_MCM_SECOND_GAMUT_REMAP_MODE_CURRENT, mode_select);
527 
528 		gamut_regs.shifts.csc_c11 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
529 		gamut_regs.masks.csc_c11 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C11_A;
530 		gamut_regs.shifts.csc_c12 = mpc401->mpc_shift->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
531 		gamut_regs.masks.csc_c12 = mpc401->mpc_mask->MPCC_MCM_SECOND_GAMUT_REMAP_C12_A;
532 
533 		switch (*mode_select) {
534 		case MPCC_GAMUT_REMAP_MODE_SELECT_1:
535 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_A[mpcc_id]);
536 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_A[mpcc_id]);
537 			break;
538 		case MPCC_GAMUT_REMAP_MODE_SELECT_2:
539 			gamut_regs.csc_c11_c12 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C11_C12_B[mpcc_id]);
540 			gamut_regs.csc_c33_c34 = REG(MPC_MCM_SECOND_GAMUT_REMAP_C33_C34_B[mpcc_id]);
541 			break;
542 		default:
543 			break;
544 		}
545 		break;
546 
547 	default:
548 		break;
549 	}
550 
551 	if (*mode_select != MPCC_GAMUT_REMAP_MODE_SELECT_0) {
552 		cm_helper_read_color_matrices(
553 			mpc401->base.ctx,
554 			regval,
555 			&gamut_regs);
556 	}
557 }
558 
mpc401_get_gamut_remap(struct mpc * mpc,int mpcc_id,struct mpc_grph_gamut_adjustment * adjust)559 void mpc401_get_gamut_remap(struct mpc *mpc,
560 	int mpcc_id,
561 	struct mpc_grph_gamut_adjustment *adjust)
562 {
563 	uint16_t arr_reg_val[12] = {0};
564 	uint32_t mode_select = MPCC_GAMUT_REMAP_MODE_SELECT_0;
565 
566 	mpc_read_gamut_remap(mpc, mpcc_id, arr_reg_val, adjust->mpcc_gamut_remap_block_id, &mode_select);
567 
568 	if (mode_select == MPCC_GAMUT_REMAP_MODE_SELECT_0) {
569 		adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
570 		return;
571 	}
572 
573 	adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
574 	convert_hw_matrix(adjust->temperature_matrix,
575 		arr_reg_val, ARRAY_SIZE(arr_reg_val));
576 }
577 
578 static const struct mpc_funcs dcn401_mpc_funcs = {
579 	.read_mpcc_state = mpc1_read_mpcc_state,
580 	.insert_plane = mpc1_insert_plane,
581 	.remove_mpcc = mpc1_remove_mpcc,
582 	.mpc_init = mpc32_mpc_init,
583 	.mpc_init_single_inst = mpc3_mpc_init_single_inst,
584 	.update_blending = mpc2_update_blending,
585 	.cursor_lock = mpc1_cursor_lock,
586 	.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
587 	.wait_for_idle = mpc2_assert_idle_mpcc,
588 	.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
589 	.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
590 	.set_denorm =  mpc3_set_denorm,
591 	.set_denorm_clamp = mpc3_set_denorm_clamp,
592 	.set_output_csc = mpc3_set_output_csc,
593 	.set_ocsc_default = mpc3_set_ocsc_default,
594 	.set_output_gamma = mpc3_set_output_gamma,
595 	.insert_plane_to_secondary = NULL,
596 	.remove_mpcc_from_secondary =  NULL,
597 	.set_dwb_mux = mpc3_set_dwb_mux,
598 	.disable_dwb_mux = mpc3_disable_dwb_mux,
599 	.is_dwb_idle = mpc3_is_dwb_idle,
600 	.set_gamut_remap = mpc401_set_gamut_remap,
601 	.program_shaper = mpc32_program_shaper,
602 	.program_3dlut = mpc32_program_3dlut,
603 	.program_1dlut = mpc32_program_post1dlut,
604 	.acquire_rmu = NULL,
605 	.release_rmu = NULL,
606 	.power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
607 	.get_mpc_out_mux = mpc1_get_mpc_out_mux,
608 	.set_bg_color = mpc1_set_bg_color,
609 	.set_movable_cm_location = mpc401_set_movable_cm_location,
610 	.update_3dlut_fast_load_select = mpc401_update_3dlut_fast_load_select,
611 	.populate_lut = mpc401_populate_lut,
612 	.program_lut_read_write_control = mpc401_program_lut_read_write_control,
613 	.program_lut_mode = mpc401_program_lut_mode,
614 	.program_3dlut_size = mpc401_program_3dlut_size,
615 };
616 
617 
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)618 void dcn401_mpc_construct(struct dcn401_mpc *mpc401,
619 	struct dc_context *ctx,
620 	const struct dcn401_mpc_registers *mpc_regs,
621 	const struct dcn401_mpc_shift *mpc_shift,
622 	const struct dcn401_mpc_mask *mpc_mask,
623 	int num_mpcc,
624 	int num_rmu)
625 {
626 	int i;
627 
628 	mpc401->base.ctx = ctx;
629 
630 	mpc401->base.funcs = &dcn401_mpc_funcs;
631 
632 	mpc401->mpc_regs = mpc_regs;
633 	mpc401->mpc_shift = mpc_shift;
634 	mpc401->mpc_mask = mpc_mask;
635 
636 	mpc401->mpcc_in_use_mask = 0;
637 	mpc401->num_mpcc = num_mpcc;
638 	mpc401->num_rmu = num_rmu;
639 
640 	for (i = 0; i < MAX_MPCC; i++)
641 		mpc3_init_mpcc(&mpc401->base.mpcc_array[i], i);
642 }
643