1 /* 2 * Copyright 2016 Advanced Micro Devices, Inc. 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 "dce_mem_input.h" 27 #include "reg_helper.h" 28 #include "basics/conversion.h" 29 30 #define CTX \ 31 dce_mi->base.ctx 32 #define REG(reg)\ 33 dce_mi->regs->reg 34 35 #undef FN 36 #define FN(reg_name, field_name) \ 37 dce_mi->shifts->field_name, dce_mi->masks->field_name 38 39 struct pte_setting { 40 unsigned int bpp; 41 unsigned int page_width; 42 unsigned int page_height; 43 unsigned char min_pte_before_flip_horiz_scan; 44 unsigned char min_pte_before_flip_vert_scan; 45 unsigned char pte_req_per_chunk; 46 unsigned char param_6; 47 unsigned char param_7; 48 unsigned char param_8; 49 }; 50 51 enum mi_bits_per_pixel { 52 mi_bpp_8 = 0, 53 mi_bpp_16, 54 mi_bpp_32, 55 mi_bpp_64, 56 mi_bpp_count, 57 }; 58 59 enum mi_tiling_format { 60 mi_tiling_linear = 0, 61 mi_tiling_1D, 62 mi_tiling_2D, 63 mi_tiling_count, 64 }; 65 66 static const struct pte_setting pte_settings[mi_tiling_count][mi_bpp_count] = { 67 [mi_tiling_linear] = { 68 { 8, 4096, 1, 8, 0, 1, 0, 0, 0}, 69 { 16, 2048, 1, 8, 0, 1, 0, 0, 0}, 70 { 32, 1024, 1, 8, 0, 1, 0, 0, 0}, 71 { 64, 512, 1, 8, 0, 1, 0, 0, 0}, /* new for 64bpp from HW */ 72 }, 73 [mi_tiling_1D] = { 74 { 8, 512, 8, 1, 0, 1, 0, 0, 0}, /* 0 for invalid */ 75 { 16, 256, 8, 2, 0, 1, 0, 0, 0}, 76 { 32, 128, 8, 4, 0, 1, 0, 0, 0}, 77 { 64, 64, 8, 4, 0, 1, 0, 0, 0}, /* fake */ 78 }, 79 [mi_tiling_2D] = { 80 { 8, 64, 64, 8, 8, 1, 4, 0, 0}, 81 { 16, 64, 32, 8, 16, 1, 8, 0, 0}, 82 { 32, 32, 32, 16, 16, 1, 8, 0, 0}, 83 { 64, 8, 32, 16, 16, 1, 8, 0, 0}, /* fake */ 84 }, 85 }; 86 87 static enum mi_bits_per_pixel get_mi_bpp( 88 enum surface_pixel_format format) 89 { 90 if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616) 91 return mi_bpp_64; 92 else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB8888) 93 return mi_bpp_32; 94 else if (format >= SURFACE_PIXEL_FORMAT_GRPH_ARGB1555) 95 return mi_bpp_16; 96 else 97 return mi_bpp_8; 98 } 99 100 static enum mi_tiling_format get_mi_tiling( 101 union dc_tiling_info *tiling_info) 102 { 103 switch (tiling_info->gfx8.array_mode) { 104 case DC_ARRAY_1D_TILED_THIN1: 105 case DC_ARRAY_1D_TILED_THICK: 106 case DC_ARRAY_PRT_TILED_THIN1: 107 return mi_tiling_1D; 108 case DC_ARRAY_2D_TILED_THIN1: 109 case DC_ARRAY_2D_TILED_THICK: 110 case DC_ARRAY_2D_TILED_X_THICK: 111 case DC_ARRAY_PRT_2D_TILED_THIN1: 112 case DC_ARRAY_PRT_2D_TILED_THICK: 113 return mi_tiling_2D; 114 case DC_ARRAY_LINEAR_GENERAL: 115 case DC_ARRAY_LINEAR_ALLIGNED: 116 return mi_tiling_linear; 117 default: 118 return mi_tiling_2D; 119 } 120 } 121 122 static bool is_vert_scan(enum dc_rotation_angle rotation) 123 { 124 switch (rotation) { 125 case ROTATION_ANGLE_90: 126 case ROTATION_ANGLE_270: 127 return true; 128 default: 129 return false; 130 } 131 } 132 133 static void dce_mi_program_pte_vm( 134 struct mem_input *mi, 135 enum surface_pixel_format format, 136 union dc_tiling_info *tiling_info, 137 enum dc_rotation_angle rotation) 138 { 139 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 140 enum mi_bits_per_pixel mi_bpp = get_mi_bpp(format); 141 enum mi_tiling_format mi_tiling = get_mi_tiling(tiling_info); 142 const struct pte_setting *pte = &pte_settings[mi_tiling][mi_bpp]; 143 144 unsigned int page_width = log_2(pte->page_width); 145 unsigned int page_height = log_2(pte->page_height); 146 unsigned int min_pte_before_flip = is_vert_scan(rotation) ? 147 pte->min_pte_before_flip_vert_scan : 148 pte->min_pte_before_flip_horiz_scan; 149 150 REG_UPDATE(GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT, 151 GRPH_PIPE_OUTSTANDING_REQUEST_LIMIT, 0x7f); 152 153 REG_UPDATE_3(DVMM_PTE_CONTROL, 154 DVMM_PAGE_WIDTH, page_width, 155 DVMM_PAGE_HEIGHT, page_height, 156 DVMM_MIN_PTE_BEFORE_FLIP, min_pte_before_flip); 157 158 REG_UPDATE_2(DVMM_PTE_ARB_CONTROL, 159 DVMM_PTE_REQ_PER_CHUNK, pte->pte_req_per_chunk, 160 DVMM_MAX_PTE_REQ_OUTSTANDING, 0x7f); 161 } 162 163 static void program_urgency_watermark( 164 struct dce_mem_input *dce_mi, 165 uint32_t wm_select, 166 uint32_t urgency_low_wm, 167 uint32_t urgency_high_wm) 168 { 169 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, 170 URGENCY_WATERMARK_MASK, wm_select); 171 172 REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0, 173 URGENCY_LOW_WATERMARK, urgency_low_wm, 174 URGENCY_HIGH_WATERMARK, urgency_high_wm); 175 } 176 177 #if defined(CONFIG_DRM_AMD_DC_SI) 178 static void dce60_program_urgency_watermark( 179 struct dce_mem_input *dce_mi, 180 uint32_t wm_select, 181 uint32_t urgency_low_wm, 182 uint32_t urgency_high_wm) 183 { 184 REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL3, 185 URGENCY_WATERMARK_MASK, wm_select); 186 187 REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0, 188 URGENCY_LOW_WATERMARK, urgency_low_wm, 189 URGENCY_HIGH_WATERMARK, urgency_high_wm); 190 } 191 #endif 192 193 static void dce120_program_urgency_watermark( 194 struct dce_mem_input *dce_mi, 195 uint32_t wm_select, 196 uint32_t urgency_low_wm, 197 uint32_t urgency_high_wm) 198 { 199 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, 200 URGENCY_WATERMARK_MASK, wm_select); 201 202 REG_SET_2(DPG_PIPE_URGENCY_CONTROL, 0, 203 URGENCY_LOW_WATERMARK, urgency_low_wm, 204 URGENCY_HIGH_WATERMARK, urgency_high_wm); 205 206 REG_SET_2(DPG_PIPE_URGENT_LEVEL_CONTROL, 0, 207 URGENT_LEVEL_LOW_WATERMARK, urgency_low_wm, 208 URGENT_LEVEL_HIGH_WATERMARK, urgency_high_wm); 209 210 } 211 212 #if defined(CONFIG_DRM_AMD_DC_SI) 213 static void dce60_program_nbp_watermark( 214 struct dce_mem_input *dce_mi, 215 uint32_t wm_select, 216 uint32_t nbp_wm) 217 { 218 REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, 219 NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select); 220 221 REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, 222 NB_PSTATE_CHANGE_ENABLE, 1, 223 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1, 224 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1); 225 226 REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, 227 NB_PSTATE_CHANGE_WATERMARK, nbp_wm); 228 } 229 #endif 230 231 static void program_nbp_watermark( 232 struct dce_mem_input *dce_mi, 233 uint32_t wm_select, 234 uint32_t nbp_wm) 235 { 236 if (REG(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL)) { 237 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, 238 NB_PSTATE_CHANGE_WATERMARK_MASK, wm_select); 239 240 REG_UPDATE_3(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, 241 NB_PSTATE_CHANGE_ENABLE, 1, 242 NB_PSTATE_CHANGE_URGENT_DURING_REQUEST, 1, 243 NB_PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1); 244 245 REG_UPDATE(DPG_PIPE_NB_PSTATE_CHANGE_CONTROL, 246 NB_PSTATE_CHANGE_WATERMARK, nbp_wm); 247 } 248 249 if (REG(DPG_PIPE_LOW_POWER_CONTROL)) { 250 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, 251 PSTATE_CHANGE_WATERMARK_MASK, wm_select); 252 253 REG_UPDATE_3(DPG_PIPE_LOW_POWER_CONTROL, 254 PSTATE_CHANGE_ENABLE, 1, 255 PSTATE_CHANGE_URGENT_DURING_REQUEST, 1, 256 PSTATE_CHANGE_NOT_SELF_REFRESH_DURING_REQUEST, 1); 257 258 REG_UPDATE(DPG_PIPE_LOW_POWER_CONTROL, 259 PSTATE_CHANGE_WATERMARK, nbp_wm); 260 } 261 } 262 263 #if defined(CONFIG_DRM_AMD_DC_SI) 264 static void dce60_program_stutter_watermark( 265 struct dce_mem_input *dce_mi, 266 uint32_t wm_select, 267 uint32_t stutter_mark) 268 { 269 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL, 270 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select); 271 272 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL, 273 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark); 274 } 275 #endif 276 277 static void dce120_program_stutter_watermark( 278 struct dce_mem_input *dce_mi, 279 uint32_t wm_select, 280 uint32_t stutter_mark, 281 uint32_t stutter_entry) 282 { 283 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, 284 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select); 285 286 if (REG(DPG_PIPE_STUTTER_CONTROL2)) 287 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL2, 288 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark, 289 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry); 290 else 291 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL, 292 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark, 293 STUTTER_ENTER_SELF_REFRESH_WATERMARK, stutter_entry); 294 } 295 296 static void program_stutter_watermark( 297 struct dce_mem_input *dce_mi, 298 uint32_t wm_select, 299 uint32_t stutter_mark) 300 { 301 REG_UPDATE(DPG_WATERMARK_MASK_CONTROL, 302 STUTTER_EXIT_SELF_REFRESH_WATERMARK_MASK, wm_select); 303 304 if (REG(DPG_PIPE_STUTTER_CONTROL2)) 305 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL2, 306 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark); 307 else 308 REG_UPDATE(DPG_PIPE_STUTTER_CONTROL, 309 STUTTER_EXIT_SELF_REFRESH_WATERMARK, stutter_mark); 310 } 311 312 static void dce_mi_program_display_marks( 313 struct mem_input *mi, 314 struct dce_watermarks nbp, 315 struct dce_watermarks stutter_exit, 316 struct dce_watermarks stutter_enter, 317 struct dce_watermarks urgent, 318 uint32_t total_dest_line_time_ns) 319 { 320 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 321 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1; 322 323 program_urgency_watermark(dce_mi, 2, /* set a */ 324 urgent.a_mark, total_dest_line_time_ns); 325 program_urgency_watermark(dce_mi, 1, /* set d */ 326 urgent.d_mark, total_dest_line_time_ns); 327 328 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL, 329 STUTTER_ENABLE, stutter_en, 330 STUTTER_IGNORE_FBC, 1); 331 program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */ 332 program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */ 333 334 program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */ 335 program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */ 336 } 337 338 #if defined(CONFIG_DRM_AMD_DC_SI) 339 static void dce60_mi_program_display_marks( 340 struct mem_input *mi, 341 struct dce_watermarks nbp, 342 struct dce_watermarks stutter_exit, 343 struct dce_watermarks stutter_enter, 344 struct dce_watermarks urgent, 345 uint32_t total_dest_line_time_ns) 346 { 347 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 348 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1; 349 350 dce60_program_urgency_watermark(dce_mi, 2, /* set a */ 351 urgent.a_mark, total_dest_line_time_ns); 352 dce60_program_urgency_watermark(dce_mi, 1, /* set d */ 353 urgent.d_mark, total_dest_line_time_ns); 354 355 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL, 356 STUTTER_ENABLE, stutter_en, 357 STUTTER_IGNORE_FBC, 1); 358 dce60_program_nbp_watermark(dce_mi, 2, nbp.a_mark); /* set a */ 359 dce60_program_nbp_watermark(dce_mi, 1, nbp.d_mark); /* set d */ 360 361 dce60_program_stutter_watermark(dce_mi, 2, stutter_exit.a_mark); /* set a */ 362 dce60_program_stutter_watermark(dce_mi, 1, stutter_exit.d_mark); /* set d */ 363 } 364 #endif 365 366 static void dce112_mi_program_display_marks(struct mem_input *mi, 367 struct dce_watermarks nbp, 368 struct dce_watermarks stutter_exit, 369 struct dce_watermarks stutter_entry, 370 struct dce_watermarks urgent, 371 uint32_t total_dest_line_time_ns) 372 { 373 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 374 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1; 375 376 program_urgency_watermark(dce_mi, 0, /* set a */ 377 urgent.a_mark, total_dest_line_time_ns); 378 program_urgency_watermark(dce_mi, 1, /* set b */ 379 urgent.b_mark, total_dest_line_time_ns); 380 program_urgency_watermark(dce_mi, 2, /* set c */ 381 urgent.c_mark, total_dest_line_time_ns); 382 program_urgency_watermark(dce_mi, 3, /* set d */ 383 urgent.d_mark, total_dest_line_time_ns); 384 385 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL, 386 STUTTER_ENABLE, stutter_en, 387 STUTTER_IGNORE_FBC, 1); 388 program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */ 389 program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */ 390 program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */ 391 program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */ 392 393 program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark); /* set a */ 394 program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark); /* set b */ 395 program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark); /* set c */ 396 program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark); /* set d */ 397 } 398 399 static void dce120_mi_program_display_marks(struct mem_input *mi, 400 struct dce_watermarks nbp, 401 struct dce_watermarks stutter_exit, 402 struct dce_watermarks stutter_entry, 403 struct dce_watermarks urgent, 404 uint32_t total_dest_line_time_ns) 405 { 406 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 407 uint32_t stutter_en = mi->ctx->dc->debug.disable_stutter ? 0 : 1; 408 409 dce120_program_urgency_watermark(dce_mi, 0, /* set a */ 410 urgent.a_mark, total_dest_line_time_ns); 411 dce120_program_urgency_watermark(dce_mi, 1, /* set b */ 412 urgent.b_mark, total_dest_line_time_ns); 413 dce120_program_urgency_watermark(dce_mi, 2, /* set c */ 414 urgent.c_mark, total_dest_line_time_ns); 415 dce120_program_urgency_watermark(dce_mi, 3, /* set d */ 416 urgent.d_mark, total_dest_line_time_ns); 417 418 REG_UPDATE_2(DPG_PIPE_STUTTER_CONTROL, 419 STUTTER_ENABLE, stutter_en, 420 STUTTER_IGNORE_FBC, 1); 421 program_nbp_watermark(dce_mi, 0, nbp.a_mark); /* set a */ 422 program_nbp_watermark(dce_mi, 1, nbp.b_mark); /* set b */ 423 program_nbp_watermark(dce_mi, 2, nbp.c_mark); /* set c */ 424 program_nbp_watermark(dce_mi, 3, nbp.d_mark); /* set d */ 425 426 dce120_program_stutter_watermark(dce_mi, 0, stutter_exit.a_mark, stutter_entry.a_mark); /* set a */ 427 dce120_program_stutter_watermark(dce_mi, 1, stutter_exit.b_mark, stutter_entry.b_mark); /* set b */ 428 dce120_program_stutter_watermark(dce_mi, 2, stutter_exit.c_mark, stutter_entry.c_mark); /* set c */ 429 dce120_program_stutter_watermark(dce_mi, 3, stutter_exit.d_mark, stutter_entry.d_mark); /* set d */ 430 } 431 432 static void program_tiling( 433 struct dce_mem_input *dce_mi, const union dc_tiling_info *info) 434 { 435 if (dce_mi->masks->GRPH_SW_MODE) { /* GFX9 */ 436 REG_UPDATE_6(GRPH_CONTROL, 437 GRPH_SW_MODE, info->gfx9.swizzle, 438 GRPH_NUM_BANKS, log_2(info->gfx9.num_banks), 439 GRPH_NUM_SHADER_ENGINES, log_2(info->gfx9.num_shader_engines), 440 GRPH_NUM_PIPES, log_2(info->gfx9.num_pipes), 441 GRPH_COLOR_EXPANSION_MODE, 1, 442 GRPH_SE_ENABLE, info->gfx9.shaderEnable); 443 /* TODO: DCP0_GRPH_CONTROL__GRPH_SE_ENABLE where to get info 444 GRPH_SE_ENABLE, 1, 445 GRPH_Z, 0); 446 */ 447 } 448 449 if (dce_mi->masks->GRPH_MICRO_TILE_MODE) { /* GFX8 */ 450 REG_UPDATE_9(GRPH_CONTROL, 451 GRPH_NUM_BANKS, info->gfx8.num_banks, 452 GRPH_BANK_WIDTH, info->gfx8.bank_width, 453 GRPH_BANK_HEIGHT, info->gfx8.bank_height, 454 GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect, 455 GRPH_TILE_SPLIT, info->gfx8.tile_split, 456 GRPH_MICRO_TILE_MODE, info->gfx8.tile_mode, 457 GRPH_PIPE_CONFIG, info->gfx8.pipe_config, 458 GRPH_ARRAY_MODE, info->gfx8.array_mode, 459 GRPH_COLOR_EXPANSION_MODE, 1); 460 /* 01 - DCP_GRPH_COLOR_EXPANSION_MODE_ZEXP: zero expansion for YCbCr */ 461 /* 462 GRPH_Z, 0); 463 */ 464 } 465 466 if (dce_mi->masks->GRPH_ARRAY_MODE) { /* GFX6 but reuses gfx8 struct */ 467 REG_UPDATE_8(GRPH_CONTROL, 468 GRPH_NUM_BANKS, info->gfx8.num_banks, 469 GRPH_BANK_WIDTH, info->gfx8.bank_width, 470 GRPH_BANK_HEIGHT, info->gfx8.bank_height, 471 GRPH_MACRO_TILE_ASPECT, info->gfx8.tile_aspect, 472 GRPH_TILE_SPLIT, info->gfx8.tile_split, 473 /* DCE6 has no GRPH_MICRO_TILE_MODE mask */ 474 GRPH_PIPE_CONFIG, info->gfx8.pipe_config, 475 GRPH_ARRAY_MODE, info->gfx8.array_mode, 476 GRPH_COLOR_EXPANSION_MODE, 1); 477 /* 01 - DCP_GRPH_COLOR_EXPANSION_MODE_ZEXP: zero expansion for YCbCr */ 478 /* 479 GRPH_Z, 0); 480 */ 481 } 482 } 483 484 485 static void program_size_and_rotation( 486 struct dce_mem_input *dce_mi, 487 enum dc_rotation_angle rotation, 488 const struct plane_size *plane_size) 489 { 490 const struct rect *in_rect = &plane_size->surface_size; 491 struct rect hw_rect = plane_size->surface_size; 492 const uint32_t rotation_angles[ROTATION_ANGLE_COUNT] = { 493 [ROTATION_ANGLE_0] = 0, 494 [ROTATION_ANGLE_90] = 1, 495 [ROTATION_ANGLE_180] = 2, 496 [ROTATION_ANGLE_270] = 3, 497 }; 498 499 if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) { 500 hw_rect.x = in_rect->y; 501 hw_rect.y = in_rect->x; 502 503 hw_rect.height = in_rect->width; 504 hw_rect.width = in_rect->height; 505 } 506 507 REG_SET(GRPH_X_START, 0, 508 GRPH_X_START, hw_rect.x); 509 510 REG_SET(GRPH_Y_START, 0, 511 GRPH_Y_START, hw_rect.y); 512 513 REG_SET(GRPH_X_END, 0, 514 GRPH_X_END, hw_rect.width); 515 516 REG_SET(GRPH_Y_END, 0, 517 GRPH_Y_END, hw_rect.height); 518 519 REG_SET(GRPH_PITCH, 0, 520 GRPH_PITCH, plane_size->surface_pitch); 521 522 REG_SET(HW_ROTATION, 0, 523 GRPH_ROTATION_ANGLE, rotation_angles[rotation]); 524 } 525 526 #if defined(CONFIG_DRM_AMD_DC_SI) 527 static void dce60_program_size( 528 struct dce_mem_input *dce_mi, 529 enum dc_rotation_angle rotation, /* not used in DCE6 */ 530 const struct plane_size *plane_size) 531 { 532 struct rect hw_rect = plane_size->surface_size; 533 /* DCE6 has no HW rotation, skip rotation_angles declaration */ 534 535 /* DCE6 has no HW rotation, skip ROTATION_ANGLE_* processing */ 536 537 REG_SET(GRPH_X_START, 0, 538 GRPH_X_START, hw_rect.x); 539 540 REG_SET(GRPH_Y_START, 0, 541 GRPH_Y_START, hw_rect.y); 542 543 REG_SET(GRPH_X_END, 0, 544 GRPH_X_END, hw_rect.width); 545 546 REG_SET(GRPH_Y_END, 0, 547 GRPH_Y_END, hw_rect.height); 548 549 REG_SET(GRPH_PITCH, 0, 550 GRPH_PITCH, plane_size->surface_pitch); 551 552 /* DCE6 has no HW_ROTATION register, skip setting rotation_angles */ 553 } 554 #endif 555 556 static void program_grph_pixel_format( 557 struct dce_mem_input *dce_mi, 558 enum surface_pixel_format format) 559 { 560 uint32_t red_xbar = 0, blue_xbar = 0; /* no swap */ 561 uint32_t grph_depth = 0, grph_format = 0; 562 uint32_t sign = 0, floating = 0; 563 564 if (format == SURFACE_PIXEL_FORMAT_GRPH_ABGR8888 || 565 /*todo: doesn't look like we handle BGRA here, 566 * should problem swap endian*/ 567 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010 || 568 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS || 569 format == SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F) { 570 /* ABGR formats */ 571 red_xbar = 2; 572 blue_xbar = 2; 573 } 574 575 REG_SET_2(GRPH_SWAP_CNTL, 0, 576 GRPH_RED_CROSSBAR, red_xbar, 577 GRPH_BLUE_CROSSBAR, blue_xbar); 578 579 switch (format) { 580 case SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS: 581 grph_depth = 0; 582 grph_format = 0; 583 break; 584 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 585 grph_depth = 1; 586 grph_format = 0; 587 break; 588 case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 589 grph_depth = 1; 590 grph_format = 1; 591 break; 592 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 593 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 594 grph_depth = 2; 595 grph_format = 0; 596 break; 597 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 598 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 599 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: 600 grph_depth = 2; 601 grph_format = 1; 602 break; 603 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 604 sign = 1; 605 floating = 1; 606 fallthrough; 607 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: /* shouldn't this get float too? */ 608 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 609 grph_depth = 3; 610 grph_format = 0; 611 break; 612 default: 613 DC_ERR("unsupported grph pixel format"); 614 break; 615 } 616 617 REG_UPDATE_2(GRPH_CONTROL, 618 GRPH_DEPTH, grph_depth, 619 GRPH_FORMAT, grph_format); 620 621 REG_UPDATE_4(PRESCALE_GRPH_CONTROL, 622 GRPH_PRESCALE_SELECT, floating, 623 GRPH_PRESCALE_R_SIGN, sign, 624 GRPH_PRESCALE_G_SIGN, sign, 625 GRPH_PRESCALE_B_SIGN, sign); 626 } 627 628 static void dce_mi_program_surface_config( 629 struct mem_input *mi, 630 enum surface_pixel_format format, 631 union dc_tiling_info *tiling_info, 632 struct plane_size *plane_size, 633 enum dc_rotation_angle rotation, 634 struct dc_plane_dcc_param *dcc, 635 bool horizontal_mirror) 636 { 637 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 638 REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1); 639 640 program_tiling(dce_mi, tiling_info); 641 program_size_and_rotation(dce_mi, rotation, plane_size); 642 643 if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN && 644 format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 645 program_grph_pixel_format(dce_mi, format); 646 } 647 648 #if defined(CONFIG_DRM_AMD_DC_SI) 649 static void dce60_mi_program_surface_config( 650 struct mem_input *mi, 651 enum surface_pixel_format format, 652 union dc_tiling_info *tiling_info, 653 struct plane_size *plane_size, 654 enum dc_rotation_angle rotation, /* not used in DCE6 */ 655 struct dc_plane_dcc_param *dcc, 656 bool horizontal_mirror) 657 { 658 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 659 REG_UPDATE(GRPH_ENABLE, GRPH_ENABLE, 1); 660 661 program_tiling(dce_mi, tiling_info); 662 dce60_program_size(dce_mi, rotation, plane_size); 663 664 if (format >= SURFACE_PIXEL_FORMAT_GRPH_BEGIN && 665 format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 666 program_grph_pixel_format(dce_mi, format); 667 } 668 #endif 669 670 static uint32_t get_dmif_switch_time_us( 671 uint32_t h_total, 672 uint32_t v_total, 673 uint32_t pix_clk_khz) 674 { 675 uint32_t frame_time; 676 uint32_t pixels_per_second; 677 uint32_t pixels_per_frame; 678 uint32_t refresh_rate; 679 const uint32_t us_in_sec = 1000000; 680 const uint32_t min_single_frame_time_us = 30000; 681 /*return double of frame time*/ 682 const uint32_t single_frame_time_multiplier = 2; 683 684 if (!h_total || v_total || !pix_clk_khz) 685 return single_frame_time_multiplier * min_single_frame_time_us; 686 687 /*TODO: should we use pixel format normalized pixel clock here?*/ 688 pixels_per_second = pix_clk_khz * 1000; 689 pixels_per_frame = h_total * v_total; 690 691 if (!pixels_per_second || !pixels_per_frame) { 692 /* avoid division by zero */ 693 ASSERT(pixels_per_frame); 694 ASSERT(pixels_per_second); 695 return single_frame_time_multiplier * min_single_frame_time_us; 696 } 697 698 refresh_rate = pixels_per_second / pixels_per_frame; 699 700 if (!refresh_rate) { 701 /* avoid division by zero*/ 702 ASSERT(refresh_rate); 703 return single_frame_time_multiplier * min_single_frame_time_us; 704 } 705 706 frame_time = us_in_sec / refresh_rate; 707 708 if (frame_time < min_single_frame_time_us) 709 frame_time = min_single_frame_time_us; 710 711 frame_time *= single_frame_time_multiplier; 712 713 return frame_time; 714 } 715 716 static void dce_mi_allocate_dmif( 717 struct mem_input *mi, 718 uint32_t h_total, 719 uint32_t v_total, 720 uint32_t pix_clk_khz, 721 uint32_t total_stream_num) 722 { 723 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 724 const uint32_t retry_delay = 10; 725 uint32_t retry_count = get_dmif_switch_time_us( 726 h_total, 727 v_total, 728 pix_clk_khz) / retry_delay; 729 730 uint32_t pix_dur; 731 uint32_t buffers_allocated; 732 uint32_t dmif_buffer_control; 733 734 dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL, 735 DMIF_BUFFERS_ALLOCATED, &buffers_allocated); 736 737 if (buffers_allocated == 2) 738 return; 739 740 REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control, 741 DMIF_BUFFERS_ALLOCATED, 2); 742 743 REG_WAIT(DMIF_BUFFER_CONTROL, 744 DMIF_BUFFERS_ALLOCATION_COMPLETED, 1, 745 retry_delay, retry_count); 746 747 if (pix_clk_khz != 0) { 748 pix_dur = 1000000000ULL / pix_clk_khz; 749 750 REG_UPDATE(DPG_PIPE_ARBITRATION_CONTROL1, 751 PIXEL_DURATION, pix_dur); 752 } 753 754 if (dce_mi->wa.single_head_rdreq_dmif_limit) { 755 uint32_t enable = (total_stream_num > 1) ? 0 : 756 dce_mi->wa.single_head_rdreq_dmif_limit; 757 758 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT, 759 ENABLE, enable); 760 } 761 } 762 763 static void dce_mi_free_dmif( 764 struct mem_input *mi, 765 uint32_t total_stream_num) 766 { 767 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mi); 768 uint32_t buffers_allocated; 769 uint32_t dmif_buffer_control; 770 771 dmif_buffer_control = REG_GET(DMIF_BUFFER_CONTROL, 772 DMIF_BUFFERS_ALLOCATED, &buffers_allocated); 773 774 if (buffers_allocated == 0) 775 return; 776 777 REG_SET(DMIF_BUFFER_CONTROL, dmif_buffer_control, 778 DMIF_BUFFERS_ALLOCATED, 0); 779 780 REG_WAIT(DMIF_BUFFER_CONTROL, 781 DMIF_BUFFERS_ALLOCATION_COMPLETED, 1, 782 10, 3500); 783 784 if (dce_mi->wa.single_head_rdreq_dmif_limit) { 785 uint32_t enable = (total_stream_num > 1) ? 0 : 786 dce_mi->wa.single_head_rdreq_dmif_limit; 787 788 REG_UPDATE(MC_HUB_RDREQ_DMIF_LIMIT, 789 ENABLE, enable); 790 } 791 } 792 793 794 static void program_sec_addr( 795 struct dce_mem_input *dce_mi, 796 PHYSICAL_ADDRESS_LOC address) 797 { 798 /*high register MUST be programmed first*/ 799 REG_SET(GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 0, 800 GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 801 address.high_part); 802 803 REG_SET_2(GRPH_SECONDARY_SURFACE_ADDRESS, 0, 804 GRPH_SECONDARY_SURFACE_ADDRESS, address.low_part >> 8, 805 GRPH_SECONDARY_DFQ_ENABLE, 0); 806 } 807 808 static void program_pri_addr( 809 struct dce_mem_input *dce_mi, 810 PHYSICAL_ADDRESS_LOC address) 811 { 812 /*high register MUST be programmed first*/ 813 REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 0, 814 GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 815 address.high_part); 816 817 REG_SET(GRPH_PRIMARY_SURFACE_ADDRESS, 0, 818 GRPH_PRIMARY_SURFACE_ADDRESS, 819 address.low_part >> 8); 820 } 821 822 823 static bool dce_mi_is_flip_pending(struct mem_input *mem_input) 824 { 825 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input); 826 uint32_t update_pending; 827 828 REG_GET(GRPH_UPDATE, GRPH_SURFACE_UPDATE_PENDING, &update_pending); 829 if (update_pending) 830 return true; 831 832 mem_input->current_address = mem_input->request_address; 833 return false; 834 } 835 836 static bool dce_mi_program_surface_flip_and_addr( 837 struct mem_input *mem_input, 838 const struct dc_plane_address *address, 839 bool flip_immediate) 840 { 841 struct dce_mem_input *dce_mi = TO_DCE_MEM_INPUT(mem_input); 842 843 REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 1); 844 845 REG_UPDATE( 846 GRPH_FLIP_CONTROL, 847 GRPH_SURFACE_UPDATE_H_RETRACE_EN, flip_immediate ? 1 : 0); 848 849 switch (address->type) { 850 case PLN_ADDR_TYPE_GRAPHICS: 851 if (address->grph.addr.quad_part == 0) 852 break; 853 program_pri_addr(dce_mi, address->grph.addr); 854 break; 855 case PLN_ADDR_TYPE_GRPH_STEREO: 856 if (address->grph_stereo.left_addr.quad_part == 0 || 857 address->grph_stereo.right_addr.quad_part == 0) 858 break; 859 program_pri_addr(dce_mi, address->grph_stereo.left_addr); 860 program_sec_addr(dce_mi, address->grph_stereo.right_addr); 861 break; 862 default: 863 /* not supported */ 864 BREAK_TO_DEBUGGER(); 865 break; 866 } 867 868 mem_input->request_address = *address; 869 870 if (flip_immediate) 871 mem_input->current_address = *address; 872 873 REG_UPDATE(GRPH_UPDATE, GRPH_UPDATE_LOCK, 0); 874 875 return true; 876 } 877 878 static const struct mem_input_funcs dce_mi_funcs = { 879 .mem_input_program_display_marks = dce_mi_program_display_marks, 880 .allocate_mem_input = dce_mi_allocate_dmif, 881 .free_mem_input = dce_mi_free_dmif, 882 .mem_input_program_surface_flip_and_addr = 883 dce_mi_program_surface_flip_and_addr, 884 .mem_input_program_pte_vm = dce_mi_program_pte_vm, 885 .mem_input_program_surface_config = 886 dce_mi_program_surface_config, 887 .mem_input_is_flip_pending = dce_mi_is_flip_pending 888 }; 889 890 #if defined(CONFIG_DRM_AMD_DC_SI) 891 static const struct mem_input_funcs dce60_mi_funcs = { 892 .mem_input_program_display_marks = dce60_mi_program_display_marks, 893 .allocate_mem_input = dce_mi_allocate_dmif, 894 .free_mem_input = dce_mi_free_dmif, 895 .mem_input_program_surface_flip_and_addr = 896 dce_mi_program_surface_flip_and_addr, 897 .mem_input_program_pte_vm = dce_mi_program_pte_vm, 898 .mem_input_program_surface_config = 899 dce60_mi_program_surface_config, 900 .mem_input_is_flip_pending = dce_mi_is_flip_pending 901 }; 902 #endif 903 904 static const struct mem_input_funcs dce112_mi_funcs = { 905 .mem_input_program_display_marks = dce112_mi_program_display_marks, 906 .allocate_mem_input = dce_mi_allocate_dmif, 907 .free_mem_input = dce_mi_free_dmif, 908 .mem_input_program_surface_flip_and_addr = 909 dce_mi_program_surface_flip_and_addr, 910 .mem_input_program_pte_vm = dce_mi_program_pte_vm, 911 .mem_input_program_surface_config = 912 dce_mi_program_surface_config, 913 .mem_input_is_flip_pending = dce_mi_is_flip_pending 914 }; 915 916 static const struct mem_input_funcs dce120_mi_funcs = { 917 .mem_input_program_display_marks = dce120_mi_program_display_marks, 918 .allocate_mem_input = dce_mi_allocate_dmif, 919 .free_mem_input = dce_mi_free_dmif, 920 .mem_input_program_surface_flip_and_addr = 921 dce_mi_program_surface_flip_and_addr, 922 .mem_input_program_pte_vm = dce_mi_program_pte_vm, 923 .mem_input_program_surface_config = 924 dce_mi_program_surface_config, 925 .mem_input_is_flip_pending = dce_mi_is_flip_pending 926 }; 927 928 void dce_mem_input_construct( 929 struct dce_mem_input *dce_mi, 930 struct dc_context *ctx, 931 int inst, 932 const struct dce_mem_input_registers *regs, 933 const struct dce_mem_input_shift *mi_shift, 934 const struct dce_mem_input_mask *mi_mask) 935 { 936 dce_mi->base.ctx = ctx; 937 938 dce_mi->base.inst = inst; 939 dce_mi->base.funcs = &dce_mi_funcs; 940 941 dce_mi->regs = regs; 942 dce_mi->shifts = mi_shift; 943 dce_mi->masks = mi_mask; 944 } 945 946 #if defined(CONFIG_DRM_AMD_DC_SI) 947 void dce60_mem_input_construct( 948 struct dce_mem_input *dce_mi, 949 struct dc_context *ctx, 950 int inst, 951 const struct dce_mem_input_registers *regs, 952 const struct dce_mem_input_shift *mi_shift, 953 const struct dce_mem_input_mask *mi_mask) 954 { 955 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); 956 dce_mi->base.funcs = &dce60_mi_funcs; 957 } 958 #endif 959 960 void dce112_mem_input_construct( 961 struct dce_mem_input *dce_mi, 962 struct dc_context *ctx, 963 int inst, 964 const struct dce_mem_input_registers *regs, 965 const struct dce_mem_input_shift *mi_shift, 966 const struct dce_mem_input_mask *mi_mask) 967 { 968 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); 969 dce_mi->base.funcs = &dce112_mi_funcs; 970 } 971 972 void dce120_mem_input_construct( 973 struct dce_mem_input *dce_mi, 974 struct dc_context *ctx, 975 int inst, 976 const struct dce_mem_input_registers *regs, 977 const struct dce_mem_input_shift *mi_shift, 978 const struct dce_mem_input_mask *mi_mask) 979 { 980 dce_mem_input_construct(dce_mi, ctx, inst, regs, mi_shift, mi_mask); 981 dce_mi->base.funcs = &dce120_mi_funcs; 982 } 983