File Index
Files and directories
Sign in
FILE

dc_spl_translate.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/dc_spl_translate.c C
  1// SPDX-License-Identifier: MIT
  2//
  3// Copyright 2024 Advanced Micro Devices, Inc.
  4
  5#include "dc_spl_translate.h"
  6#include "dcn20/dcn20_dpp.h"
  7#include "dcn32/dcn32_dpp.h"
  8#include "dcn401/dcn401_dpp.h"
  9
 10static struct spl_callbacks dcn2_spl_callbacks = {
 11	.spl_calc_lb_num_partitions = dscl2_spl_calc_lb_num_partitions,
 12};
 13static struct spl_callbacks dcn32_spl_callbacks = {
 14	.spl_calc_lb_num_partitions = dscl32_spl_calc_lb_num_partitions,
 15};
 16static struct spl_callbacks dcn401_spl_callbacks = {
 17	.spl_calc_lb_num_partitions = dscl401_spl_calc_lb_num_partitions,
 18};
 19static void populate_splrect_from_rect(struct spl_rect *spl_rect, const struct rect *rect)
 20{
 21	spl_rect->x = rect->x;
 22	spl_rect->y = rect->y;
 23	spl_rect->width = rect->width;
 24	spl_rect->height = rect->height;
 25}
 26static void populate_rect_from_splrect(struct rect *rect, const struct spl_rect *spl_rect)
 27{
 28	rect->x = spl_rect->x;
 29	rect->y = spl_rect->y;
 30	rect->width = spl_rect->width;
 31	rect->height = spl_rect->height;
 32}
 33static void populate_spltaps_from_taps(struct spl_taps *spl_scaling_quality,
 34		const struct scaling_taps *scaling_quality)
 35{
 36	spl_scaling_quality->h_taps_c = scaling_quality->h_taps_c;
 37	spl_scaling_quality->h_taps = scaling_quality->h_taps;
 38	spl_scaling_quality->v_taps_c = scaling_quality->v_taps_c;
 39	spl_scaling_quality->v_taps = scaling_quality->v_taps;
 40	spl_scaling_quality->integer_scaling = scaling_quality->integer_scaling;
 41}
 42static 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 + 1;
 46	scaling_quality->h_taps = spl_scaling_quality->h_taps + 1;
 47	scaling_quality->v_taps_c = spl_scaling_quality->v_taps_c + 1;
 48	scaling_quality->v_taps = spl_scaling_quality->v_taps + 1;
 49}
 50static void populate_ratios_from_splratios(struct scaling_ratios *ratios,
 51		const struct ratio *spl_ratios)
 52{
 53	ratios->horz = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio >> 5, 3, 19);
 54	ratios->vert = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio >> 5, 3, 19);
 55	ratios->horz_c = dc_fixpt_from_ux_dy(spl_ratios->h_scale_ratio_c >> 5, 3, 19);
 56	ratios->vert_c = dc_fixpt_from_ux_dy(spl_ratios->v_scale_ratio_c >> 5, 3, 19);
 57}
 58static void populate_inits_from_splinits(struct scl_inits *inits,
 59		const struct init *spl_inits)
 60{
 61	inits->h = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int, spl_inits->h_filter_init_frac >> 5, 0, 19);
 62	inits->v = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int, spl_inits->v_filter_init_frac >> 5, 0, 19);
 63	inits->h_c = dc_fixpt_from_int_dy(spl_inits->h_filter_init_int_c, spl_inits->h_filter_init_frac_c >> 5, 0, 19);
 64	inits->v_c = dc_fixpt_from_int_dy(spl_inits->v_filter_init_int_c, spl_inits->v_filter_init_frac_c >> 5, 0, 19);
 65}
 66static void populate_splformat_from_format(enum spl_pixel_format *spl_pixel_format, const enum pixel_format pixel_format)
 67{
 68	if (pixel_format < PIXEL_FORMAT_INVALID)
 69		*spl_pixel_format = (enum spl_pixel_format)pixel_format;
 70	else
 71		*spl_pixel_format = SPL_PIXEL_FORMAT_INVALID;
 72}
 73/// @brief Translate SPL input parameters from pipe context
 74/// @param pipe_ctx
 75/// @param spl_in
 76void translate_SPL_in_params_from_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_in *spl_in)
 77{
 78	const struct dc_plane_state *plane_state = pipe_ctx->plane_state;
 79	const struct dc_stream_state *stream = pipe_ctx->stream;
 80	struct rect odm_slice_src = resource_get_odm_slice_src_rect(pipe_ctx);
 81
 82	// Assign the function to calculate the number of partitions in the line buffer
 83	// This is used to determine the vtap support
 84	switch (plane_state->ctx->dce_version)	{
 85	case DCN_VERSION_2_0:
 86		spl_in->callbacks = dcn2_spl_callbacks;
 87		break;
 88	case DCN_VERSION_3_2:
 89		spl_in->callbacks = dcn32_spl_callbacks;
 90		break;
 91	case DCN_VERSION_4_01:
 92		spl_in->callbacks = dcn401_spl_callbacks;
 93		break;
 94	default:
 95		spl_in->callbacks = dcn2_spl_callbacks;
 96	}
 97	// Make format field from spl_in point to plane_res scl_data format
 98	populate_splformat_from_format(&spl_in->basic_in.format, pipe_ctx->plane_res.scl_data.format);
 99	// Make view_format from basic_out point to view_format from stream
100	spl_in->basic_out.view_format = (enum spl_view_3d)stream->view_format;
101	// Populate spl input basic input clip rect from plane state clip rect
102	populate_splrect_from_rect(&spl_in->basic_in.clip_rect, &plane_state->clip_rect);
103	// Populate spl input basic out src rect from stream src rect
104	populate_splrect_from_rect(&spl_in->basic_out.src_rect, &stream->src);
105	// Populate spl input basic out dst rect from stream dst rect
106	populate_splrect_from_rect(&spl_in->basic_out.dst_rect, &stream->dst);
107	// Make spl input basic input info rotation field point to plane state rotation
108	spl_in->basic_in.rotation = (enum spl_rotation_angle)plane_state->rotation;
109	// Populate spl input basic input src rect from plane state src rect
110	populate_splrect_from_rect(&spl_in->basic_in.src_rect, &plane_state->src_rect);
111	// Populate spl input basic input dst rect from plane state dst rect
112	populate_splrect_from_rect(&spl_in->basic_in.dst_rect, &plane_state->dst_rect);
113	// Make spl input basic input info horiz mirror field point to plane state horz mirror
114	spl_in->basic_in.horizontal_mirror = plane_state->horizontal_mirror;
115
116	// Calculate horizontal splits and split index
117	spl_in->basic_in.num_h_slices_recout_width_align.use_recout_width_aligned = false;
118	spl_in->basic_in.num_h_slices_recout_width_align.num_slices_recout_width.mpc_num_h_slices =
119		resource_get_mpc_slice_count(pipe_ctx);
120
121	if (stream->view_format == VIEW_3D_FORMAT_SIDE_BY_SIDE)
122		spl_in->basic_in.mpc_h_slice_index = 0;
123	else
124		spl_in->basic_in.mpc_h_slice_index = resource_get_mpc_slice_index(pipe_ctx);
125
126	populate_splrect_from_rect(&spl_in->basic_out.odm_slice_rect, &odm_slice_src);
127	spl_in->basic_out.odm_combine_factor = 0;
128	spl_in->odm_slice_index = resource_get_odm_slice_index(pipe_ctx);
129	// Make spl input basic out info output_size width point to stream h active
130	spl_in->basic_out.output_size.width =
131		stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right + pipe_ctx->dsc_padding_params.dsc_hactive_padding;
132	// Make spl input basic out info output_size height point to v active
133	spl_in->basic_out.output_size.height =
134		stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
135	spl_in->basic_out.max_downscale_src_width =
136			pipe_ctx->stream->ctx->dc->debug.max_downscale_src_width;
137	spl_in->basic_out.always_scale = pipe_ctx->stream->ctx->dc->debug.always_scale;
138	// Make spl input basic output info alpha_en field point to plane res scl_data lb_params alpha_en
139	spl_in->basic_out.alpha_en = pipe_ctx->plane_res.scl_data.lb_params.alpha_en;
140	spl_in->basic_out.use_two_pixels_per_container = pipe_ctx->stream_res.tg->funcs->is_two_pixels_per_container(&stream->timing);
141	// Make spl input basic input info scaling quality field point to plane state scaling_quality
142	populate_spltaps_from_taps(&spl_in->scaling_quality, &plane_state->scaling_quality);
143	// Translate edge adaptive scaler preference
144	spl_in->prefer_easf = pipe_ctx->stream->ctx->dc->config.prefer_easf;
145	spl_in->disable_easf = false;
146	if (pipe_ctx->stream->ctx->dc->debug.force_easf == 1)
147		spl_in->prefer_easf = false;
148	else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 2)
149		spl_in->disable_easf = true;
150	else if (pipe_ctx->stream->ctx->dc->debug.force_easf == 3)
151		spl_in->override_easf = true;
152	/* Translate adaptive sharpening preference */
153	unsigned int sharpness_setting = pipe_ctx->stream->ctx->dc->debug.force_sharpness;
154	unsigned int force_sharpness_level = pipe_ctx->stream->ctx->dc->debug.force_sharpness_level;
155	if (sharpness_setting == SHARPNESS_HW_OFF)
156		spl_in->adaptive_sharpness.enable = false;
157	else if (sharpness_setting == SHARPNESS_ZERO) {
158		spl_in->adaptive_sharpness.enable = true;
159		spl_in->adaptive_sharpness.sharpness_level = 0;
160	} else if (sharpness_setting == SHARPNESS_CUSTOM) {
161		/* SAT: read harpness_range from dc_plane_state */
162		spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_min = plane_state->sharpness_range.sdr_rgb_min;
163		spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_max = plane_state->sharpness_range.sdr_rgb_max;
164		spl_in->adaptive_sharpness.sharpness_range.sdr_rgb_mid = plane_state->sharpness_range.sdr_rgb_mid;
165		spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_min = plane_state->sharpness_range.sdr_yuv_min;
166		spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_max = plane_state->sharpness_range.sdr_yuv_max;
167		spl_in->adaptive_sharpness.sharpness_range.sdr_yuv_mid = plane_state->sharpness_range.sdr_yuv_mid;
168		spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_min = plane_state->sharpness_range.hdr_rgb_min;
169		spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_max = plane_state->sharpness_range.hdr_rgb_max;
170		spl_in->adaptive_sharpness.sharpness_range.hdr_rgb_mid = plane_state->sharpness_range.hdr_rgb_mid;
171
172		if (force_sharpness_level > 0) {
173			if (force_sharpness_level > 10)
174				force_sharpness_level = 10;
175			spl_in->adaptive_sharpness.enable = true;
176			spl_in->adaptive_sharpness.sharpness_level = force_sharpness_level;
177		} else if (!plane_state->adaptive_sharpness_en) {
178			spl_in->adaptive_sharpness.enable = false;
179			spl_in->adaptive_sharpness.sharpness_level = 0;
180		} else {
181			spl_in->adaptive_sharpness.enable = true;
182			spl_in->adaptive_sharpness.sharpness_level = plane_state->sharpness_level;
183		}
184	}
185	// Translate linear light scaling preference
186	if (pipe_ctx->stream->ctx->dc->debug.force_lls > 0)
187		spl_in->lls_pref = pipe_ctx->stream->ctx->dc->debug.force_lls;
188	else
189		spl_in->lls_pref = plane_state->linear_light_scaling;
190	/* Translate chroma subsampling offset ( cositing ) */
191	if (pipe_ctx->stream->ctx->dc->debug.force_cositing)
192		spl_in->basic_in.cositing = pipe_ctx->stream->ctx->dc->debug.force_cositing - 1;
193	else
194		spl_in->basic_in.cositing = plane_state->cositing;
195	/* Translate transfer function */
196	spl_in->basic_in.tf_type = (enum spl_transfer_func_type) plane_state->in_transfer_func.type;
197	spl_in->basic_in.tf_predefined_type = (enum spl_transfer_func_predefined) plane_state->in_transfer_func.tf;
198
199	spl_in->h_active = pipe_ctx->plane_res.scl_data.h_active;
200	spl_in->v_active = pipe_ctx->plane_res.scl_data.v_active;
201
202	spl_in->sharpen_policy = (enum sharpen_policy)plane_state->adaptive_sharpness_policy;
203	spl_in->debug.scale_to_sharpness_policy =
204		(enum scale_to_sharpness_policy)pipe_ctx->stream->ctx->dc->debug.scale_to_sharpness_policy;
205
206	/* Check if it is stream is in fullscreen and if its HDR.
207	 * Use this to determine sharpness levels
208	 */
209	spl_in->is_fullscreen = pipe_ctx->stream->sharpening_required;
210	spl_in->is_hdr_on = dm_helpers_is_hdr_on(pipe_ctx->stream->ctx, pipe_ctx->stream);
211	spl_in->sdr_white_level_nits = plane_state->sdr_white_level_nits;
212}
213
214/// @brief Translate SPL output parameters to pipe context
215/// @param pipe_ctx
216/// @param spl_out
217void translate_SPL_out_params_to_pipe_ctx(struct pipe_ctx *pipe_ctx, struct spl_out *spl_out)
218{
219	// Make scaler data recout point to spl output field recout
220	populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.recout, &spl_out->dscl_prog_data->recout);
221	// Make scaler data ratios point to spl output field ratios
222	populate_ratios_from_splratios(&pipe_ctx->plane_res.scl_data.ratios, &spl_out->dscl_prog_data->ratios);
223	// Make scaler data viewport point to spl output field viewport
224	populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport, &spl_out->dscl_prog_data->viewport);
225	// Make scaler data viewport_c point to spl output field viewport_c
226	populate_rect_from_splrect(&pipe_ctx->plane_res.scl_data.viewport_c, &spl_out->dscl_prog_data->viewport_c);
227	// Make scaler data taps point to spl output field scaling taps
228	populate_taps_from_spltaps(&pipe_ctx->plane_res.scl_data.taps, &spl_out->dscl_prog_data->taps);
229	// Make scaler data init point to spl output field init
230	populate_inits_from_splinits(&pipe_ctx->plane_res.scl_data.inits, &spl_out->dscl_prog_data->init);
231}
~/ Read-only file preview.