Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: dce60_hw_sequencer: add DCE6 specific functions (v2)

[Why]
DCE6 has no bottom_pipe and no Blender HW
DCE6 needs 'blank_target' set to false in order to turn on the display
DCE6 has a specific dce60_pipe_control_lock() fuction that is a no op

[How]
Add DCE6 specific functions with needed private dce60_* dependent fuctions
Comment DCE6 specific CTRC program visibility implementation
Fix a typo in the initial header includes comment 's/DCE8/DCE6/g'
Use dce60_apply_ctx_for_surface() in dce60_hw_sequencer_construct
Use dce60_pipe_control_lock() in dce60_hw_sequencer_construct

v2: add missing return type (Alex)

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Mauro Rossi <issor.oruam@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Mauro Rossi and committed by
Alex Deucher
167d74fd 102b2f58

+379 -2
+379 -2
drivers/gpu/drm/amd/display/dc/dce60/dce60_hw_sequencer.c
··· 32 32 #include "dce110/dce110_hw_sequencer.h" 33 33 #include "dce100/dce100_hw_sequencer.h" 34 34 35 - /* include DCE8 register header files */ 35 + /* include DCE6 register header files */ 36 36 #include "dce/dce_6_0_d.h" 37 37 #include "dce/dce_6_0_sh_mask.h" 38 + 39 + #define DC_LOGGER_INIT() 38 40 39 41 /******************************************************************************* 40 42 * Private definitions ··· 44 42 45 43 /***************************PIPE_CONTROL***********************************/ 46 44 45 + /* 46 + * Check if FBC can be enabled 47 + */ 48 + static bool dce60_should_enable_fbc(struct dc *dc, 49 + struct dc_state *context, 50 + uint32_t *pipe_idx) 51 + { 52 + uint32_t i; 53 + struct pipe_ctx *pipe_ctx = NULL; 54 + struct resource_context *res_ctx = &context->res_ctx; 55 + unsigned int underlay_idx = dc->res_pool->underlay_pipe_index; 56 + 57 + 58 + ASSERT(dc->fbc_compressor); 59 + 60 + /* FBC memory should be allocated */ 61 + if (!dc->ctx->fbc_gpu_addr) 62 + return false; 63 + 64 + /* Only supports single display */ 65 + if (context->stream_count != 1) 66 + return false; 67 + 68 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 69 + if (res_ctx->pipe_ctx[i].stream) { 70 + 71 + pipe_ctx = &res_ctx->pipe_ctx[i]; 72 + 73 + if (!pipe_ctx) 74 + continue; 75 + 76 + /* fbc not applicable on underlay pipe */ 77 + if (pipe_ctx->pipe_idx != underlay_idx) { 78 + *pipe_idx = i; 79 + break; 80 + } 81 + } 82 + } 83 + 84 + if (i == dc->res_pool->pipe_count) 85 + return false; 86 + 87 + if (!pipe_ctx->stream->link) 88 + return false; 89 + 90 + /* Only supports eDP */ 91 + if (pipe_ctx->stream->link->connector_signal != SIGNAL_TYPE_EDP) 92 + return false; 93 + 94 + /* PSR should not be enabled */ 95 + if (pipe_ctx->stream->link->psr_settings.psr_feature_enabled) 96 + return false; 97 + 98 + /* Nothing to compress */ 99 + if (!pipe_ctx->plane_state) 100 + return false; 101 + 102 + /* Only for non-linear tiling */ 103 + if (pipe_ctx->plane_state->tiling_info.gfx8.array_mode == DC_ARRAY_LINEAR_GENERAL) 104 + return false; 105 + 106 + return true; 107 + } 108 + 109 + /* 110 + * Enable FBC 111 + */ 112 + static void dce60_enable_fbc( 113 + struct dc *dc, 114 + struct dc_state *context) 115 + { 116 + uint32_t pipe_idx = 0; 117 + 118 + if (dce60_should_enable_fbc(dc, context, &pipe_idx)) { 119 + /* Program GRPH COMPRESSED ADDRESS and PITCH */ 120 + struct compr_addr_and_pitch_params params = {0, 0, 0}; 121 + struct compressor *compr = dc->fbc_compressor; 122 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; 123 + 124 + params.source_view_width = pipe_ctx->stream->timing.h_addressable; 125 + params.source_view_height = pipe_ctx->stream->timing.v_addressable; 126 + params.inst = pipe_ctx->stream_res.tg->inst; 127 + compr->compr_surface_address.quad_part = dc->ctx->fbc_gpu_addr; 128 + 129 + compr->funcs->surface_address_and_pitch(compr, &params); 130 + compr->funcs->set_fbc_invalidation_triggers(compr, 1); 131 + 132 + compr->funcs->enable_fbc(compr, &params); 133 + } 134 + } 135 + 136 + 137 + /******************************************************************************* 138 + * Front End programming 139 + ******************************************************************************/ 140 + 141 + static void dce60_set_default_colors(struct pipe_ctx *pipe_ctx) 142 + { 143 + struct default_adjustment default_adjust = { 0 }; 144 + 145 + default_adjust.force_hw_default = false; 146 + default_adjust.in_color_space = pipe_ctx->plane_state->color_space; 147 + default_adjust.out_color_space = pipe_ctx->stream->output_color_space; 148 + default_adjust.csc_adjust_type = GRAPHICS_CSC_ADJUST_TYPE_SW; 149 + default_adjust.surface_pixel_format = pipe_ctx->plane_res.scl_data.format; 150 + 151 + /* display color depth */ 152 + default_adjust.color_depth = 153 + pipe_ctx->stream->timing.display_color_depth; 154 + 155 + /* Lb color depth */ 156 + default_adjust.lb_color_depth = pipe_ctx->plane_res.scl_data.lb_params.depth; 157 + 158 + pipe_ctx->plane_res.xfm->funcs->opp_set_csc_default( 159 + pipe_ctx->plane_res.xfm, &default_adjust); 160 + } 161 + 162 + /******************************************************************************* 163 + * In order to turn on surface we will program 164 + * CRTC 165 + * 166 + * DCE6 has no bottom_pipe and no Blender HW 167 + * We need to set 'blank_target' to false in order to turn on the display 168 + * 169 + * |-----------|------------|---------| 170 + * |curr pipe | set_blank | | 171 + * |Surface |blank_target| CRCT | 172 + * |visibility | argument | | 173 + * |-----------|------------|---------| 174 + * | off | true | blank | 175 + * | on | false | unblank | 176 + * |-----------|------------|---------| 177 + * 178 + ******************************************************************************/ 179 + static void dce60_program_surface_visibility(const struct dc *dc, 180 + struct pipe_ctx *pipe_ctx) 181 + { 182 + bool blank_target = false; 183 + 184 + /* DCE6 has no bottom_pipe and no Blender HW */ 185 + 186 + if (!pipe_ctx->plane_state->visible) 187 + blank_target = true; 188 + 189 + /* DCE6 skip dce_set_blender_mode() but then proceed to 'unblank' CRTC */ 190 + pipe_ctx->stream_res.tg->funcs->set_blank(pipe_ctx->stream_res.tg, blank_target); 191 + 192 + } 193 + 194 + 195 + static void dce60_get_surface_visual_confirm_color(const struct pipe_ctx *pipe_ctx, 196 + struct tg_color *color) 197 + { 198 + uint32_t color_value = MAX_TG_COLOR_VALUE * (4 - pipe_ctx->stream_res.tg->inst) / 4; 199 + 200 + switch (pipe_ctx->plane_res.scl_data.format) { 201 + case PIXEL_FORMAT_ARGB8888: 202 + /* set boarder color to red */ 203 + color->color_r_cr = color_value; 204 + break; 205 + 206 + case PIXEL_FORMAT_ARGB2101010: 207 + /* set boarder color to blue */ 208 + color->color_b_cb = color_value; 209 + break; 210 + case PIXEL_FORMAT_420BPP8: 211 + /* set boarder color to green */ 212 + color->color_g_y = color_value; 213 + break; 214 + case PIXEL_FORMAT_420BPP10: 215 + /* set boarder color to yellow */ 216 + color->color_g_y = color_value; 217 + color->color_r_cr = color_value; 218 + break; 219 + case PIXEL_FORMAT_FP16: 220 + /* set boarder color to white */ 221 + color->color_r_cr = color_value; 222 + color->color_b_cb = color_value; 223 + color->color_g_y = color_value; 224 + break; 225 + default: 226 + break; 227 + } 228 + } 229 + 230 + static void dce60_program_scaler(const struct dc *dc, 231 + const struct pipe_ctx *pipe_ctx) 232 + { 233 + struct tg_color color = {0}; 234 + 235 + /* DCE6 skips DCN TOFPGA check for transform_set_pixel_storage_depth == NULL */ 236 + 237 + if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) 238 + dce60_get_surface_visual_confirm_color(pipe_ctx, &color); 239 + else 240 + color_space_to_black_color(dc, 241 + pipe_ctx->stream->output_color_space, 242 + &color); 243 + 244 + pipe_ctx->plane_res.xfm->funcs->transform_set_pixel_storage_depth( 245 + pipe_ctx->plane_res.xfm, 246 + pipe_ctx->plane_res.scl_data.lb_params.depth, 247 + &pipe_ctx->stream->bit_depth_params); 248 + 249 + if (pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color) { 250 + /* 251 + * The way 420 is packed, 2 channels carry Y component, 1 channel 252 + * alternate between Cb and Cr, so both channels need the pixel 253 + * value for Y 254 + */ 255 + if (pipe_ctx->stream->timing.pixel_encoding == PIXEL_ENCODING_YCBCR420) 256 + color.color_r_cr = color.color_g_y; 257 + 258 + pipe_ctx->stream_res.tg->funcs->set_overscan_blank_color( 259 + pipe_ctx->stream_res.tg, 260 + &color); 261 + } 262 + 263 + pipe_ctx->plane_res.xfm->funcs->transform_set_scaler(pipe_ctx->plane_res.xfm, 264 + &pipe_ctx->plane_res.scl_data); 265 + } 266 + 267 + static void 268 + dce60_program_front_end_for_pipe( 269 + struct dc *dc, struct pipe_ctx *pipe_ctx) 270 + { 271 + struct mem_input *mi = pipe_ctx->plane_res.mi; 272 + struct dc_plane_state *plane_state = pipe_ctx->plane_state; 273 + struct xfm_grph_csc_adjustment adjust; 274 + struct out_csc_color_matrix tbl_entry; 275 + unsigned int i; 276 + struct dce_hwseq *hws = dc->hwseq; 277 + 278 + DC_LOGGER_INIT(); 279 + memset(&tbl_entry, 0, sizeof(tbl_entry)); 280 + 281 + memset(&adjust, 0, sizeof(adjust)); 282 + adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS; 283 + 284 + dce_enable_fe_clock(dc->hwseq, mi->inst, true); 285 + 286 + dce60_set_default_colors(pipe_ctx); 287 + if (pipe_ctx->stream->csc_color_matrix.enable_adjustment 288 + == true) { 289 + tbl_entry.color_space = 290 + pipe_ctx->stream->output_color_space; 291 + 292 + for (i = 0; i < 12; i++) 293 + tbl_entry.regval[i] = 294 + pipe_ctx->stream->csc_color_matrix.matrix[i]; 295 + 296 + pipe_ctx->plane_res.xfm->funcs->opp_set_csc_adjustment 297 + (pipe_ctx->plane_res.xfm, &tbl_entry); 298 + } 299 + 300 + if (pipe_ctx->stream->gamut_remap_matrix.enable_remap == true) { 301 + adjust.gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW; 302 + 303 + for (i = 0; i < CSC_TEMPERATURE_MATRIX_SIZE; i++) 304 + adjust.temperature_matrix[i] = 305 + pipe_ctx->stream->gamut_remap_matrix.matrix[i]; 306 + } 307 + 308 + pipe_ctx->plane_res.xfm->funcs->transform_set_gamut_remap(pipe_ctx->plane_res.xfm, &adjust); 309 + 310 + pipe_ctx->plane_res.scl_data.lb_params.alpha_en = pipe_ctx->bottom_pipe != 0; 311 + 312 + dce60_program_scaler(dc, pipe_ctx); 313 + 314 + mi->funcs->mem_input_program_surface_config( 315 + mi, 316 + plane_state->format, 317 + &plane_state->tiling_info, 318 + &plane_state->plane_size, 319 + plane_state->rotation, 320 + NULL, 321 + false); 322 + if (mi->funcs->set_blank) 323 + mi->funcs->set_blank(mi, pipe_ctx->plane_state->visible); 324 + 325 + if (dc->config.gpu_vm_support) 326 + mi->funcs->mem_input_program_pte_vm( 327 + pipe_ctx->plane_res.mi, 328 + plane_state->format, 329 + &plane_state->tiling_info, 330 + plane_state->rotation); 331 + 332 + /* Moved programming gamma from dc to hwss */ 333 + if (pipe_ctx->plane_state->update_flags.bits.full_update || 334 + pipe_ctx->plane_state->update_flags.bits.in_transfer_func_change || 335 + pipe_ctx->plane_state->update_flags.bits.gamma_change) 336 + hws->funcs.set_input_transfer_func(dc, pipe_ctx, pipe_ctx->plane_state); 337 + 338 + if (pipe_ctx->plane_state->update_flags.bits.full_update) 339 + hws->funcs.set_output_transfer_func(dc, pipe_ctx, pipe_ctx->stream); 340 + 341 + DC_LOG_SURFACE( 342 + "Pipe:%d %p: addr hi:0x%x, " 343 + "addr low:0x%x, " 344 + "src: %d, %d, %d," 345 + " %d; dst: %d, %d, %d, %d;" 346 + "clip: %d, %d, %d, %d\n", 347 + pipe_ctx->pipe_idx, 348 + (void *) pipe_ctx->plane_state, 349 + pipe_ctx->plane_state->address.grph.addr.high_part, 350 + pipe_ctx->plane_state->address.grph.addr.low_part, 351 + pipe_ctx->plane_state->src_rect.x, 352 + pipe_ctx->plane_state->src_rect.y, 353 + pipe_ctx->plane_state->src_rect.width, 354 + pipe_ctx->plane_state->src_rect.height, 355 + pipe_ctx->plane_state->dst_rect.x, 356 + pipe_ctx->plane_state->dst_rect.y, 357 + pipe_ctx->plane_state->dst_rect.width, 358 + pipe_ctx->plane_state->dst_rect.height, 359 + pipe_ctx->plane_state->clip_rect.x, 360 + pipe_ctx->plane_state->clip_rect.y, 361 + pipe_ctx->plane_state->clip_rect.width, 362 + pipe_ctx->plane_state->clip_rect.height); 363 + 364 + DC_LOG_SURFACE( 365 + "Pipe %d: width, height, x, y\n" 366 + "viewport:%d, %d, %d, %d\n" 367 + "recout: %d, %d, %d, %d\n", 368 + pipe_ctx->pipe_idx, 369 + pipe_ctx->plane_res.scl_data.viewport.width, 370 + pipe_ctx->plane_res.scl_data.viewport.height, 371 + pipe_ctx->plane_res.scl_data.viewport.x, 372 + pipe_ctx->plane_res.scl_data.viewport.y, 373 + pipe_ctx->plane_res.scl_data.recout.width, 374 + pipe_ctx->plane_res.scl_data.recout.height, 375 + pipe_ctx->plane_res.scl_data.recout.x, 376 + pipe_ctx->plane_res.scl_data.recout.y); 377 + } 378 + 379 + static void dce60_apply_ctx_for_surface( 380 + struct dc *dc, 381 + const struct dc_stream_state *stream, 382 + int num_planes, 383 + struct dc_state *context) 384 + { 385 + int i; 386 + 387 + if (num_planes == 0) 388 + return; 389 + 390 + if (dc->fbc_compressor) 391 + dc->fbc_compressor->funcs->disable_fbc(dc->fbc_compressor); 392 + 393 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 394 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; 395 + 396 + if (pipe_ctx->stream != stream) 397 + continue; 398 + 399 + /* Need to allocate mem before program front end for Fiji */ 400 + pipe_ctx->plane_res.mi->funcs->allocate_mem_input( 401 + pipe_ctx->plane_res.mi, 402 + pipe_ctx->stream->timing.h_total, 403 + pipe_ctx->stream->timing.v_total, 404 + pipe_ctx->stream->timing.pix_clk_100hz / 10, 405 + context->stream_count); 406 + 407 + dce60_program_front_end_for_pipe(dc, pipe_ctx); 408 + 409 + dc->hwss.update_plane_addr(dc, pipe_ctx); 410 + 411 + dce60_program_surface_visibility(dc, pipe_ctx); 412 + 413 + } 414 + 415 + if (dc->fbc_compressor) 416 + dce60_enable_fbc(dc, context); 417 + } 418 + 47 419 void dce60_hw_sequencer_construct(struct dc *dc) 48 420 { 49 421 dce110_hw_sequencer_construct(dc); 50 422 51 423 dc->hwseq->funcs.enable_display_power_gating = dce100_enable_display_power_gating; 52 - dc->hwss.pipe_control_lock = dce_pipe_control_lock; 424 + dc->hwss.apply_ctx_for_surface = dce60_apply_ctx_for_surface; 425 + dc->hwss.pipe_control_lock = dce60_pipe_control_lock; 53 426 dc->hwss.prepare_bandwidth = dce100_prepare_bandwidth; 54 427 dc->hwss.optimize_bandwidth = dce100_optimize_bandwidth; 55 428 }