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 "dce_mem_input.h"
0027 #include "reg_helper.h"
0028 #include "basics/conversion.h"
0029
0030 #define CTX \
0031 dce_mi->base.ctx
0032 #define REG(reg)\
0033 dce_mi->regs->reg
0034
0035 #undef FN
0036 #define FN(reg_name, field_name) \
0037 dce_mi->shifts->field_name, dce_mi->masks->field_name
0038
0039 struct pte_setting {
0040 unsigned int bpp;
0041 unsigned int page_width;
0042 unsigned int page_height;
0043 unsigned char min_pte_before_flip_horiz_scan;
0044 unsigned char min_pte_before_flip_vert_scan;
0045 unsigned char pte_req_per_chunk;
0046 unsigned char param_6;
0047 unsigned char param_7;
0048 unsigned char param_8;
0049 };
0050
0051 enum mi_bits_per_pixel {
0052 mi_bpp_8 = 0,
0053 mi_bpp_16,
0054 mi_bpp_32,
0055 mi_bpp_64,
0056 mi_bpp_count,
0057 };
0058
0059 enum mi_tiling_format {
0060 mi_tiling_linear = 0,
0061 mi_tiling_1D,
0062 mi_tiling_2D,
0063 mi_tiling_count,
0064 };
0065
0066 static const struct pte_setting pte_settings[mi_tiling_count][mi_bpp_count] = {
0067 [mi_tiling_linear] = {
0068 { 8, 4096, 1, 8, 0, 1, 0, 0, 0},
0069 { 16, 2048, 1, 8, 0, 1, 0, 0, 0},
0070 { 32, 1024, 1, 8, 0, 1, 0, 0, 0},
0071 { 64, 512, 1, 8, 0, 1, 0, 0, 0},
0072 },
0073 [mi_tiling_1D] = {
0074 { 8, 512, 8, 1, 0, 1, 0, 0, 0},
0075 { 16, 256, 8, 2, 0, 1, 0, 0, 0},
0076 { 32, 128, 8, 4, 0, 1, 0, 0, 0},
0077 { 64, 64, 8, 4, 0, 1, 0, 0, 0},
0078 },
0079 [mi_tiling_2D] = {
0080 { 8, 64, 64, 8, 8, 1, 4, 0, 0},
0081 { 16, 64, 32, 8, 16, 1, 8, 0, 0},
0082 { 32, 32, 32, 16, 16, 1, 8, 0, 0},
0083 { 64, 8, 32, 16, 16, 1, 8, 0, 0},
0084 },
0085 };
0086
0087 static enum mi_bits_per_pixel get_mi_bpp(
0088 enum surface_pixel_format format)
0089 {
0090 if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616)
0091 return mi_bpp_64;
0092 else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888)
0093 return mi_bpp_32;
0094 else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB1555)
0095 return mi_bpp_16;
0096 else
0097 return mi_bpp_8;
0098 }
0099
0100 static enum mi_tiling_format get_mi_tiling(
0101 union dc_tiling_info *tiling_info)
0102 {
0103 switch (tiling_info->gfx8.array_mode) {
0104 case DC_ARRAY_1D_TILED_THIN1:
0105 case DC_ARRAY_1D_TILED_THICK:
0106 case DC_ARRAY_PRT_TILED_THIN1:
0107 return mi_tiling_1D;
0108 case DC_ARRAY_2D_TILED_THIN1:
0109 case DC_ARRAY_2D_TILED_THICK:
0110 case DC_ARRAY_2D_TILED_X_THICK:
0111 case DC_ARRAY_PRT_2D_TILED_THIN1:
0112 case DC_ARRAY_PRT_2D_TILED_THICK:
0113 return mi_tiling_2D;
0114 case DC_ARRAY_LINEAR_GENERAL:
0115 case DC_ARRAY_LINEAR_ALLIGNED:
0116 return mi_tiling_linear;
0117 default:
0118 return mi_tiling_2D;
0119 }
0120 }
0121
0122 static bool is_vert_scan(enum dc_rotation_angle rotation)
0123 {
0124 switch (rotation) {
0125 case ROTATION_ANGLE_90:
0126 case ROTATION_ANGLE_270:
0127 return true;
0128 default:
0129 return false;
0130 }
0131 }
0132
0133 static void dce_mi_program_pte_vm(
0134 struct mem_input *mi,
0135 enum surface_pixel_format format,
0136 union dc_tiling_info *tiling_info,
0137 enum dc_rotation_angle rotation)
0138 {
0139 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0140 enum mi_bits_per_pixel mi_bpp = get_mi_bpp(format);
0141 enum mi_tiling_format mi_tiling = get_mi_tiling(tiling_info);
0142 const struct pte_setting *pte = &pte_settings[mi_tiling][mi_bpp];
0143
0144 unsigned int page_width = log_2(pte->page_width);
0145 unsigned int page_height = log_2(pte->page_height);
0146 unsigned int min_pte_before_flip = is_vert_scan(rotation) ?
0147 pte->min_pte_before_flip_vert_scan :
0148 pte->min_pte_before_flip_horiz_scan;
0149
0150 REG_UPDATE(GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT,
0151 GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT, 0x7f);
0152
0153 REG_UPDATE_3(DVMM_PTE_CONTROL,
0154 DVMM_PAGE_WIDTH, page_width,
0155 DVMM_PAGE_HEIGHT, page_height,
0156 DVMM_MIN_PTE_BEFORE_FLIP, min_pte_before_flip);
0157
0158 REG_UPDATE_2(DVMM_PTE_ARB_CONTROL,
0159 DVMM_PTE_REQ_PER_CHUNK, pte->pte_req_per_chunk,
0160 DVMM_MAX_PTE_REQ_OUTSTANDING, 0x7f);
0161 }
0162
0163 static void program_urgency_watermark(
0164 struct dce_mem_input *dce_mi,
0165 uint32_t wm_select,
0166 uint32_t urgency_low_wm,
0167 uint32_t urgency_high_wm)
0168 {
0169 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
0170 URGENCY_WATERMARK_MASK, wm_select);
0171
0172 REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
0173 URGENCY_LOW_WATERMARK, urgency_low_wm,
0174 URGENCY_HIGH_WATERMARK, urgency_high_wm);
0175 }
0176
0177 #if defined(CONFIG_DRM_AMD_DC_SI)
0178 static void dce60_program_urgency_watermark(
0179 struct dce_mem_input *dce_mi,
0180 uint32_t wm_select,
0181 uint32_t urgency_low_wm,
0182 uint32_t urgency_high_wm)
0183 {
0184 REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL3,
0185 URGENCY_WATERMARK_MASK, wm_select);
0186
0187 REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
0188 URGENCY_LOW_WATERMARK, urgency_low_wm,
0189 URGENCY_HIGH_WATERMARK, urgency_high_wm);
0190 }
0191 #endif
0192
0193 static void dce120_program_urgency_watermark(
0194 struct dce_mem_input *dce_mi,
0195 uint32_t wm_select,
0196 uint32_t urgency_low_wm,
0197 uint32_t urgency_high_wm)
0198 {
0199 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
0200 URGENCY_WATERMARK_MASK, wm_select);
0201
0202 REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0,
0203 URGENCY_LOW_WATERMARK, urgency_low_wm,
0204 URGENCY_HIGH_WATERMARK, urgency_high_wm);
0205
0206 REG_SET_2(DPG_PIPE_URGENT_LEVEL_CONTROL, 0,
0207 URGENT_LEVEL_LOW_WATERMARK, urgency_low_wm,
0208 URGENT_LEVEL_HIGH_WATERMARK, urgency_high_wm);
0209
0210 }
0211
0212 #if defined(CONFIG_DRM_AMD_DC_SI)
0213 static void dce60_program_nbp_watermark(
0214 struct dce_mem_input *dce_mi,
0215 uint32_t wm_select,
0216 uint32_t nbp_wm)
0217 {
0218 REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
0219 NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
0220
0221 REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
0222 NB_PSTATE_CHANGE_ENABLE, 1,
0223 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
0224 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
0225
0226 REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
0227 NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
0228 }
0229 #endif
0230
0231 static void program_nbp_watermark(
0232 struct dce_mem_input *dce_mi,
0233 uint32_t wm_select,
0234 uint32_t nbp_wm)
0235 {
0236 if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) {
0237 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
0238 NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select);
0239
0240 REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
0241 NB_PSTATE_CHANGE_ENABLE, 1,
0242 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
0243 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
0244
0245 REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL,
0246 NB_PSTATE_CHANGE_WATERMARK, nbp_wm);
0247 }
0248
0249 if (REG(DPG_PIPE_LOW_POWER_CONTROL)) {
0250 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
0251 PSTATE_CHANGE_WATERMARK_MASK, wm_select);
0252
0253 REG_UPDATE_3(DPG_PIPE_LOW_POWER_CONTROL,
0254 PSTATE_CHANGE_ENABLE, 1,
0255 PSTATE_CHANGE_URGENT_DURING_REQUEST, 1,
0256 PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1);
0257
0258 REG_UPDATE(DPG_PIPE_LOW_POWER_CONTROL,
0259 PSTATE_CHANGE_WATERMARK, nbp_wm);
0260 }
0261 }
0262
0263 #if defined(CONFIG_DRM_AMD_DC_SI)
0264 static void dce60_program_stutter_watermark(
0265 struct dce_mem_input *dce_mi,
0266 uint32_t wm_select,
0267 uint32_t stutter_mark)
0268 {
0269 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
0270 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
0271
0272 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
0273 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
0274 }
0275 #endif
0276
0277 static void dce120_program_stutter_watermark(
0278 struct dce_mem_input *dce_mi,
0279 uint32_t wm_select,
0280 uint32_t stutter_mark,
0281 uint32_t stutter_entry)
0282 {
0283 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
0284 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
0285
0286 if (REG(DPG_PIPE_STUTTER_CONTROL2))
0287 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL2,
0288 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
0289 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
0290 else
0291 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
0292 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark,
0293 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry);
0294 }
0295
0296 static void program_stutter_watermark(
0297 struct dce_mem_input *dce_mi,
0298 uint32_t wm_select,
0299 uint32_t stutter_mark)
0300 {
0301 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL,
0302 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select);
0303
0304 if (REG(DPG_PIPE_STUTTER_CONTROL2))
0305 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL2,
0306 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
0307 else
0308 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL,
0309 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark);
0310 }
0311
0312 static void dce_mi_program_display_marks(
0313 struct mem_input *mi,
0314 struct dce_watermarks nbp,
0315 struct dce_watermarks stutter_exit,
0316 struct dce_watermarks stutter_enter,
0317 struct dce_watermarks urgent,
0318 uint32_t total_dest_line_time_ns)
0319 {
0320 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0321 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
0322
0323 program_urgency_watermark(dce_mi, 2,
0324 urgent.a_mark, total_dest_line_time_ns);
0325 program_urgency_watermark(dce_mi, 1,
0326 urgent.d_mark, total_dest_line_time_ns);
0327
0328 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
0329 STUTTER_ENABLE, stutter_en,
0330 STUTTER_IGNORE_FBC, 1);
0331 program_nbp_watermark(dce_mi, 2, nbp.a_mark);
0332 program_nbp_watermark(dce_mi, 1, nbp.d_mark);
0333
0334 program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark);
0335 program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark);
0336 }
0337
0338 #if defined(CONFIG_DRM_AMD_DC_SI)
0339 static void dce60_mi_program_display_marks(
0340 struct mem_input *mi,
0341 struct dce_watermarks nbp,
0342 struct dce_watermarks stutter_exit,
0343 struct dce_watermarks stutter_enter,
0344 struct dce_watermarks urgent,
0345 uint32_t total_dest_line_time_ns)
0346 {
0347 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0348 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
0349
0350 dce60_program_urgency_watermark(dce_mi, 2,
0351 urgent.a_mark, total_dest_line_time_ns);
0352 dce60_program_urgency_watermark(dce_mi, 1,
0353 urgent.d_mark, total_dest_line_time_ns);
0354
0355 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
0356 STUTTER_ENABLE, stutter_en,
0357 STUTTER_IGNORE_FBC, 1);
0358 dce60_program_nbp_watermark(dce_mi, 2, nbp.a_mark);
0359 dce60_program_nbp_watermark(dce_mi, 1, nbp.d_mark);
0360
0361 dce60_program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark);
0362 dce60_program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark);
0363 }
0364 #endif
0365
0366 static void dce112_mi_program_display_marks(struct mem_input *mi,
0367 struct dce_watermarks nbp,
0368 struct dce_watermarks stutter_exit,
0369 struct dce_watermarks stutter_entry,
0370 struct dce_watermarks urgent,
0371 uint32_t total_dest_line_time_ns)
0372 {
0373 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0374 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
0375
0376 program_urgency_watermark(dce_mi, 0,
0377 urgent.a_mark, total_dest_line_time_ns);
0378 program_urgency_watermark(dce_mi, 1,
0379 urgent.b_mark, total_dest_line_time_ns);
0380 program_urgency_watermark(dce_mi, 2,
0381 urgent.c_mark, total_dest_line_time_ns);
0382 program_urgency_watermark(dce_mi, 3,
0383 urgent.d_mark, total_dest_line_time_ns);
0384
0385 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
0386 STUTTER_ENABLE, stutter_en,
0387 STUTTER_IGNORE_FBC, 1);
0388 program_nbp_watermark(dce_mi, 0, nbp.a_mark);
0389 program_nbp_watermark(dce_mi, 1, nbp.b_mark);
0390 program_nbp_watermark(dce_mi, 2, nbp.c_mark);
0391 program_nbp_watermark(dce_mi, 3, nbp.d_mark);
0392
0393 program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark);
0394 program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark);
0395 program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark);
0396 program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark);
0397 }
0398
0399 static void dce120_mi_program_display_marks(struct mem_input *mi,
0400 struct dce_watermarks nbp,
0401 struct dce_watermarks stutter_exit,
0402 struct dce_watermarks stutter_entry,
0403 struct dce_watermarks urgent,
0404 uint32_t total_dest_line_time_ns)
0405 {
0406 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0407 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1;
0408
0409 dce120_program_urgency_watermark(dce_mi, 0,
0410 urgent.a_mark, total_dest_line_time_ns);
0411 dce120_program_urgency_watermark(dce_mi, 1,
0412 urgent.b_mark, total_dest_line_time_ns);
0413 dce120_program_urgency_watermark(dce_mi, 2,
0414 urgent.c_mark, total_dest_line_time_ns);
0415 dce120_program_urgency_watermark(dce_mi, 3,
0416 urgent.d_mark, total_dest_line_time_ns);
0417
0418 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL,
0419 STUTTER_ENABLE, stutter_en,
0420 STUTTER_IGNORE_FBC, 1);
0421 program_nbp_watermark(dce_mi, 0, nbp.a_mark);
0422 program_nbp_watermark(dce_mi, 1, nbp.b_mark);
0423 program_nbp_watermark(dce_mi, 2, nbp.c_mark);
0424 program_nbp_watermark(dce_mi, 3, nbp.d_mark);
0425
0426 dce120_program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark, stutter_entry.a_mark);
0427 dce120_program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark, stutter_entry.b_mark);
0428 dce120_program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark, stutter_entry.c_mark);
0429 dce120_program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark, stutter_entry.d_mark);
0430 }
0431
0432 static void program_tiling(
0433 struct dce_mem_input *dce_mi, const union dc_tiling_info *info)
0434 {
0435 if (dce_mi->masks->GRPH_SW_MODE) {
0436 REG_UPDATE_6(GRPH_CONTROL,
0437 GRPH_SW_MODE, info->gfx9.swizzle,
0438 GRPH_NUM_BANKS, log_2(info->gfx9.num_banks),
0439 GRPH_NUM_SHADER_ENGINES, log_2(info->gfx9.num_shader_engines),
0440 GRPH_NUM_PIPES, log_2(info->gfx9.num_pipes),
0441 GRPH_COLOR_EXPANSION_MODE, 1,
0442 GRPH_SE_ENABLE, info->gfx9.shaderEnable);
0443
0444
0445
0446
0447 }
0448
0449 if (dce_mi->masks->GRPH_MICRO_TILE_MODE) {
0450 REG_UPDATE_9(GRPH_CONTROL,
0451 GRPH_NUM_BANKS, info->gfx8.num_banks,
0452 GRPH_BANK_WIDTH, info->gfx8.bank_width,
0453 GRPH_BANK_HEIGHT, info->gfx8.bank_height,
0454 GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect,
0455 GRPH_TILE_SPLIT, info->gfx8.tile_split,
0456 GRPH_MICRO_TILE_MODE, info->gfx8.tile_mode,
0457 GRPH_PIPE_CONFIG, info->gfx8.pipe_config,
0458 GRPH_ARRAY_MODE, info->gfx8.array_mode,
0459 GRPH_COLOR_EXPANSION_MODE, 1);
0460
0461
0462
0463
0464 }
0465
0466 if (dce_mi->masks->GRPH_ARRAY_MODE) {
0467 REG_UPDATE_8(GRPH_CONTROL,
0468 GRPH_NUM_BANKS, info->gfx8.num_banks,
0469 GRPH_BANK_WIDTH, info->gfx8.bank_width,
0470 GRPH_BANK_HEIGHT, info->gfx8.bank_height,
0471 GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect,
0472 GRPH_TILE_SPLIT, info->gfx8.tile_split,
0473
0474 GRPH_PIPE_CONFIG, info->gfx8.pipe_config,
0475 GRPH_ARRAY_MODE, info->gfx8.array_mode,
0476 GRPH_COLOR_EXPANSION_MODE, 1);
0477
0478
0479
0480
0481 }
0482 }
0483
0484
0485 static void program_size_and_rotation(
0486 struct dce_mem_input *dce_mi,
0487 enum dc_rotation_angle rotation,
0488 const struct plane_size *plane_size)
0489 {
0490 const struct rect *in_rect = &plane_size->surface_size;
0491 struct rect hw_rect = plane_size->surface_size;
0492 const uint32_t rotation_angles[ROTATION_ANGLE_COUNT] = {
0493 [ROTATION_ANGLE_0] = 0,
0494 [ROTATION_ANGLE_90] = 1,
0495 [ROTATION_ANGLE_180] = 2,
0496 [ROTATION_ANGLE_270] = 3,
0497 };
0498
0499 if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) {
0500 hw_rect.x = in_rect->y;
0501 hw_rect.y = in_rect->x;
0502
0503 hw_rect.height = in_rect->width;
0504 hw_rect.width = in_rect->height;
0505 }
0506
0507 REG_SET(GRPH_X_START, 0,
0508 GRPH_X_START, hw_rect.x);
0509
0510 REG_SET(GRPH_Y_START, 0,
0511 GRPH_Y_START, hw_rect.y);
0512
0513 REG_SET(GRPH_X_END, 0,
0514 GRPH_X_END, hw_rect.width);
0515
0516 REG_SET(GRPH_Y_END, 0,
0517 GRPH_Y_END, hw_rect.height);
0518
0519 REG_SET(GRPH_PITCH, 0,
0520 GRPH_PITCH, plane_size->surface_pitch);
0521
0522 REG_SET(HW_ROTATION, 0,
0523 GRPH_ROTATION_ANGLE, rotation_angles[rotation]);
0524 }
0525
0526 #if defined(CONFIG_DRM_AMD_DC_SI)
0527 static void dce60_program_size(
0528 struct dce_mem_input *dce_mi,
0529 enum dc_rotation_angle rotation,
0530 const struct plane_size *plane_size)
0531 {
0532 struct rect hw_rect = plane_size->surface_size;
0533
0534
0535
0536
0537 REG_SET(GRPH_X_START, 0,
0538 GRPH_X_START, hw_rect.x);
0539
0540 REG_SET(GRPH_Y_START, 0,
0541 GRPH_Y_START, hw_rect.y);
0542
0543 REG_SET(GRPH_X_END, 0,
0544 GRPH_X_END, hw_rect.width);
0545
0546 REG_SET(GRPH_Y_END, 0,
0547 GRPH_Y_END, hw_rect.height);
0548
0549 REG_SET(GRPH_PITCH, 0,
0550 GRPH_PITCH, plane_size->surface_pitch);
0551
0552
0553 }
0554 #endif
0555
0556 static void program_grph_pixel_format(
0557 struct dce_mem_input *dce_mi,
0558 enum surface_pixel_format format)
0559 {
0560 uint32_t red_xbar = 0, blue_xbar = 0;
0561 uint32_t grph_depth = 0, grph_format = 0;
0562 uint32_t sign = 0, floating = 0;
0563
0564 if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 ||
0565
0566
0567 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 ||
0568 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS ||
0569 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616 ||
0570 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) {
0571
0572 red_xbar = 2;
0573 blue_xbar = 2;
0574 }
0575
0576 REG_SET_2(GRPH_SWAP_CNTL, 0,
0577 GRPH_RED_CROSSBAR, red_xbar,
0578 GRPH_BLUE_CROSSBAR, blue_xbar);
0579
0580 switch (format) {
0581 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS:
0582 grph_depth = 0;
0583 grph_format = 0;
0584 break;
0585 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
0586 grph_depth = 1;
0587 grph_format = 0;
0588 break;
0589 case SURFACE_PIXEL_FORMAT_GRPH_RGB565:
0590 grph_depth = 1;
0591 grph_format = 1;
0592 break;
0593 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
0594 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
0595 grph_depth = 2;
0596 grph_format = 0;
0597 break;
0598 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
0599 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
0600 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS:
0601 grph_depth = 2;
0602 grph_format = 1;
0603 break;
0604 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
0605 sign = 1;
0606 floating = 1;
0607 fallthrough;
0608 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
0609 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
0610 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616:
0611 grph_depth = 3;
0612 grph_format = 0;
0613 break;
0614 default:
0615 DC_ERR("unsupported grph pixel format");
0616 break;
0617 }
0618
0619 REG_UPDATE_2(GRPH_CONTROL,
0620 GRPH_DEPTH, grph_depth,
0621 GRPH_FORMAT, grph_format);
0622
0623 REG_UPDATE_4(PRESCALE_GRPH_CONTROL,
0624 GRPH_PRESCALE_SELECT, floating,
0625 GRPH_PRESCALE_R_SIGN, sign,
0626 GRPH_PRESCALE_G_SIGN, sign,
0627 GRPH_PRESCALE_B_SIGN, sign);
0628 }
0629
0630 static void dce_mi_program_surface_config(
0631 struct mem_input *mi,
0632 enum surface_pixel_format format,
0633 union dc_tiling_info *tiling_info,
0634 struct plane_size *plane_size,
0635 enum dc_rotation_angle rotation,
0636 struct dc_plane_dcc_param *dcc,
0637 bool horizontal_mirror)
0638 {
0639 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0640 REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
0641
0642 program_tiling(dce_mi, tiling_info);
0643 program_size_and_rotation(dce_mi, rotation, plane_size);
0644
0645 if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
0646 format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
0647 program_grph_pixel_format(dce_mi, format);
0648 }
0649
0650 #if defined(CONFIG_DRM_AMD_DC_SI)
0651 static void dce60_mi_program_surface_config(
0652 struct mem_input *mi,
0653 enum surface_pixel_format format,
0654 union dc_tiling_info *tiling_info,
0655 struct plane_size *plane_size,
0656 enum dc_rotation_angle rotation,
0657 struct dc_plane_dcc_param *dcc,
0658 bool horizontal_mirror)
0659 {
0660 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0661 REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1);
0662
0663 program_tiling(dce_mi, tiling_info);
0664 dce60_program_size(dce_mi, rotation, plane_size);
0665
0666 if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN &&
0667 format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
0668 program_grph_pixel_format(dce_mi, format);
0669 }
0670 #endif
0671
0672 static uint32_t get_dmif_switch_time_us(
0673 uint32_t h_total,
0674 uint32_t v_total,
0675 uint32_t pix_clk_khz)
0676 {
0677 uint32_t frame_time;
0678 uint32_t pixels_per_second;
0679 uint32_t pixels_per_frame;
0680 uint32_t refresh_rate;
0681 const uint32_t us_in_sec = 1000000;
0682 const uint32_t min_single_frame_time_us = 30000;
0683
0684 const uint32_t single_frame_time_multiplier = 2;
0685
0686 if (!h_total || v_total || !pix_clk_khz)
0687 return single_frame_time_multiplier * min_single_frame_time_us;
0688
0689
0690 pixels_per_second = pix_clk_khz * 1000;
0691 pixels_per_frame = h_total * v_total;
0692
0693 if (!pixels_per_second || !pixels_per_frame) {
0694
0695 ASSERT(pixels_per_frame);
0696 ASSERT(pixels_per_second);
0697 return single_frame_time_multiplier * min_single_frame_time_us;
0698 }
0699
0700 refresh_rate = pixels_per_second / pixels_per_frame;
0701
0702 if (!refresh_rate) {
0703
0704 ASSERT(refresh_rate);
0705 return single_frame_time_multiplier * min_single_frame_time_us;
0706 }
0707
0708 frame_time = us_in_sec / refresh_rate;
0709
0710 if (frame_time < min_single_frame_time_us)
0711 frame_time = min_single_frame_time_us;
0712
0713 frame_time *= single_frame_time_multiplier;
0714
0715 return frame_time;
0716 }
0717
0718 static void dce_mi_allocate_dmif(
0719 struct mem_input *mi,
0720 uint32_t h_total,
0721 uint32_t v_total,
0722 uint32_t pix_clk_khz,
0723 uint32_t total_stream_num)
0724 {
0725 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0726 const uint32_t retry_delay = 10;
0727 uint32_t retry_count = get_dmif_switch_time_us(
0728 h_total,
0729 v_total,
0730 pix_clk_khz) / retry_delay;
0731
0732 uint32_t pix_dur;
0733 uint32_t buffers_allocated;
0734 uint32_t dmif_buffer_control;
0735
0736 dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
0737 DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
0738
0739 if (buffers_allocated == 2)
0740 return;
0741
0742 REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
0743 DMIF_BUFFERS_ALLOCATED, 2);
0744
0745 REG_WAIT(DMIF_BUFFER_CONTROL,
0746 DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
0747 retry_delay, retry_count);
0748
0749 if (pix_clk_khz != 0) {
0750 pix_dur = 1000000000ULL / pix_clk_khz;
0751
0752 REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1,
0753 PIXEL_DURATION, pix_dur);
0754 }
0755
0756 if (dce_mi->wa.single_head_rdreq_dmif_limit) {
0757 uint32_t enable = (total_stream_num > 1) ? 0 :
0758 dce_mi->wa.single_head_rdreq_dmif_limit;
0759
0760 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
0761 ENABLE, enable);
0762 }
0763 }
0764
0765 static void dce_mi_free_dmif(
0766 struct mem_input *mi,
0767 uint32_t total_stream_num)
0768 {
0769 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi);
0770 uint32_t buffers_allocated;
0771 uint32_t dmif_buffer_control;
0772
0773 dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL,
0774 DMIF_BUFFERS_ALLOCATED, &buffers_allocated);
0775
0776 if (buffers_allocated == 0)
0777 return;
0778
0779 REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control,
0780 DMIF_BUFFERS_ALLOCATED, 0);
0781
0782 REG_WAIT(DMIF_BUFFER_CONTROL,
0783 DMIF_BUFFERS_ALLOCATION_COMPLETED, 1,
0784 10, 3500);
0785
0786 if (dce_mi->wa.single_head_rdreq_dmif_limit) {
0787 uint32_t enable = (total_stream_num > 1) ? 0 :
0788 dce_mi->wa.single_head_rdreq_dmif_limit;
0789
0790 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT,
0791 ENABLE, enable);
0792 }
0793 }
0794
0795
0796 static void program_sec_addr(
0797 struct dce_mem_input *dce_mi,
0798 PHYSICAL_ADDRESS_LOC address)
0799 {
0800
0801 REG_SET(GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0,
0802 GRPH_SECONDARY_SURFACE_ADDRESS_HIGH,
0803 address.high_part);
0804
0805 REG_SET_2(GRPH_SECONDARY_SURFACE_ADDRESS, 0,
0806 GRPH_SECONDARY_SURFACE_ADDRESS, address.low_part >> 8,
0807 GRPH_SECONDARY_DFQ_ENABLE, 0);
0808 }
0809
0810 static void program_pri_addr(
0811 struct dce_mem_input *dce_mi,
0812 PHYSICAL_ADDRESS_LOC address)
0813 {
0814
0815 REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0,
0816 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH,
0817 address.high_part);
0818
0819 REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS, 0,
0820 GRPH_PRIMARY_SURFACE_ADDRESS,
0821 address.low_part >> 8);
0822 }
0823
0824
0825 static bool dce_mi_is_flip_pending(struct mem_input *mem_input)
0826 {
0827 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
0828 uint32_t update_pending;
0829
0830 REG_GET(GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING, &update_pending);
0831 if (update_pending)
0832 return true;
0833
0834 mem_input->current_address = mem_input->request_address;
0835 return false;
0836 }
0837
0838 static bool dce_mi_program_surface_flip_and_addr(
0839 struct mem_input *mem_input,
0840 const struct dc_plane_address *address,
0841 bool flip_immediate)
0842 {
0843 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input);
0844
0845 REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 1);
0846
0847 REG_UPDATE(
0848 GRPH_FLIP_CONTROL,
0849 GRPH_SURFACE_UPDATE_H_RETRACE_EN, flip_immediate ? 1 : 0);
0850
0851 switch (address->type) {
0852 case PLN_ADDR_TYPE_GRAPHICS:
0853 if (address->grph.addr.quad_part == 0)
0854 break;
0855 program_pri_addr(dce_mi, address->grph.addr);
0856 break;
0857 case PLN_ADDR_TYPE_GRPH_STEREO:
0858 if (address->grph_stereo.left_addr.quad_part == 0 ||
0859 address->grph_stereo.right_addr.quad_part == 0)
0860 break;
0861 program_pri_addr(dce_mi, address->grph_stereo.left_addr);
0862 program_sec_addr(dce_mi, address->grph_stereo.right_addr);
0863 break;
0864 default:
0865
0866 BREAK_TO_DEBUGGER();
0867 break;
0868 }
0869
0870 mem_input->request_address = *address;
0871
0872 if (flip_immediate)
0873 mem_input->current_address = *address;
0874
0875 REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 0);
0876
0877 return true;
0878 }
0879
0880 static const struct mem_input_funcs dce_mi_funcs = {
0881 .mem_input_program_display_marks = dce_mi_program_display_marks,
0882 .allocate_mem_input = dce_mi_allocate_dmif,
0883 .free_mem_input = dce_mi_free_dmif,
0884 .mem_input_program_surface_flip_and_addr =
0885 dce_mi_program_surface_flip_and_addr,
0886 .mem_input_program_pte_vm = dce_mi_program_pte_vm,
0887 .mem_input_program_surface_config =
0888 dce_mi_program_surface_config,
0889 .mem_input_is_flip_pending = dce_mi_is_flip_pending
0890 };
0891
0892 #if defined(CONFIG_DRM_AMD_DC_SI)
0893 static const struct mem_input_funcs dce60_mi_funcs = {
0894 .mem_input_program_display_marks = dce60_mi_program_display_marks,
0895 .allocate_mem_input = dce_mi_allocate_dmif,
0896 .free_mem_input = dce_mi_free_dmif,
0897 .mem_input_program_surface_flip_and_addr =
0898 dce_mi_program_surface_flip_and_addr,
0899 .mem_input_program_pte_vm = dce_mi_program_pte_vm,
0900 .mem_input_program_surface_config =
0901 dce60_mi_program_surface_config,
0902 .mem_input_is_flip_pending = dce_mi_is_flip_pending
0903 };
0904 #endif
0905
0906 static const struct mem_input_funcs dce112_mi_funcs = {
0907 .mem_input_program_display_marks = dce112_mi_program_display_marks,
0908 .allocate_mem_input = dce_mi_allocate_dmif,
0909 .free_mem_input = dce_mi_free_dmif,
0910 .mem_input_program_surface_flip_and_addr =
0911 dce_mi_program_surface_flip_and_addr,
0912 .mem_input_program_pte_vm = dce_mi_program_pte_vm,
0913 .mem_input_program_surface_config =
0914 dce_mi_program_surface_config,
0915 .mem_input_is_flip_pending = dce_mi_is_flip_pending
0916 };
0917
0918 static const struct mem_input_funcs dce120_mi_funcs = {
0919 .mem_input_program_display_marks = dce120_mi_program_display_marks,
0920 .allocate_mem_input = dce_mi_allocate_dmif,
0921 .free_mem_input = dce_mi_free_dmif,
0922 .mem_input_program_surface_flip_and_addr =
0923 dce_mi_program_surface_flip_and_addr,
0924 .mem_input_program_pte_vm = dce_mi_program_pte_vm,
0925 .mem_input_program_surface_config =
0926 dce_mi_program_surface_config,
0927 .mem_input_is_flip_pending = dce_mi_is_flip_pending
0928 };
0929
0930 void dce_mem_input_construct(
0931 struct dce_mem_input *dce_mi,
0932 struct dc_context *ctx,
0933 int inst,
0934 const struct dce_mem_input_registers *regs,
0935 const struct dce_mem_input_shift *mi_shift,
0936 const struct dce_mem_input_mask *mi_mask)
0937 {
0938 dce_mi->base.ctx = ctx;
0939
0940 dce_mi->base.inst = inst;
0941 dce_mi->base.funcs = &dce_mi_funcs;
0942
0943 dce_mi->regs = regs;
0944 dce_mi->shifts = mi_shift;
0945 dce_mi->masks = mi_mask;
0946 }
0947
0948 #if defined(CONFIG_DRM_AMD_DC_SI)
0949 void dce60_mem_input_construct(
0950 struct dce_mem_input *dce_mi,
0951 struct dc_context *ctx,
0952 int inst,
0953 const struct dce_mem_input_registers *regs,
0954 const struct dce_mem_input_shift *mi_shift,
0955 const struct dce_mem_input_mask *mi_mask)
0956 {
0957 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
0958 dce_mi->base.funcs = &dce60_mi_funcs;
0959 }
0960 #endif
0961
0962 void dce112_mem_input_construct(
0963 struct dce_mem_input *dce_mi,
0964 struct dc_context *ctx,
0965 int inst,
0966 const struct dce_mem_input_registers *regs,
0967 const struct dce_mem_input_shift *mi_shift,
0968 const struct dce_mem_input_mask *mi_mask)
0969 {
0970 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
0971 dce_mi->base.funcs = &dce112_mi_funcs;
0972 }
0973
0974 void dce120_mem_input_construct(
0975 struct dce_mem_input *dce_mi,
0976 struct dc_context *ctx,
0977 int inst,
0978 const struct dce_mem_input_registers *regs,
0979 const struct dce_mem_input_shift *mi_shift,
0980 const struct dce_mem_input_mask *mi_mask)
0981 {
0982 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask);
0983 dce_mi->base.funcs = &dce120_mi_funcs;
0984 }