xref: /linux/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c (revision 2a6b6c9a226279b4f6668450ddb21ae655558087)
1 // SPDX-License-Identifier: MIT
2 //
3 // Copyright 2024 Advanced Micro Devices, Inc.
4 
5 #include "dc_spl_translate.h"
6 #include "spl/dc_spl_types.h"
7 #include "dcn20/dcn20_dpp.h"
8 #include "dcn32/dcn32_dpp.h"
9 #include "dcn401/dcn401_dpp.h"
10 
11 static struct spl_funcs dcn2_spl_funcs = {
12 	.spl_calc_lb_num_partitions = dscl2_spl_calc_lb_num_partitions,
13 };
14 static struct spl_funcs dcn32_spl_funcs = {
15 	.spl_calc_lb_num_partitions = dscl32_spl_calc_lb_num_partitions,
16 };
17 static struct spl_funcs dcn401_spl_funcs = {
18 	.spl_calc_lb_num_partitions = dscl401_spl_calc_lb_num_partitions,
19 };
20 static void populate_splrect_from_rect(struct spl_rect *spl_rect, const struct rect *rect)
21 {
22 	spl_rect->x = rect->x;
23 	spl_rect->y = rect->y;
24 	spl_rect->width = rect->width;
25 	spl_rect->height = rect->height;
26 }
27 static void populate_rect_from_splrect(struct rect *rect, const struct spl_rect *spl_rect)
28 {
29 	rect->x = spl_rect->x;
30 	rect->y = spl_rect->y;
31 	rect->width = spl_rect->width;
32 	rect->height = spl_rect->height;
33 }
34 static void populate_spltaps_from_taps(struct spl_taps *spl_scaling_quality,
35 		const struct scaling_taps *scaling_quality)
36 {
37 	spl_scaling_quality->h_taps_c = scaling_quality->h_taps_c;
38 	spl_scaling_quality->h_taps = scaling_quality->h_taps;
39 	spl_scaling_quality->v_taps_c = scaling_quality->v_taps_c;
40 	spl_scaling_quality->v_taps = scaling_quality->v_taps;
41 }
42 static void populate_taps_from_spltaps(struct scaling_taps *scaling_quality,
43 		const struct spl_taps *spl_scaling_quality)
44 {
45 	scaling_quality->h_taps_c = spl_scaling_quality->h_taps_c;
46 	scaling_quality->h_taps = spl_scaling_quality->h_taps;
47 	scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c;
48 	scaling_quality->v_taps = spl_scaling_quality->v_taps;
49 }
50 static void populate_ratios_from_splratios(struct scaling_ratios *ratios,
51 		const struct spl_ratios *spl_ratios)
52 {
53 	ratios->horz = spl_ratios->horz;
54 	ratios->vert = spl_ratios->vert;
55 	ratios->horz_c = spl_ratios->horz_c;
56 	ratios->vert_c = spl_ratios->vert_c;
57 }
58 static void populate_inits_from_splinits(struct scl_inits *inits,
59 		const struct spl_inits *spl_inits)
60 {
61 	inits->h = spl_inits->h;
62 	inits->v = spl_inits->v;
63 	inits->h_c = spl_inits->h_c;
64 	inits->v_c = spl_inits->v_c;
65 }
66 /// @brief Translate SPL input parameters from pipe context
67 /// @param pipe_ctx
68 /// @param spl_in
69 void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_in *spl_in)
70 {
71 	const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
72 	const struct dc_stream_state *stream = pipe_ctx->stream;
73 	struct rect odm_slice_src = resource_get_odm_slice_src_rect(pipe_ctx);
74 
75 	// Assign the function to calculate the number of partitions in the line buffer
76 	// This is used to determine the vtap support
77 	switch (plane_state->ctx->dce_version)	{
78 	case DCN_VERSION_2_0:
79 		spl_in->funcs = &dcn2_spl_funcs;
80 		break;
81 	case DCN_VERSION_3_2:
82 		spl_in->funcs = &dcn32_spl_funcs;
83 		break;
84 	case DCN_VERSION_4_01:
85 		spl_in->funcs = &dcn401_spl_funcs;
86 		break;
87 	default:
88 		spl_in->funcs = &dcn2_spl_funcs;
89 	}
90 	// Make format field from spl_in point to plane_res scl_data format
91 	spl_in->basic_in.format = (enum spl_pixel_format)pipe_ctx->plane_res.scl_data.format;
92 	// Make view_format from basic_out point to view_format from stream
93 	spl_in->basic_out.view_format = (enum spl_view_3d)stream->view_format;
94 	// Populate spl input basic input clip rect from plane state clip rect
95 	populate_splrect_from_rect(&spl_in->basic_in.clip_rect, &plane_state->clip_rect);
96 	// Populate spl input basic out src rect from stream src rect
97 	populate_splrect_from_rect(&spl_in->basic_out.src_rect, &stream->src);
98 	// Populate spl input basic out dst rect from stream dst rect
99 	populate_splrect_from_rect(&spl_in->basic_out.dst_rect, &stream->dst);
100 	// Make spl input basic input info rotation field point to plane state rotation
101 	spl_in->basic_in.rotation = (enum spl_rotation_angle)plane_state->rotation;
102 	// Populate spl input basic input src rect from plane state src rect
103 	populate_splrect_from_rect(&spl_in->basic_in.src_rect, &plane_state->src_rect);
104 	// Populate spl input basic input dst rect from plane state dst rect
105 	populate_splrect_from_rect(&spl_in->basic_in.dst_rect, &plane_state->dst_rect);
106 	// Make spl input basic input info horiz mirror field point to plane state horz mirror
107 	spl_in->basic_in.horizontal_mirror = plane_state->horizontal_mirror;
108 
109 	// Calculate horizontal splits and split index
110 	spl_in->basic_in.mpc_combine_h = resource_get_mpc_slice_count(pipe_ctx);
111 
112 	if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
113 		spl_in->basic_in.mpc_combine_v = 0;
114 	else
115 		spl_in->basic_in.mpc_combine_v = resource_get_mpc_slice_index(pipe_ctx);
116 
117 	populate_splrect_from_rect(&spl_in->basic_out.odm_slice_rect, &odm_slice_src);
118 	spl_in->basic_out.odm_combine_factor = 0;
119 	spl_in->odm_slice_index = resource_get_odm_slice_index(pipe_ctx);
120 	// Make spl input basic out info output_size width point to stream h active
121 	spl_in->basic_out.output_size.width =
122 		stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
123 	// Make spl input basic out info output_size height point to v active
124 	spl_in->basic_out.output_size.height =
125 		stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
126 	spl_in->basic_out.max_downscale_src_width =
127 			pipe_ctx->stream->ctx->dc->debug.max_downscale_src_width;
128 	spl_in->basic_out.always_scale = pipe_ctx->stream->ctx->dc->debug.always_scale;
129 	// Make spl input basic output info alpha_en field point to plane res scl_data lb_params alpha_en
130 	spl_in->basic_out.alpha_en = pipe_ctx->plane_res.scl_data.lb_params.alpha_en;
131 	// Make spl input basic input info scaling quality field point to plane state scaling_quality
132 	populate_spltaps_from_taps(&spl_in->scaling_quality, &plane_state->scaling_quality);
133 	// Translate edge adaptive scaler preference
134 	spl_in->prefer_easf = pipe_ctx->stream->ctx->dc->config.prefer_easf;
135 	spl_in->disable_easf = false;
136 	if (pipe_ctx->stream->ctx->dc->debug.force_easf == 1)
137 		spl_in->prefer_easf = false;
138 	else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 2)
139 		spl_in->disable_easf = true;
140 	/* Translate adaptive sharpening preference */
141 	if (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 0) {
142 		spl_in->adaptive_sharpness.enable = (pipe_ctx->stream->ctx->dc->debug.force_sharpness > 1) ? true : false;
143 		if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 2)
144 			spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
145 		else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness == 3)
146 			spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
147 		else if (pipe_ctx->stream->ctx->dc->debug.force_sharpness >= 4)
148 			spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
149 	} else {
150 		spl_in->adaptive_sharpness.enable = plane_state->adaptive_sharpness_en;
151 		if (plane_state->sharpnessX1000 == 0)
152 			spl_in->adaptive_sharpness.enable = false;
153 		else if (plane_state->sharpnessX1000 < 999)
154 			spl_in->adaptive_sharpness.sharpness = SHARPNESS_LOW;
155 		else if (plane_state->sharpnessX1000 < 1999)
156 			spl_in->adaptive_sharpness.sharpness = SHARPNESS_MID;
157 		else // Any other value is high sharpness
158 			spl_in->adaptive_sharpness.sharpness = SHARPNESS_HIGH;
159 	}
160 	// Translate linear light scaling preference
161 	if (pipe_ctx->stream->ctx->dc->debug.force_lls > 0)
162 		spl_in->lls_pref = pipe_ctx->stream->ctx->dc->debug.force_lls;
163 	else
164 		spl_in->lls_pref = plane_state->linear_light_scaling;
165 	/* Translate chroma subsampling offset ( cositing ) */
166 	if (pipe_ctx->stream->ctx->dc->debug.force_cositing)
167 		spl_in->basic_in.cositing = pipe_ctx->stream->ctx->dc->debug.force_cositing - 1;
168 	else
169 		spl_in->basic_in.cositing = plane_state->cositing;
170 	/* Translate transfer function */
171 	spl_in->basic_in.tf_type = (enum spl_transfer_func_type) plane_state->in_transfer_func.type;
172 	spl_in->basic_in.tf_predefined_type = (enum spl_transfer_func_predefined) plane_state->in_transfer_func.tf;
173 
174 }
175 
176 /// @brief Translate SPL output parameters to pipe context
177 /// @param pipe_ctx
178 /// @param spl_out
179 void translate_SPL_out_params_to_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_out *spl_out)
180 {
181 	// Make scaler data recout point to spl output field recout
182 	populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->scl_data.recout);
183 	// Make scaler data ratios point to spl output field ratios
184 	populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->scl_data.ratios);
185 	// Make scaler data viewport point to spl output field viewport
186 	populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->scl_data.viewport);
187 	// Make scaler data viewport_c point to spl output field viewport_c
188 	populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->scl_data.viewport_c);
189 	// Make scaler data taps point to spl output field scaling taps
190 	populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->scl_data.taps);
191 	// Make scaler data init point to spl output field init
192 	populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->scl_data.inits);
193 }
194