xref: /linux/drivers/gpu/drm/amd/display/dc/mpc/dcn401/dcn401_mpc.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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