brintos

brintos / linux-shallow public Read only

0
0
Text · 12.7 KiB · 1fdeef4 Raw
433 lines · c
1/*2 * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com>3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * 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 OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "dm_services.h"27#include "dc.h"28#include "core_types.h"29#include "dce60_hw_sequencer.h"30 31#include "dce/dce_hwseq.h"32#include "dce110/dce110_hwseq.h"33#include "dce100/dce100_hwseq.h"34 35/* include DCE6 register header files */36#include "dce/dce_6_0_d.h"37#include "dce/dce_6_0_sh_mask.h"38 39#define DC_LOGGER_INIT()40 41/*******************************************************************************42 * Private definitions43 ******************************************************************************/44 45/***************************PIPE_CONTROL***********************************/46 47/*48 *  Check if FBC can be enabled49 */50static bool dce60_should_enable_fbc(struct dc *dc,51		struct dc_state *context,52		uint32_t *pipe_idx)53{54	uint32_t i;55	struct pipe_ctx *pipe_ctx = NULL;56	struct resource_context *res_ctx = &context->res_ctx;57	unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;58 59 60	ASSERT(dc->fbc_compressor);61 62	/* FBC memory should be allocated */63	if (!dc->ctx->fbc_gpu_addr)64		return false;65 66	/* Only supports single display */67	if (context->stream_count != 1)68		return false;69 70	for (i = 0; i < dc->res_pool->pipe_count; i++) {71		if (res_ctx->pipe_ctx[i].stream) {72 73			pipe_ctx = &res_ctx->pipe_ctx[i];74 75			if (!pipe_ctx)76				continue;77 78			/* fbc not applicable on underlay pipe */79			if (pipe_ctx->pipe_idx != underlay_idx) {80				*pipe_idx = i;81				break;82			}83		}84	}85 86	if (i == dc->res_pool->pipe_count)87		return false;88 89	if (!pipe_ctx->stream->link)90		return false;91 92	/* Only supports eDP */93	if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)94		return false;95 96	/* PSR should not be enabled */97	if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)98		return false;99 100	/* Nothing to compress */101	if (!pipe_ctx->plane_state)102		return false;103 104	/* Only for non-linear tiling */105	if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)106		return false;107 108	return true;109}110 111/*112 *  Enable FBC113 */114static void dce60_enable_fbc(115		struct dc *dc,116		struct dc_state *context)117{118	uint32_t pipe_idx = 0;119 120	if (dce60_should_enable_fbc(dc, context, &pipe_idx)) {121		/* Program GRPH COMPRESSED ADDRESS and PITCH */122		struct compr_addr_and_pitch_params params = {0, 0, 0};123		struct compressor *compr = dc->fbc_compressor;124		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];125 126		params.source_view_width = pipe_ctx->stream->timing.h_addressable;127		params.source_view_height = pipe_ctx->stream->timing.v_addressable;128		params.inst = pipe_ctx->stream_res.tg->inst;129		compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;130 131		compr->funcs->surface_address_and_pitch(compr, &params);132		compr->funcs->set_fbc_invalidation_triggers(compr, 1);133 134		compr->funcs->enable_fbc(compr, &params);135	}136}137 138 139/*******************************************************************************140 * Front End programming141 ******************************************************************************/142 143static void dce60_set_default_colors(struct pipe_ctx *pipe_ctx)144{145	struct default_adjustment default_adjust = { 0 };146 147	default_adjust.force_hw_default = false;148	default_adjust.in_color_space = pipe_ctx->plane_state->color_space;149	default_adjust.out_color_space = pipe_ctx->stream->output_color_space;150	default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;151	default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;152 153	/* display color depth */154	default_adjust.color_depth =155		pipe_ctx->stream->timing.display_color_depth;156 157	/* Lb color depth */158	default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;159 160	pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(161					pipe_ctx->plane_res.xfm, &default_adjust);162}163 164/*******************************************************************************165 * In order to turn on surface we will program166 * CRTC167 *168 * DCE6 has no bottom_pipe and no Blender HW169 * We need to set 'blank_target' to false in order to turn on the display170 *171 * |-----------|------------|---------|172 * |curr pipe  | set_blank  |         |173 * |Surface    |blank_target|  CRCT   |174 * |visibility |  argument  |         |175 * |-----------|------------|---------|176 * |    off    |   true     | blank   |177 * |    on     |   false    | unblank |178 * |-----------|------------|---------|179 *180 ******************************************************************************/181static void dce60_program_surface_visibility(const struct dc *dc,182		struct pipe_ctx *pipe_ctx)183{184	bool blank_target = false;185 186	/* DCE6 has no bottom_pipe and no Blender HW */187 188	if (!pipe_ctx->plane_state->visible)189		blank_target = true;190 191	/* DCE6 skip dce_set_blender_mode() but then proceed to 'unblank' CRTC */192	pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);193 194}195 196 197static void dce60_get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx,198		struct tg_color *color)199{200	uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4;201 202	switch (pipe_ctx->plane_res.scl_data.format) {203	case PIXEL_FORMAT_ARGB8888:204		/* set boarder color to red */205		color->color_r_cr = color_value;206		break;207 208	case PIXEL_FORMAT_ARGB2101010:209		/* set boarder color to blue */210		color->color_b_cb = color_value;211		break;212	case PIXEL_FORMAT_420BPP8:213		/* set boarder color to green */214		color->color_g_y = color_value;215		break;216	case PIXEL_FORMAT_420BPP10:217		/* set boarder color to yellow */218		color->color_g_y = color_value;219		color->color_r_cr = color_value;220		break;221	case PIXEL_FORMAT_FP16:222		/* set boarder color to white */223		color->color_r_cr = color_value;224		color->color_b_cb = color_value;225		color->color_g_y = color_value;226		break;227	default:228		break;229	}230}231 232static void dce60_program_scaler(const struct dc *dc,233		const struct pipe_ctx *pipe_ctx)234{235	struct tg_color color = {0};236 237	/* DCE6 skips DCN TOFPGA check for transform_set_pixel_storage_depth == NULL */238 239	if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)240		dce60_get_surface_visual_confirm_color(pipe_ctx, &color);241	else242		color_space_to_black_color(dc,243				pipe_ctx->stream->output_color_space,244				&color);245 246	pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(247		pipe_ctx->plane_res.xfm,248		pipe_ctx->plane_res.scl_data.lb_params.depth,249		&pipe_ctx->stream->bit_depth_params);250 251	if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) {252		/*253		 * The way 420 is packed, 2 channels carry Y component, 1 channel254		 * alternate between Cb and Cr, so both channels need the pixel255		 * value for Y256		 */257		if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)258			color.color_r_cr = color.color_g_y;259 260		pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(261				pipe_ctx->stream_res.tg,262				&color);263	}264 265	pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,266		&pipe_ctx->plane_res.scl_data);267}268 269static void270dce60_program_front_end_for_pipe(271		struct dc *dc, struct pipe_ctx *pipe_ctx)272{273	struct mem_input *mi = pipe_ctx->plane_res.mi;274	struct dc_plane_state *plane_state = pipe_ctx->plane_state;275	struct xfm_grph_csc_adjustment adjust;276	struct out_csc_color_matrix tbl_entry;277	unsigned int i;278	struct dce_hwseq *hws = dc->hwseq;279 280	DC_LOGGER_INIT();281	memset(&tbl_entry, 0, sizeof(tbl_entry));282 283	memset(&adjust, 0, sizeof(adjust));284	adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;285 286	dce_enable_fe_clock(dc->hwseq, mi->inst, true);287 288	dce60_set_default_colors(pipe_ctx);289	if (pipe_ctx->stream->csc_color_matrix.enable_adjustment290			== true) {291		tbl_entry.color_space =292			pipe_ctx->stream->output_color_space;293 294		for (i = 0; i < 12; i++)295			tbl_entry.regval[i] =296			pipe_ctx->stream->csc_color_matrix.matrix[i];297 298		pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment299				(pipe_ctx->plane_res.xfm, &tbl_entry);300	}301 302	if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {303		adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;304 305		for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)306			adjust.temperature_matrix[i] =307				pipe_ctx->stream->gamut_remap_matrix.matrix[i];308	}309 310	pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);311 312	pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;313 314	dce60_program_scaler(dc, pipe_ctx);315 316	mi->funcs->mem_input_program_surface_config(317			mi,318			plane_state->format,319			&plane_state->tiling_info,320			&plane_state->plane_size,321			plane_state->rotation,322			NULL,323			false);324	if (mi->funcs->set_blank)325		mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);326 327	if (dc->config.gpu_vm_support)328		mi->funcs->mem_input_program_pte_vm(329				pipe_ctx->plane_res.mi,330				plane_state->format,331				&plane_state->tiling_info,332				plane_state->rotation);333 334	/* Moved programming gamma from dc to hwss */335	if (pipe_ctx->plane_state->update_flags.bits.full_update ||336			pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||337			pipe_ctx->plane_state->update_flags.bits.gamma_change)338		hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);339 340	if (pipe_ctx->plane_state->update_flags.bits.full_update)341		hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);342 343	DC_LOG_SURFACE(344			"Pipe:%d %p: addr hi:0x%x, "345			"addr low:0x%x, "346			"src: %d, %d, %d,"347			" %d; dst: %d, %d, %d, %d;"348			"clip: %d, %d, %d, %d\n",349			pipe_ctx->pipe_idx,350			(void *) pipe_ctx->plane_state,351			pipe_ctx->plane_state->address.grph.addr.high_part,352			pipe_ctx->plane_state->address.grph.addr.low_part,353			pipe_ctx->plane_state->src_rect.x,354			pipe_ctx->plane_state->src_rect.y,355			pipe_ctx->plane_state->src_rect.width,356			pipe_ctx->plane_state->src_rect.height,357			pipe_ctx->plane_state->dst_rect.x,358			pipe_ctx->plane_state->dst_rect.y,359			pipe_ctx->plane_state->dst_rect.width,360			pipe_ctx->plane_state->dst_rect.height,361			pipe_ctx->plane_state->clip_rect.x,362			pipe_ctx->plane_state->clip_rect.y,363			pipe_ctx->plane_state->clip_rect.width,364			pipe_ctx->plane_state->clip_rect.height);365 366	DC_LOG_SURFACE(367			"Pipe %d: width, height, x, y\n"368			"viewport:%d, %d, %d, %d\n"369			"recout:  %d, %d, %d, %d\n",370			pipe_ctx->pipe_idx,371			pipe_ctx->plane_res.scl_data.viewport.width,372			pipe_ctx->plane_res.scl_data.viewport.height,373			pipe_ctx->plane_res.scl_data.viewport.x,374			pipe_ctx->plane_res.scl_data.viewport.y,375			pipe_ctx->plane_res.scl_data.recout.width,376			pipe_ctx->plane_res.scl_data.recout.height,377			pipe_ctx->plane_res.scl_data.recout.x,378			pipe_ctx->plane_res.scl_data.recout.y);379}380 381static void dce60_apply_ctx_for_surface(382		struct dc *dc,383		const struct dc_stream_state *stream,384		int num_planes,385		struct dc_state *context)386{387	int i;388 389	if (num_planes == 0)390		return;391 392	if (dc->fbc_compressor)393		dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);394 395	for (i = 0; i < dc->res_pool->pipe_count; i++) {396		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];397 398		if (pipe_ctx->stream != stream)399			continue;400 401		/* Need to allocate mem before program front end for Fiji */402		pipe_ctx->plane_res.mi->funcs->allocate_mem_input(403				pipe_ctx->plane_res.mi,404				pipe_ctx->stream->timing.h_total,405				pipe_ctx->stream->timing.v_total,406				pipe_ctx->stream->timing.pix_clk_100hz / 10,407				context->stream_count);408 409		dce60_program_front_end_for_pipe(dc, pipe_ctx);410 411		dc->hwss.update_plane_addr(dc, pipe_ctx);412 413		dce60_program_surface_visibility(dc, pipe_ctx);414 415	}416 417	if (dc->fbc_compressor)418		dce60_enable_fbc(dc, context);419}420 421void dce60_hw_sequencer_construct(struct dc *dc)422{423	dce110_hw_sequencer_construct(dc);424 425	dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;426	dc->hwss.apply_ctx_for_surface = dce60_apply_ctx_for_surface;427	dc->hwss.cursor_lock = dce60_pipe_control_lock;428	dc->hwss.pipe_control_lock = dce60_pipe_control_lock;429	dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;430	dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;431}432 433