xref: /linux/drivers/gpu/drm/amd/display/dc/dpp/dcn60/dcn60_dpp.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2025 Advanced Micro Devices, Inc.
4 
5 #include "dm_services.h"
6 #include "core_types.h"
7 #include "reg_helper.h"
8 #include "basics/conversion.h"
9 #include "dcn60/dcn60_dpp.h"
10 
11 #define REG(reg)\
12 	dpp->tf_regs->reg
13 
14 #define CTX \
15 	dpp->base.ctx
16 
17 #undef FN
18 #define FN(reg_name, field_name) \
19 	dpp->tf_shift->field_name, dpp->tf_mask->field_name
20 
21 void dpp60_dpp_setup(
22 	struct dpp *dpp_base,
23 	enum surface_pixel_format format,
24 	enum expansion_mode mode,
25 	struct dc_csc_transform input_csc_color_matrix,
26 	enum dc_color_space input_color_space,
27 	struct cnv_alpha_2bit_lut *alpha_2bit_lut)
28 {
29 	struct dcn60_dpp *dpp = TO_DCN60_DPP(dpp_base);
30 	uint32_t pixel_format = 8;
31 	uint32_t alpha_en = 1;
32 	enum dc_color_space color_space = COLOR_SPACE_SRGB;
33 	enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS;
34 	uint32_t is_2bit = 0;
35 	uint32_t dealpha_en = 0, dealpha_ablnd_en = 0;
36 	uint32_t realpha_en = 0, realpha_ablnd_en = 0;
37 	struct out_csc_color_matrix tbl_entry;
38 	int i;
39 
40 	REG_SET_2(FORMAT_CONTROL, 0,
41 		CNVC_BYPASS, 0,
42 		FORMAT_EXPANSION_MODE, mode);
43 
44 	REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0);
45 	REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0);
46 	REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0);
47 	REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0);
48 
49 	REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_R, 0);
50 	REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_G, 1);
51 	REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_B, 2);
52 
53 	switch (format) {
54 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
55 		pixel_format = 1;
56 		break;
57 	case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
58 		pixel_format = 3;
59 		alpha_en = 0;
60 		break;
61 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
62 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
63 		pixel_format = 8;
64 		break;
65 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
66 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
67 		pixel_format = 10;
68 		is_2bit = 1;
69 		break;
70 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
71 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CrCb_P208:
72 		pixel_format = 64;
73 		color_space = COLOR_SPACE_YCBCR709;
74 		select = INPUT_CSC_SELECT_ICSC;
75 		break;
76 	case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
77 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CbCr_P208:
78 		pixel_format = 65;
79 		color_space = COLOR_SPACE_YCBCR709;
80 		select = INPUT_CSC_SELECT_ICSC;
81 		break;
82 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
83 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CrCb_P210:
84 		pixel_format = 66;
85 		color_space = COLOR_SPACE_YCBCR709;
86 		select = INPUT_CSC_SELECT_ICSC;
87 		break;
88 	case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
89 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CbCr_P210:
90 		pixel_format = 67;
91 		color_space = COLOR_SPACE_YCBCR709;
92 		select = INPUT_CSC_SELECT_ICSC;
93 		break;
94 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CrCb_P212:
95 		pixel_format = 68;
96 		color_space = COLOR_SPACE_YCBCR709;
97 		select = INPUT_CSC_SELECT_ICSC;
98 		break;
99 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CbCr_P212:
100 		pixel_format = 69;
101 		color_space = COLOR_SPACE_YCBCR709;
102 		select = INPUT_CSC_SELECT_ICSC;
103 		break;
104 	/* Packed 422 formats*/
105 	case SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb:
106 		pixel_format = 72;
107 		color_space = COLOR_SPACE_YCBCR709;
108 		select = INPUT_CSC_SELECT_ICSC;
109 		// color space and select subjected to change
110 		break;
111 	case SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr:
112 		pixel_format = 73;
113 		color_space = COLOR_SPACE_YCBCR709;
114 		select = INPUT_CSC_SELECT_ICSC;
115 		// color space and select subjected to change
116 		break;
117 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY:
118 		pixel_format = 74;
119 		color_space = COLOR_SPACE_YCBCR709;
120 		select = INPUT_CSC_SELECT_ICSC;
121 		// color space and select subjected to change
122 		break;
123 	case SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY:
124 		pixel_format = 75;
125 		color_space = COLOR_SPACE_YCBCR709;
126 		select = INPUT_CSC_SELECT_ICSC;
127 		// color space and select subjected to change
128 		break;
129 	case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb:
130 		pixel_format = 76;
131 		color_space = COLOR_SPACE_YCBCR709;
132 		select = INPUT_CSC_SELECT_ICSC;
133 		// color space and select subjected to change
134 		break;
135 	case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr:
136 		pixel_format = 77;
137 		color_space = COLOR_SPACE_YCBCR709;
138 		select = INPUT_CSC_SELECT_ICSC;
139 		// color space and select subjected to change
140 		break;
141 	case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY:
142 		pixel_format = 78;
143 		color_space = COLOR_SPACE_YCBCR709;
144 		select = INPUT_CSC_SELECT_ICSC;
145 		// color space and select subjected to change
146 		break;
147 	case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY:
148 		pixel_format = 79;
149 		color_space = COLOR_SPACE_YCBCR709;
150 		select = INPUT_CSC_SELECT_ICSC;
151 		// color space and select subjected to change
152 		break;
153 	case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb:
154 		pixel_format = 80;
155 		color_space = COLOR_SPACE_YCBCR709;
156 		select = INPUT_CSC_SELECT_ICSC;
157 		// color space and select subjected to change
158 		break;
159 	case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr:
160 		pixel_format = 81;
161 		color_space = COLOR_SPACE_YCBCR709;
162 		select = INPUT_CSC_SELECT_ICSC;
163 		// color space and select subjected to change
164 		break;
165 	case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY:
166 		pixel_format = 82;
167 		color_space = COLOR_SPACE_YCBCR709;
168 		select = INPUT_CSC_SELECT_ICSC;
169 		// color space and select subjected to change
170 		break;
171 	case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY:
172 		pixel_format = 83;
173 		color_space = COLOR_SPACE_YCBCR709;
174 		select = INPUT_CSC_SELECT_ICSC;
175 		// color space and select subjected to change
176 		break;
177 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
178 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
179 		pixel_format = 26; /* ARGB16161616_UNORM */
180 		break;
181 	case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
182 		pixel_format = 24;
183 		break;
184 	case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
185 		pixel_format = 25;
186 		break;
187 	case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
188 		pixel_format = 12;
189 		color_space = COLOR_SPACE_YCBCR709;
190 		select = INPUT_CSC_SELECT_ICSC;
191 		break;
192 	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
193 		pixel_format = 112;
194 		alpha_en = 0;
195 		break;
196 	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
197 		pixel_format = 113;
198 		alpha_en = 0;
199 		break;
200 	case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
201 		pixel_format = 114;
202 		color_space = COLOR_SPACE_YCBCR709;
203 		select = INPUT_CSC_SELECT_ICSC;
204 		is_2bit = 1;
205 		break;
206 	case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
207 		pixel_format = 115;
208 		color_space = COLOR_SPACE_YCBCR709;
209 		select = INPUT_CSC_SELECT_ICSC;
210 		is_2bit = 1;
211 		break;
212 	case SURFACE_PIXEL_FORMAT_GRPH_RGBE:
213 		pixel_format = 116;
214 		break;
215 	case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
216 		pixel_format = 116;
217 		break;
218 	case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
219 		pixel_format = 118;
220 		alpha_en = 0;
221 		break;
222 	case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
223 		pixel_format = 119;
224 		alpha_en = 0;
225 		break;
226 	default:
227 		break;
228 	}
229 
230 	/* Set default color space based on format if none is given. */
231 	color_space = input_color_space ? input_color_space : color_space;
232 
233 	if (is_2bit == 1 && alpha_2bit_lut != NULL) {
234 		REG_UPDATE(ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0);
235 		REG_UPDATE(ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1);
236 		REG_UPDATE(ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2);
237 		REG_UPDATE(ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3);
238 	}
239 
240 	REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0,
241 		CNVC_SURFACE_PIXEL_FORMAT, pixel_format);
242 
243 	REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en);
244 
245 	REG_SET_2(PRE_DEALPHA, 0,
246 		PRE_DEALPHA_EN, dealpha_en,
247 		PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en);
248 	REG_SET_2(PRE_REALPHA, 0,
249 		PRE_REALPHA_EN, realpha_en,
250 		PRE_REALPHA_ABLND_EN, realpha_ablnd_en);
251 
252 	if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
253 			format >= SURFACE_PIXEL_FORMAT_SUBSAMPLE_END ||
254 			color_space != COLOR_SPACE_SRGB) {
255 		/* If input adjustment exists, program the ICSC with those values. */
256 		if (input_csc_color_matrix.enable_adjustment == true) {
257 			for (i = 0; i < 12; i++)
258 				tbl_entry.regval[i] = input_csc_color_matrix.matrix[i];
259 
260 			tbl_entry.color_space = input_color_space;
261 
262 			if (dpp3_should_bypass_post_csc_for_colorspace(color_space))
263 				select = INPUT_CSC_SELECT_BYPASS;
264 			else
265 				select = INPUT_CSC_SELECT_ICSC;
266 
267 			dpp3_program_post_csc(dpp_base, color_space, select,
268 				&tbl_entry);
269 		} else {
270 			dpp3_program_post_csc(dpp_base, color_space, select, NULL);
271 		}
272 	}
273 }
274 
275 void dpp60_full_bypass(struct dpp *dpp_base)
276 {
277 	struct dcn60_dpp *dpp = TO_DCN60_DPP(dpp_base);
278 
279 	/* Input pixel format: ARGB8888 */
280 	REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0,
281 		CNVC_SURFACE_PIXEL_FORMAT, 0x8);
282 
283 	/* Zero expansion */
284 	REG_SET_3(FORMAT_CONTROL, 0,
285 		CNVC_BYPASS, 0,
286 		FORMAT_CONTROL__ALPHA_EN, 0,
287 		FORMAT_EXPANSION_MODE, 0);
288 
289 	/* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */
290 	if (dpp->tf_mask->CM_BYPASS_EN)
291 		REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1);
292 	else
293 		REG_SET(CM_CONTROL, 0, CM_BYPASS, 1);
294 }
295 
296 static struct dpp_funcs dcn60_dpp_funcs = {
297 	.dpp_program_gamcor_lut		= dpp3_program_gamcor_lut,
298 	.dpp_read_state				= dpp401_read_state,
299 	.dpp_reset					= dpp_reset,
300 	.dpp_set_scaler				= dpp60_dscl_set_scaler_manual_scale,
301 	.dpp_get_optimal_number_of_taps	= dpp3_get_optimal_number_of_taps,
302 	.dpp_set_pre_degam			= NULL,
303 	.dpp_full_bypass			= dpp60_full_bypass,
304 	.dpp_setup					= dpp60_dpp_setup,
305 	.dpp_program_cm_dealpha		= dpp3_program_cm_dealpha,
306 	.dpp_program_cm_bias		= dpp3_program_cm_bias,
307 	.dpp_program_bias_and_scale	= dpp35_program_bias_and_scale_fcnv,
308 	.dpp_cnv_set_alpha_keyer	= dpp2_cnv_set_alpha_keyer,
309 	.set_cursor_attributes		= dpp401_set_cursor_attributes,
310 	.set_cursor_position		= dpp401_set_cursor_position,
311 	.set_optional_cursor_attributes	= dpp401_set_optional_cursor_attributes,
312 	.dpp_dppclk_control			= dpp1_dppclk_control,
313 	.dpp_set_hdr_multiplier		= dpp3_set_hdr_multiplier,
314 	.set_cursor_matrix			= dpp401_set_cursor_matrix,
315 	.dpp_cm_hist_control		= dpp42_dpp_cm_hist_control,
316 	.dpp_cm_hist_read			= dpp42_dpp_cm_hist_read,
317 	.dpp_read_reg_state			= dpp30_read_reg_state,
318 	.dpp_set_pregam_state		= dpp50_set_pregam_state,
319 };
320 
321 static struct dpp_caps dcn60_dpp_cap = {
322 	.dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT,
323 	.max_lb_partitions = 63,
324 	.dscl_calc_lb_num_partitions = dscl401_calc_lb_num_partitions,
325 };
326 
327 bool dpp60_construct(
328 	struct dcn60_dpp *dpp,
329 	struct dc_context *ctx,
330 	uint32_t inst,
331 	const struct dcn60_dpp_registers *tf_regs,
332 	const struct dcn60_dpp_shift *tf_shift,
333 	const struct dcn60_dpp_mask *tf_mask)
334 {
335 	dpp->base.ctx = ctx;
336 
337 	dpp->base.inst = inst;
338 	dpp->base.funcs = &dcn60_dpp_funcs;
339 	dpp->base.caps = &dcn60_dpp_cap;
340 
341 	dpp->tf_regs = tf_regs;
342 	dpp->tf_shift = tf_shift;
343 	dpp->tf_mask = tf_mask;
344 
345 	return true;
346 }
347