0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include "dm_services.h"
0027 #include "dc.h"
0028 #include "core_types.h"
0029 #include "dce60_hw_sequencer.h"
0030
0031 #include "dce/dce_hwseq.h"
0032 #include "dce110/dce110_hw_sequencer.h"
0033 #include "dce100/dce100_hw_sequencer.h"
0034
0035
0036 #include "dce/dce_6_0_d.h"
0037 #include "dce/dce_6_0_sh_mask.h"
0038
0039 #define DC_LOGGER_INIT()
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 static bool dce60_should_enable_fbc(struct dc *dc,
0051 struct dc_state *context,
0052 uint32_t *pipe_idx)
0053 {
0054 uint32_t i;
0055 struct pipe_ctx *pipe_ctx = NULL;
0056 struct resource_context *res_ctx = &context->res_ctx;
0057 unsigned int underlay_idx = dc->res_pool->underlay_pipe_index;
0058
0059
0060 ASSERT(dc->fbc_compressor);
0061
0062
0063 if (!dc->ctx->fbc_gpu_addr)
0064 return false;
0065
0066
0067 if (context->stream_count != 1)
0068 return false;
0069
0070 for (i = 0; i < dc->res_pool->pipe_count; i++) {
0071 if (res_ctx->pipe_ctx[i].stream) {
0072
0073 pipe_ctx = &res_ctx->pipe_ctx[i];
0074
0075 if (!pipe_ctx)
0076 continue;
0077
0078
0079 if (pipe_ctx->pipe_idx != underlay_idx) {
0080 *pipe_idx = i;
0081 break;
0082 }
0083 }
0084 }
0085
0086 if (i == dc->res_pool->pipe_count)
0087 return false;
0088
0089 if (!pipe_ctx->stream->link)
0090 return false;
0091
0092
0093 if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP)
0094 return false;
0095
0096
0097 if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled)
0098 return false;
0099
0100
0101 if (!pipe_ctx->plane_state)
0102 return false;
0103
0104
0105 if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL)
0106 return false;
0107
0108 return true;
0109 }
0110
0111
0112
0113
0114 static void dce60_enable_fbc(
0115 struct dc *dc,
0116 struct dc_state *context)
0117 {
0118 uint32_t pipe_idx = 0;
0119
0120 if (dce60_should_enable_fbc(dc, context, &pipe_idx)) {
0121
0122 struct compr_addr_and_pitch_params params = {0, 0, 0};
0123 struct compressor *compr = dc->fbc_compressor;
0124 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
0125
0126 params.source_view_width = pipe_ctx->stream->timing.h_addressable;
0127 params.source_view_height = pipe_ctx->stream->timing.v_addressable;
0128 params.inst = pipe_ctx->stream_res.tg->inst;
0129 compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr;
0130
0131 compr->funcs->surface_address_and_pitch(compr, ¶ms);
0132 compr->funcs->set_fbc_invalidation_triggers(compr, 1);
0133
0134 compr->funcs->enable_fbc(compr, ¶ms);
0135 }
0136 }
0137
0138
0139
0140
0141
0142
0143 static void dce60_set_default_colors(struct pipe_ctx *pipe_ctx)
0144 {
0145 struct default_adjustment default_adjust = { 0 };
0146
0147 default_adjust.force_hw_default = false;
0148 default_adjust.in_color_space = pipe_ctx->plane_state->color_space;
0149 default_adjust.out_color_space = pipe_ctx->stream->output_color_space;
0150 default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW;
0151 default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format;
0152
0153
0154 default_adjust.color_depth =
0155 pipe_ctx->stream->timing.display_color_depth;
0156
0157
0158 default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth;
0159
0160 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default(
0161 pipe_ctx->plane_res.xfm, &default_adjust);
0162 }
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 static void dce60_program_surface_visibility(const struct dc *dc,
0182 struct pipe_ctx *pipe_ctx)
0183 {
0184 bool blank_target = false;
0185
0186
0187
0188 if (!pipe_ctx->plane_state->visible)
0189 blank_target = true;
0190
0191
0192 pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target);
0193
0194 }
0195
0196
0197 static void dce60_get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx,
0198 struct tg_color *color)
0199 {
0200 uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4;
0201
0202 switch (pipe_ctx->plane_res.scl_data.format) {
0203 case PIXEL_FORMAT_ARGB8888:
0204
0205 color->color_r_cr = color_value;
0206 break;
0207
0208 case PIXEL_FORMAT_ARGB2101010:
0209
0210 color->color_b_cb = color_value;
0211 break;
0212 case PIXEL_FORMAT_420BPP8:
0213
0214 color->color_g_y = color_value;
0215 break;
0216 case PIXEL_FORMAT_420BPP10:
0217
0218 color->color_g_y = color_value;
0219 color->color_r_cr = color_value;
0220 break;
0221 case PIXEL_FORMAT_FP16:
0222
0223 color->color_r_cr = color_value;
0224 color->color_b_cb = color_value;
0225 color->color_g_y = color_value;
0226 break;
0227 default:
0228 break;
0229 }
0230 }
0231
0232 static void dce60_program_scaler(const struct dc *dc,
0233 const struct pipe_ctx *pipe_ctx)
0234 {
0235 struct tg_color color = {0};
0236
0237
0238
0239 if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE)
0240 dce60_get_surface_visual_confirm_color(pipe_ctx, &color);
0241 else
0242 color_space_to_black_color(dc,
0243 pipe_ctx->stream->output_color_space,
0244 &color);
0245
0246 pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth(
0247 pipe_ctx->plane_res.xfm,
0248 pipe_ctx->plane_res.scl_data.lb_params.depth,
0249 &pipe_ctx->stream->bit_depth_params);
0250
0251 if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) {
0252
0253
0254
0255
0256
0257 if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420)
0258 color.color_r_cr = color.color_g_y;
0259
0260 pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color(
0261 pipe_ctx->stream_res.tg,
0262 &color);
0263 }
0264
0265 pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm,
0266 &pipe_ctx->plane_res.scl_data);
0267 }
0268
0269 static void
0270 dce60_program_front_end_for_pipe(
0271 struct dc *dc, struct pipe_ctx *pipe_ctx)
0272 {
0273 struct mem_input *mi = pipe_ctx->plane_res.mi;
0274 struct dc_plane_state *plane_state = pipe_ctx->plane_state;
0275 struct xfm_grph_csc_adjustment adjust;
0276 struct out_csc_color_matrix tbl_entry;
0277 unsigned int i;
0278 struct dce_hwseq *hws = dc->hwseq;
0279
0280 DC_LOGGER_INIT();
0281 memset(&tbl_entry, 0, sizeof(tbl_entry));
0282
0283 memset(&adjust, 0, sizeof(adjust));
0284 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
0285
0286 dce_enable_fe_clock(dc->hwseq, mi->inst, true);
0287
0288 dce60_set_default_colors(pipe_ctx);
0289 if (pipe_ctx->stream->csc_color_matrix.enable_adjustment
0290 == true) {
0291 tbl_entry.color_space =
0292 pipe_ctx->stream->output_color_space;
0293
0294 for (i = 0; i < 12; i++)
0295 tbl_entry.regval[i] =
0296 pipe_ctx->stream->csc_color_matrix.matrix[i];
0297
0298 pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment
0299 (pipe_ctx->plane_res.xfm, &tbl_entry);
0300 }
0301
0302 if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) {
0303 adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
0304
0305 for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++)
0306 adjust.temperature_matrix[i] =
0307 pipe_ctx->stream->gamut_remap_matrix.matrix[i];
0308 }
0309
0310 pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust);
0311
0312 pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0;
0313
0314 dce60_program_scaler(dc, pipe_ctx);
0315
0316 mi->funcs->mem_input_program_surface_config(
0317 mi,
0318 plane_state->format,
0319 &plane_state->tiling_info,
0320 &plane_state->plane_size,
0321 plane_state->rotation,
0322 NULL,
0323 false);
0324 if (mi->funcs->set_blank)
0325 mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible);
0326
0327 if (dc->config.gpu_vm_support)
0328 mi->funcs->mem_input_program_pte_vm(
0329 pipe_ctx->plane_res.mi,
0330 plane_state->format,
0331 &plane_state->tiling_info,
0332 plane_state->rotation);
0333
0334
0335 if (pipe_ctx->plane_state->update_flags.bits.full_update ||
0336 pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change ||
0337 pipe_ctx->plane_state->update_flags.bits.gamma_change)
0338 hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state);
0339
0340 if (pipe_ctx->plane_state->update_flags.bits.full_update)
0341 hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream);
0342
0343 DC_LOG_SURFACE(
0344 "Pipe:%d %p: addr hi:0x%x, "
0345 "addr low:0x%x, "
0346 "src: %d, %d, %d,"
0347 " %d; dst: %d, %d, %d, %d;"
0348 "clip: %d, %d, %d, %d\n",
0349 pipe_ctx->pipe_idx,
0350 (void *) pipe_ctx->plane_state,
0351 pipe_ctx->plane_state->address.grph.addr.high_part,
0352 pipe_ctx->plane_state->address.grph.addr.low_part,
0353 pipe_ctx->plane_state->src_rect.x,
0354 pipe_ctx->plane_state->src_rect.y,
0355 pipe_ctx->plane_state->src_rect.width,
0356 pipe_ctx->plane_state->src_rect.height,
0357 pipe_ctx->plane_state->dst_rect.x,
0358 pipe_ctx->plane_state->dst_rect.y,
0359 pipe_ctx->plane_state->dst_rect.width,
0360 pipe_ctx->plane_state->dst_rect.height,
0361 pipe_ctx->plane_state->clip_rect.x,
0362 pipe_ctx->plane_state->clip_rect.y,
0363 pipe_ctx->plane_state->clip_rect.width,
0364 pipe_ctx->plane_state->clip_rect.height);
0365
0366 DC_LOG_SURFACE(
0367 "Pipe %d: width, height, x, y\n"
0368 "viewport:%d, %d, %d, %d\n"
0369 "recout: %d, %d, %d, %d\n",
0370 pipe_ctx->pipe_idx,
0371 pipe_ctx->plane_res.scl_data.viewport.width,
0372 pipe_ctx->plane_res.scl_data.viewport.height,
0373 pipe_ctx->plane_res.scl_data.viewport.x,
0374 pipe_ctx->plane_res.scl_data.viewport.y,
0375 pipe_ctx->plane_res.scl_data.recout.width,
0376 pipe_ctx->plane_res.scl_data.recout.height,
0377 pipe_ctx->plane_res.scl_data.recout.x,
0378 pipe_ctx->plane_res.scl_data.recout.y);
0379 }
0380
0381 static void dce60_apply_ctx_for_surface(
0382 struct dc *dc,
0383 const struct dc_stream_state *stream,
0384 int num_planes,
0385 struct dc_state *context)
0386 {
0387 int i;
0388
0389 if (num_planes == 0)
0390 return;
0391
0392 if (dc->fbc_compressor)
0393 dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor);
0394
0395 for (i = 0; i < dc->res_pool->pipe_count; i++) {
0396 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
0397
0398 if (pipe_ctx->stream != stream)
0399 continue;
0400
0401
0402 pipe_ctx->plane_res.mi->funcs->allocate_mem_input(
0403 pipe_ctx->plane_res.mi,
0404 pipe_ctx->stream->timing.h_total,
0405 pipe_ctx->stream->timing.v_total,
0406 pipe_ctx->stream->timing.pix_clk_100hz / 10,
0407 context->stream_count);
0408
0409 dce60_program_front_end_for_pipe(dc, pipe_ctx);
0410
0411 dc->hwss.update_plane_addr(dc, pipe_ctx);
0412
0413 dce60_program_surface_visibility(dc, pipe_ctx);
0414
0415 }
0416
0417 if (dc->fbc_compressor)
0418 dce60_enable_fbc(dc, context);
0419 }
0420
0421 void dce60_hw_sequencer_construct(struct dc *dc)
0422 {
0423 dce110_hw_sequencer_construct(dc);
0424
0425 dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating;
0426 dc->hwss.apply_ctx_for_surface = dce60_apply_ctx_for_surface;
0427 dc->hwss.cursor_lock = dce60_pipe_control_lock;
0428 dc->hwss.pipe_control_lock = dce60_pipe_control_lock;
0429 dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth;
0430 dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth;
0431 }
0432