cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dce60_hw_sequencer.c (13046B)


      1/*
      2 * Copyright 2020 Mauro Rossi <issor.oruam@gmail.com>
      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 "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_hw_sequencer.h"
     33#include "dce100/dce100_hw_sequencer.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 definitions
     43 ******************************************************************************/
     44
     45/***************************PIPE_CONTROL***********************************/
     46
     47/*
     48 *  Check if FBC can be enabled
     49 */
     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 FBC
    113 */
    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 programming
    141 ******************************************************************************/
    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 program
    166 * CRTC
    167 *
    168 * DCE6 has no bottom_pipe and no Blender HW
    169 * We need to set 'blank_target' to false in order to turn on the display
    170 *
    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	else
    242		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 channel
    254		 * alternate between Cb and Cr, so both channels need the pixel
    255		 * value for Y
    256		 */
    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 void
    270dce60_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_adjustment
    290			== 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_adjustment
    299				(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