1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright 2022-2026 Advanced Micro Devices, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: AMD 24 * 25 */ 26 27 #include <drm/drm_atomic_helper.h> 28 #include <drm/drm_blend.h> 29 #include "drm/drm_framebuffer.h" 30 #include <drm/drm_gem_atomic_helper.h> 31 #include <drm/drm_plane_helper.h> 32 #include <drm/drm_gem_framebuffer_helper.h> 33 #include <drm/drm_fourcc.h> 34 35 #include "amdgpu.h" 36 #include "dal_asic_id.h" 37 #include "amdgpu_display.h" 38 #include "amdgpu_dm_trace.h" 39 #include "amdgpu_dm_plane.h" 40 #include "dm_helpers.h" 41 #include "amdgpu_dm_colorop.h" 42 #include "gc/gc_11_0_0_offset.h" 43 #include "gc/gc_11_0_0_sh_mask.h" 44 45 /* 46 * TODO: these are currently initialized to rgb formats only. 47 * For future use cases we should either initialize them dynamically based on 48 * plane capabilities, or initialize this array to all formats, so internal drm 49 * check will succeed, and let DC implement proper check 50 */ 51 static const uint32_t rgb_formats[] = { 52 DRM_FORMAT_XRGB8888, 53 DRM_FORMAT_ARGB8888, 54 DRM_FORMAT_RGBA8888, 55 DRM_FORMAT_XRGB2101010, 56 DRM_FORMAT_XBGR2101010, 57 DRM_FORMAT_ARGB2101010, 58 DRM_FORMAT_ABGR2101010, 59 DRM_FORMAT_XRGB16161616, 60 DRM_FORMAT_XBGR16161616, 61 DRM_FORMAT_ARGB16161616, 62 DRM_FORMAT_ABGR16161616, 63 DRM_FORMAT_XBGR8888, 64 DRM_FORMAT_ABGR8888, 65 DRM_FORMAT_RGB565, 66 }; 67 68 static const uint32_t overlay_formats[] = { 69 DRM_FORMAT_XRGB8888, 70 DRM_FORMAT_ARGB8888, 71 DRM_FORMAT_RGBA8888, 72 DRM_FORMAT_XBGR8888, 73 DRM_FORMAT_ABGR8888, 74 DRM_FORMAT_RGB565, 75 DRM_FORMAT_NV21, 76 DRM_FORMAT_NV12, 77 DRM_FORMAT_P010 78 }; 79 80 static const uint32_t video_formats[] = { 81 DRM_FORMAT_NV21, 82 DRM_FORMAT_NV12, 83 DRM_FORMAT_P010 84 }; 85 86 static const u32 cursor_formats[] = { 87 DRM_FORMAT_ARGB8888 88 }; 89 90 enum dm_micro_swizzle { 91 MICRO_SWIZZLE_Z = 0, 92 MICRO_SWIZZLE_S = 1, 93 MICRO_SWIZZLE_D = 2, 94 MICRO_SWIZZLE_R = 3 95 }; 96 97 const struct drm_format_info *amdgpu_dm_plane_get_format_info(u32 pixel_format, u64 modifier) 98 { 99 return amdgpu_lookup_format_info(pixel_format, modifier); 100 } 101 EXPORT_IF_KUNIT(amdgpu_dm_plane_get_format_info); 102 103 void amdgpu_dm_plane_fill_blending_from_plane_state(const struct drm_plane_state *plane_state, 104 bool *per_pixel_alpha, bool *pre_multiplied_alpha, 105 bool *global_alpha, int *global_alpha_value) 106 { 107 *per_pixel_alpha = false; 108 *pre_multiplied_alpha = true; 109 *global_alpha = false; 110 *global_alpha_value = 0xff; 111 112 113 if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI || 114 plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) { 115 *per_pixel_alpha = plane_state->fb->format->has_alpha; 116 117 if (*per_pixel_alpha && plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) 118 *pre_multiplied_alpha = false; 119 } 120 121 if (plane_state->alpha < 0xffff) { 122 struct amdgpu_device *adev = drm_to_adev(plane_state->plane->dev); 123 *global_alpha = true; 124 /* 125 * DCN 4.2 uses a 12-bit MPCC_GLOBAL_ALPHA field, while 126 * other ASICs use an 8-bit field. The DRM plane alpha is 127 * 16-bit, so scale it down to the width the hardware expects. 128 */ 129 if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 2, 0) 130 || amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(6, 0, 0)) 131 *global_alpha_value = plane_state->alpha >> 4; 132 else 133 *global_alpha_value = plane_state->alpha >> 8; 134 135 } 136 } 137 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_blending_from_plane_state); 138 139 STATIC_IFN_KUNIT void amdgpu_dm_plane_add_modifier(uint64_t **mods, uint64_t *size, 140 uint64_t *cap, uint64_t mod) 141 { 142 if (!*mods) 143 return; 144 145 if (*cap - *size < 1) { 146 uint64_t new_cap = *cap * 2; 147 uint64_t *new_mods = kmalloc_array(new_cap, sizeof(uint64_t), GFP_KERNEL); 148 149 if (!new_mods) { 150 kfree(*mods); 151 *mods = NULL; 152 return; 153 } 154 155 memcpy(new_mods, *mods, sizeof(uint64_t) * *size); 156 kfree(*mods); 157 *mods = new_mods; 158 *cap = new_cap; 159 } 160 161 (*mods)[*size] = mod; 162 *size += 1; 163 } 164 EXPORT_IF_KUNIT(amdgpu_dm_plane_add_modifier); 165 166 STATIC_IFN_KUNIT void amdgpu_dm_plane_add_modifier_dedup(uint64_t **mods, uint64_t *size, 167 uint64_t *cap, uint64_t mod) 168 { 169 uint64_t i; 170 171 if (!*mods) 172 return; 173 174 for (i = 0; i < *size; ++i) 175 if ((*mods)[i] == mod) 176 return; 177 178 amdgpu_dm_plane_add_modifier(mods, size, cap, mod); 179 } 180 EXPORT_IF_KUNIT(amdgpu_dm_plane_add_modifier_dedup); 181 182 STATIC_IFN_KUNIT bool amdgpu_dm_plane_modifier_has_dcc(uint64_t modifier) 183 { 184 return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier); 185 } 186 EXPORT_IF_KUNIT(amdgpu_dm_plane_modifier_has_dcc); 187 188 STATIC_IFN_KUNIT unsigned int amdgpu_dm_plane_modifier_gfx9_swizzle_mode(uint64_t modifier) 189 { 190 if (modifier == DRM_FORMAT_MOD_LINEAR) 191 return 0; 192 193 return AMD_FMT_MOD_GET(TILE, modifier); 194 } 195 EXPORT_IF_KUNIT(amdgpu_dm_plane_modifier_gfx9_swizzle_mode); 196 197 STATIC_IFN_KUNIT int amdgpu_dm_plane_fill_gfx6_tiling_info_from_modifier( 198 struct dc_tiling_info *tiling_info, 199 uint64_t modifier) 200 { 201 if (modifier == DRM_FORMAT_MOD_LINEAR) { 202 tiling_info->gfx8.array_mode = DC_ARRAY_LINEAR_GENERAL; 203 tiling_info->gfxversion = DcGfxVersion8; 204 205 return 0; 206 } 207 208 if (!IS_AMD_FMT_MOD(modifier)) 209 return -EINVAL; 210 211 if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) != AMD_FMT_MOD_TILE_VER_GFX6) 212 return -EINVAL; 213 214 tiling_info->gfx8.array_mode = AMD_FMT_MOD_GET(TILE, modifier); 215 tiling_info->gfxversion = DcGfxVersion8; 216 tiling_info->gfx8.tile_mode = AMD_FMT_MOD_GET(MICROTILE, modifier); 217 218 if (AMD_FMT_MOD_GET(TILE, modifier) < AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1) 219 return 0; 220 221 tiling_info->gfx8.pipe_config = AMD_FMT_MOD_GET(PIPE_CONFIG, modifier); 222 tiling_info->gfx8.tile_split = AMD_FMT_MOD_GET(TILE_SPLIT, modifier); 223 tiling_info->gfx8.bank_width = AMD_FMT_MOD_GET(BANK_WIDTH, modifier); 224 tiling_info->gfx8.bank_height = AMD_FMT_MOD_GET(BANK_HEIGHT, modifier); 225 tiling_info->gfx8.tile_aspect = AMD_FMT_MOD_GET(MACRO_TILE_ASPECT, modifier); 226 tiling_info->gfx8.num_banks = AMD_FMT_MOD_GET(NUM_BANKS, modifier); 227 228 return 0; 229 } 230 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_gfx6_tiling_info_from_modifier); 231 232 STATIC_IFN_KUNIT void amdgpu_dm_plane_fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev, 233 struct dc_tiling_info *tiling_info) 234 { 235 /* Fill GFX9 params */ 236 tiling_info->gfx9.num_pipes = 237 adev->gfx.config.gb_addr_config_fields.num_pipes; 238 tiling_info->gfx9.num_banks = 239 adev->gfx.config.gb_addr_config_fields.num_banks; 240 tiling_info->gfx9.pipe_interleave = 241 adev->gfx.config.gb_addr_config_fields.pipe_interleave_size; 242 tiling_info->gfx9.num_shader_engines = 243 adev->gfx.config.gb_addr_config_fields.num_se; 244 tiling_info->gfx9.max_compressed_frags = 245 adev->gfx.config.gb_addr_config_fields.max_compress_frags; 246 tiling_info->gfx9.num_rb_per_se = 247 adev->gfx.config.gb_addr_config_fields.num_rb_per_se; 248 tiling_info->gfx9.shaderEnable = 1; 249 if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 3, 0)) 250 tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs; 251 } 252 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_gfx9_tiling_info_from_device); 253 254 STATIC_IFN_KUNIT void amdgpu_dm_plane_fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev, 255 struct dc_tiling_info *tiling_info, 256 uint64_t modifier) 257 { 258 unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier); 259 unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier); 260 unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier); 261 unsigned int pipes_log2; 262 263 pipes_log2 = min(5u, mod_pipe_xor_bits); 264 265 amdgpu_dm_plane_fill_gfx9_tiling_info_from_device(adev, tiling_info); 266 267 if (!IS_AMD_FMT_MOD(modifier)) 268 return; 269 270 tiling_info->gfx9.num_pipes = 1u << pipes_log2; 271 tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - pipes_log2); 272 273 if (adev->family >= AMDGPU_FAMILY_NV) { 274 tiling_info->gfx9.num_pkrs = 1u << pkrs_log2; 275 } else { 276 tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits; 277 278 /* for DCC we know it isn't rb aligned, so rb_per_se doesn't matter. */ 279 } 280 } 281 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_gfx9_tiling_info_from_modifier); 282 283 STATIC_IFN_KUNIT int amdgpu_dm_plane_validate_dcc(struct amdgpu_device *adev, 284 const enum surface_pixel_format format, 285 const enum dc_rotation_angle rotation, 286 const struct dc_tiling_info *tiling_info, 287 const struct dc_plane_dcc_param *dcc, 288 const struct dc_plane_address *address, 289 const struct plane_size *plane_size) 290 { 291 struct dc *dc = adev->dm.dc; 292 struct dc_dcc_surface_param input; 293 struct dc_surface_dcc_cap output; 294 295 memset(&input, 0, sizeof(input)); 296 memset(&output, 0, sizeof(output)); 297 298 if (!dcc->enable) 299 return 0; 300 301 if (adev->family != AMDGPU_FAMILY_GC_12_0_0 && 302 adev->family != AMDGPU_FAMILY_GC_13_0_1 && 303 format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) 304 return -EINVAL; 305 306 if (!dc->cap_funcs.get_dcc_compression_cap) 307 return -EINVAL; 308 309 input.format = format; 310 input.surface_size.width = plane_size->surface_size.width; 311 input.surface_size.height = plane_size->surface_size.height; 312 input.swizzle_mode = tiling_info->gfx9.swizzle; 313 314 if (rotation == ROTATION_ANGLE_0 || rotation == ROTATION_ANGLE_180) 315 input.scan = SCAN_DIRECTION_HORIZONTAL; 316 else if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270) 317 input.scan = SCAN_DIRECTION_VERTICAL; 318 319 if (!dc->cap_funcs.get_dcc_compression_cap(dc, &input, &output)) 320 return -EINVAL; 321 322 if (!output.capable) 323 return -EINVAL; 324 325 if (dcc->independent_64b_blks == 0 && 326 output.grph.rgb.independent_64b_blks != 0) 327 return -EINVAL; 328 329 return 0; 330 } 331 EXPORT_IF_KUNIT(amdgpu_dm_plane_validate_dcc); 332 333 STATIC_IFN_KUNIT int amdgpu_dm_plane_fill_gfx9_attrs_from_modifiers(struct amdgpu_device *adev, 334 const struct amdgpu_framebuffer *afb, 335 const enum surface_pixel_format format, 336 const enum dc_rotation_angle rotation, 337 const struct plane_size *plane_size, 338 struct dc_tiling_info *tiling_info, 339 struct dc_plane_dcc_param *dcc, 340 struct dc_plane_address *address) 341 { 342 const uint64_t modifier = afb->base.modifier; 343 int ret = 0; 344 345 amdgpu_dm_plane_fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier); 346 tiling_info->gfx9.swizzle = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier); 347 tiling_info->gfxversion = DcGfxVersion9; 348 349 if (amdgpu_dm_plane_modifier_has_dcc(modifier)) { 350 uint64_t dcc_address = afb->address + afb->base.offsets[1]; 351 bool independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier); 352 bool independent_128b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier); 353 354 dcc->enable = 1; 355 dcc->meta_pitch = afb->base.pitches[1]; 356 dcc->independent_64b_blks = independent_64b_blks; 357 if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) { 358 if (independent_64b_blks && independent_128b_blks) 359 dcc->dcc_ind_blk = hubp_ind_block_64b_no_128bcl; 360 else if (independent_128b_blks) 361 dcc->dcc_ind_blk = hubp_ind_block_128b; 362 else if (independent_64b_blks && !independent_128b_blks) 363 dcc->dcc_ind_blk = hubp_ind_block_64b; 364 else 365 dcc->dcc_ind_blk = hubp_ind_block_unconstrained; 366 } else { 367 if (independent_64b_blks) 368 dcc->dcc_ind_blk = hubp_ind_block_64b; 369 else 370 dcc->dcc_ind_blk = hubp_ind_block_unconstrained; 371 } 372 373 address->grph.meta_addr.low_part = lower_32_bits(dcc_address); 374 address->grph.meta_addr.high_part = upper_32_bits(dcc_address); 375 } 376 377 ret = amdgpu_dm_plane_validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size); 378 if (ret) 379 drm_dbg_kms(adev_to_drm(adev), "amdgpu_dm_plane_validate_dcc: returned error: %pe\n", ERR_PTR(ret)); 380 381 return ret; 382 } 383 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_gfx9_attrs_from_modifiers); 384 385 STATIC_IFN_KUNIT int amdgpu_dm_plane_fill_gfx12_attrs_from_modifiers(struct amdgpu_device *adev, 386 const struct amdgpu_framebuffer *afb, 387 const enum surface_pixel_format format, 388 const enum dc_rotation_angle rotation, 389 const struct plane_size *plane_size, 390 struct dc_tiling_info *tiling_info, 391 struct dc_plane_dcc_param *dcc, 392 struct dc_plane_address *address) 393 { 394 const uint64_t modifier = afb->base.modifier; 395 int ret = 0; 396 397 /* TODO: Most of this function shouldn't be needed on GFX12. */ 398 amdgpu_dm_plane_fill_gfx9_tiling_info_from_device(adev, tiling_info); 399 400 tiling_info->gfx9.swizzle = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier); 401 tiling_info->gfxversion = DcGfxAddr3; 402 403 if (amdgpu_dm_plane_modifier_has_dcc(modifier)) { 404 int max_compressed_block = AMD_FMT_MOD_GET(DCC_MAX_COMPRESSED_BLOCK, modifier); 405 406 dcc->enable = 1; 407 dcc->independent_64b_blks = max_compressed_block == 0; 408 409 if (max_compressed_block == 0) 410 dcc->dcc_ind_blk = hubp_ind_block_64b; 411 else if (max_compressed_block == 1) 412 dcc->dcc_ind_blk = hubp_ind_block_128b; 413 else 414 dcc->dcc_ind_blk = hubp_ind_block_unconstrained; 415 } 416 417 /* TODO: This seems wrong because there is no DCC plane on GFX12. */ 418 ret = amdgpu_dm_plane_validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size); 419 if (ret) 420 drm_dbg_kms(adev_to_drm(adev), "amdgpu_dm_plane_validate_dcc: returned: %pe\n", ERR_PTR(ret)); 421 422 return ret; 423 } 424 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_gfx12_attrs_from_modifiers); 425 426 static void amdgpu_dm_plane_add_gfx10_1_modifiers(const struct amdgpu_device *adev, 427 uint64_t **mods, 428 uint64_t *size, 429 uint64_t *capacity) 430 { 431 int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes); 432 433 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 434 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 435 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | 436 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 437 AMD_FMT_MOD_SET(DCC, 1) | 438 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | 439 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 440 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); 441 442 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 443 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 444 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | 445 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 446 AMD_FMT_MOD_SET(DCC, 1) | 447 AMD_FMT_MOD_SET(DCC_RETILE, 1) | 448 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | 449 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 450 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); 451 452 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 453 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 454 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | 455 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits)); 456 457 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 458 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | 459 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) | 460 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits)); 461 462 463 /* Only supported for 64bpp, will be filtered in amdgpu_dm_plane_format_mod_supported */ 464 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 465 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) | 466 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); 467 468 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 469 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) | 470 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); 471 } 472 473 /** 474 * amdgpu_dm_plane_get_gfx6_tile_idx() - Get tile mode index on GFX6-8 475 * 476 * @adev: amdgpu_device pointer 477 * @bpp: bits per pixel in the image 478 * @arr: array mode (aka. tile mode) of the image layout 479 * 480 * Select which tiling mode from the table is suitable for the given bits per pixel 481 * using the given array mode, assuming the displayable micro tile mode is used. 482 * 483 * On GFX6-8, the GFX block can only use pre-programmed tiling modes from GB_TILE_MODEn 484 * registers which are programmed by the kernel according to the tiling mode table. 485 * Note that the tiling table is uAPI and userspace relies on specific modes being 486 * present at specific indices. 487 * See SiLib::HwlSetupTileInfo() and CiLib::HwlSetupTileInfo() in addrlib. 488 */ 489 static u32 amdgpu_dm_plane_get_gfx6_tile_idx(const struct amdgpu_device *adev, 490 const u32 bpp, 491 const enum array_mode_values arr) 492 { 493 /* Assume that the microtile mode is DISPLAY. */ 494 495 if (arr == DC_ARRAY_1D_TILED_THIN1) 496 return 9; 497 498 ASSERT(arr == DC_ARRAY_2D_TILED_THIN1); 499 500 if (adev->family > AMDGPU_FAMILY_SI) 501 return 10; 502 503 switch (bpp) { 504 case 8: 505 return 10; 506 case 16: 507 return 11; 508 default: 509 return 12; 510 } 511 } 512 513 /** 514 * amdgpu_dm_plane_calc_gfx7_tile_split() - Calculate tile split on GFX7-8 515 * 516 * @adev: amdgpu_device pointer 517 * @bpp: bits per pixel in the image 518 * @gb_tile_mode: GB_TILE_MODEn register value for the current tiling mode 519 * 520 * Calculate the actual tile split value on GFX7-8, assuming 2D_TILED_THIN1 array mode 521 * with a non-depth micro tile mode. 522 * 523 * On GFX7-8, SAMPLE_SPLIT holds a factor from which the actual tile split bytes 524 * can be calculated. The TILE_SPLIT field is only used for the depth micro tile mode. 525 * See CiLib::HwlComputeMacroModeIndex() in addrlib. 526 */ 527 static u32 amdgpu_dm_plane_calc_gfx7_tile_split(const struct amdgpu_device *adev, 528 const u32 bpp, 529 const u32 gb_tile_mode) 530 { 531 /* Assume 2D_TILED_THIN1 mode with non-DEPTH microtiles */ 532 const u32 sample_split = (gb_tile_mode >> 25) & 0x3; 533 const u32 thickness = 1; 534 const u32 tile_size_pixels = 8 * 8; 535 const u32 tile_bytes_1x = tile_size_pixels * bpp * thickness / 8; 536 const u32 sample_split_factor = 1 << sample_split; 537 538 return clamp(tile_bytes_1x * sample_split_factor, 539 256, 540 adev->gfx.config.mem_row_size_in_kb * 1024); 541 } 542 543 /** 544 * amdgpu_dm_plane_get_gfx7_macro_tile_idx() - Get macro tile mode index on GFX7-8 545 * 546 * @bpp: bits per pixel in the image 547 * @tile_split_bytes: actual tile split bytes, see amdgpu_dm_plane_calc_gfx7_tile_split() 548 * 549 * Select which macro tiling mode from the table is suitable for the given bits per pixel, 550 * assuming 2D_TILED_THIN1 array mode and DISPLAY micro tile mode (and no multisampling). 551 * Note that the tiling table is uAPI and userspace relies on specific modes being 552 * present at specific indices. 553 * See CiLib::HwlComputeMacroModeIndex() in addrlib. 554 */ 555 static u32 amdgpu_dm_plane_get_gfx7_macro_tile_idx(const u32 bpp, const u32 tile_split_bytes) 556 { 557 const u32 thickness = 1; 558 const u32 tile_size_pixels = 8 * 8; 559 const u32 tile_bytes_1x = thickness * tile_size_pixels * bpp / 8; 560 const u32 tile_bytes = clamp(tile_bytes_1x, 64, tile_split_bytes); 561 const u32 macro_tile_idx = ilog2(tile_bytes / 64); 562 563 WARN_ON(macro_tile_idx >= 16); 564 565 return macro_tile_idx; 566 } 567 568 /** 569 * amdgpu_dm_plane_calc_gfx6_mod() - Calculate a DRM format modifier for GFX6-8 570 * 571 * @adev: amdgpu_device pointer 572 * @bpp: bits per pixel in the image 573 * @arr: array mode (aka. tile mode) of the image layout 574 * 575 * Select suitable micro and macro tile modes for the given bits per pixel, 576 * and calculate the corresponding DRM format modifier. 577 */ 578 static u64 amdgpu_dm_plane_calc_gfx6_mod(const struct amdgpu_device *adev, 579 const u32 bpp, 580 const enum array_mode_values arr) 581 { 582 u32 array_mode, micro_tile_mode, tile_split_bytes; 583 u32 gb_macrotile_mode, macrotile_idx; 584 u32 gb_tile_mode, tile_idx; 585 586 u64 modifier_base = 587 AMD_FMT_MOD | 588 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX6) | 589 AMD_FMT_MOD_SET(TILE, arr) | 590 AMD_FMT_MOD_SET(MICROTILE, AMD_FMT_MOD_MICROTILE_DISPLAY); 591 592 if (arr < DC_ARRAY_2D_TILED_THIN1) 593 return modifier_base; 594 595 tile_idx = amdgpu_dm_plane_get_gfx6_tile_idx(adev, bpp, arr); 596 gb_tile_mode = adev->gfx.config.tile_mode_array[tile_idx]; 597 array_mode = (gb_tile_mode >> 2) & 0xf; 598 599 if (adev->family == AMDGPU_FAMILY_SI) { 600 micro_tile_mode = (gb_tile_mode >> 0) & 0x3; 601 tile_split_bytes = 64 << ((gb_tile_mode >> 11) & 0x7); 602 } else { 603 micro_tile_mode = (gb_tile_mode >> 22) & 0x7; 604 tile_split_bytes = amdgpu_dm_plane_calc_gfx7_tile_split(adev, bpp, gb_tile_mode); 605 } 606 607 ASSERT(array_mode == arr); 608 ASSERT(micro_tile_mode == AMD_FMT_MOD_MICROTILE_DISPLAY); 609 610 modifier_base |= 611 AMD_FMT_MOD_SET(PIPE_CONFIG, (gb_tile_mode >> 6) & 0x1f) | 612 AMD_FMT_MOD_SET(TILE_SPLIT, ilog2(tile_split_bytes / 64)); 613 614 if (adev->family == AMDGPU_FAMILY_SI) 615 return modifier_base | 616 AMD_FMT_MOD_SET(BANK_WIDTH, (gb_tile_mode >> 14) & 0x3) | 617 AMD_FMT_MOD_SET(BANK_HEIGHT, (gb_tile_mode >> 16) & 0x3) | 618 AMD_FMT_MOD_SET(MACRO_TILE_ASPECT, (gb_tile_mode >> 18) & 0x3) | 619 AMD_FMT_MOD_SET(NUM_BANKS, (gb_tile_mode >> 20) & 0x3); 620 621 macrotile_idx = amdgpu_dm_plane_get_gfx7_macro_tile_idx(bpp, tile_split_bytes); 622 gb_macrotile_mode = adev->gfx.config.macrotile_mode_array[macrotile_idx]; 623 624 return modifier_base | 625 AMD_FMT_MOD_SET(BANK_WIDTH, (gb_macrotile_mode >> 0) & 0x3) | 626 AMD_FMT_MOD_SET(BANK_HEIGHT, (gb_macrotile_mode >> 2) & 0x3) | 627 AMD_FMT_MOD_SET(MACRO_TILE_ASPECT, (gb_macrotile_mode >> 4) & 0x3) | 628 AMD_FMT_MOD_SET(NUM_BANKS, (gb_macrotile_mode >> 6) & 0x3); 629 } 630 631 /** 632 * amdgpu_dm_plane_gfx6_format_mod_supported() - Check if a modifier is supported on GFX6-8 633 * 634 * @adev: amdgpu_device pointer 635 * @bpp: bits per pixel in the image 636 * @modifier: the modifier whose support we check 637 * 638 * On GFX6-8, not all DRM format modifier can be used with all image formats. 639 * Check whether the specified modifier is supported with the given bits per pixel value. 640 */ 641 static bool amdgpu_dm_plane_gfx6_format_mod_supported(const struct amdgpu_device *adev, 642 const u32 bpp, 643 const u64 modifier) 644 { 645 const u32 array_mode = AMD_FMT_MOD_GET(TILE, modifier); 646 const u32 micro_tile_mode = AMD_FMT_MOD_GET(MICROTILE, modifier); 647 648 if (!IS_AMD_FMT_MOD(modifier)) 649 return false; 650 651 /* GFX9 and newer format modifiers are not supported on GFX6-8. */ 652 if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) != AMD_FMT_MOD_TILE_VER_GFX6) 653 return false; 654 655 /* GFX8 and older format modifiers are not supported on GFX9+. */ 656 if (adev->family >= AMDGPU_FAMILY_AI) 657 return false; 658 659 /* GFX6-7 doesn't have any DCC, GFX8 doesn't support displayable DCC. */ 660 if (AMD_FMT_MOD_GET(DCC, modifier)) 661 return false; 662 663 /* 664 * For now, only expose 1D and 2D tiles THIN array modes. 665 * Linear is already exposed through DRM_FORMAT_MOD_LINEAR. 666 */ 667 if (array_mode != AMD_FMT_MOD_TILE_GFX6_1D_TILED_THIN1 && 668 array_mode != AMD_FMT_MOD_TILE_GFX6_2D_TILED_THIN1) 669 return false; 670 671 /* 672 * For now, only allow DISPLAY micro tile mode. 673 * THIN, DEPTH and THICK modes are not displayable. 674 * ROTATED has never been supported by Linux or Mesa. 675 */ 676 if (micro_tile_mode != AMD_FMT_MOD_MICROTILE_DISPLAY) 677 return false; 678 679 /* Verify that the modifier is the same that we'd expose for this bpp */ 680 return amdgpu_dm_plane_calc_gfx6_mod(adev, bpp, array_mode) == modifier; 681 } 682 683 /** 684 * amdgpu_dm_plane_add_gfx6_modifiers() - Expose modifiers for GFX6-8 685 * 686 * @adev: amdgpu_device pointer 687 * @mods: Pointer to array of format modifiers 688 * @size: Pointer to size of the array 689 * @capacity: Pointer to capacity of the array 690 * 691 * Calculate a DRM format modifier for macro tiled modes for each supported 692 * bits per pixel value. Use de-duplication because on some GPUs it may happen 693 * that different bpp results in the exact same macro tiling mode, depending 694 * on the tiling table. 695 * 696 * Also expose a micro tiled only mode. This is less optimal, but supported. 697 */ 698 static void amdgpu_dm_plane_add_gfx6_modifiers(const struct amdgpu_device *adev, 699 u64 **mods, 700 u64 *size, 701 u64 *capacity) 702 { 703 /* 2D tiled displayable */ 704 amdgpu_dm_plane_add_modifier(mods, size, capacity, 705 amdgpu_dm_plane_calc_gfx6_mod(adev, 16, DC_ARRAY_2D_TILED_THIN1)); 706 amdgpu_dm_plane_add_modifier_dedup(mods, size, capacity, 707 amdgpu_dm_plane_calc_gfx6_mod(adev, 32, DC_ARRAY_2D_TILED_THIN1)); 708 amdgpu_dm_plane_add_modifier_dedup(mods, size, capacity, 709 amdgpu_dm_plane_calc_gfx6_mod(adev, 64, DC_ARRAY_2D_TILED_THIN1)); 710 711 /* 1D tiled displayable */ 712 amdgpu_dm_plane_add_modifier(mods, size, capacity, 713 amdgpu_dm_plane_calc_gfx6_mod(adev, 0, DC_ARRAY_1D_TILED_THIN1)); 714 } 715 716 static void amdgpu_dm_plane_add_gfx9_modifiers(const struct amdgpu_device *adev, 717 uint64_t **mods, 718 uint64_t *size, 719 uint64_t *capacity) 720 { 721 int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes); 722 int pipe_xor_bits = min(8, pipes + 723 ilog2(adev->gfx.config.gb_addr_config_fields.num_se)); 724 int bank_xor_bits = min(8 - pipe_xor_bits, 725 ilog2(adev->gfx.config.gb_addr_config_fields.num_banks)); 726 int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) + 727 ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se); 728 729 730 if (adev->family == AMDGPU_FAMILY_RV) { 731 /* Raven2 and later */ 732 bool has_constant_encode = adev->asic_type > CHIP_RAVEN || adev->external_rev_id >= 0x81; 733 734 /* 735 * No _D DCC swizzles yet because we only allow 32bpp, which 736 * doesn't support _D on DCN 737 */ 738 739 if (has_constant_encode) { 740 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 741 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | 742 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | 743 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 744 AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | 745 AMD_FMT_MOD_SET(DCC, 1) | 746 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 747 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | 748 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1)); 749 } 750 751 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 752 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | 753 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | 754 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 755 AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | 756 AMD_FMT_MOD_SET(DCC, 1) | 757 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 758 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | 759 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0)); 760 761 if (has_constant_encode) { 762 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 763 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | 764 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | 765 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 766 AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | 767 AMD_FMT_MOD_SET(DCC, 1) | 768 AMD_FMT_MOD_SET(DCC_RETILE, 1) | 769 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 770 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | 771 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | 772 AMD_FMT_MOD_SET(RB, rb) | 773 AMD_FMT_MOD_SET(PIPE, pipes)); 774 } 775 776 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 777 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | 778 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | 779 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 780 AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) | 781 AMD_FMT_MOD_SET(DCC, 1) | 782 AMD_FMT_MOD_SET(DCC_RETILE, 1) | 783 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 784 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) | 785 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0) | 786 AMD_FMT_MOD_SET(RB, rb) | 787 AMD_FMT_MOD_SET(PIPE, pipes)); 788 } 789 790 /* 791 * Only supported for 64bpp on Raven, will be filtered on format in 792 * amdgpu_dm_plane_format_mod_supported. 793 */ 794 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 795 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D_X) | 796 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | 797 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 798 AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits)); 799 800 if (adev->family == AMDGPU_FAMILY_RV) { 801 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 802 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | 803 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) | 804 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 805 AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits)); 806 } 807 808 /* 809 * Only supported for 64bpp on Raven, will be filtered on format in 810 * amdgpu_dm_plane_format_mod_supported. 811 */ 812 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 813 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) | 814 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); 815 816 if (adev->family == AMDGPU_FAMILY_RV) { 817 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 818 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) | 819 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); 820 } 821 } 822 823 static void amdgpu_dm_plane_add_gfx10_3_modifiers(const struct amdgpu_device *adev, 824 uint64_t **mods, 825 uint64_t *size, 826 uint64_t *capacity) 827 { 828 int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes); 829 int pkrs = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs); 830 831 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 832 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 833 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | 834 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 835 AMD_FMT_MOD_SET(PACKERS, pkrs) | 836 AMD_FMT_MOD_SET(DCC, 1) | 837 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | 838 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 839 AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | 840 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); 841 842 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 843 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 844 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | 845 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 846 AMD_FMT_MOD_SET(PACKERS, pkrs) | 847 AMD_FMT_MOD_SET(DCC, 1) | 848 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | 849 AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | 850 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B)); 851 852 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 853 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 854 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | 855 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 856 AMD_FMT_MOD_SET(PACKERS, pkrs) | 857 AMD_FMT_MOD_SET(DCC, 1) | 858 AMD_FMT_MOD_SET(DCC_RETILE, 1) | 859 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | 860 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 861 AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | 862 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B)); 863 864 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 865 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 866 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | 867 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 868 AMD_FMT_MOD_SET(PACKERS, pkrs) | 869 AMD_FMT_MOD_SET(DCC, 1) | 870 AMD_FMT_MOD_SET(DCC_RETILE, 1) | 871 AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) | 872 AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | 873 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B)); 874 875 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 876 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) | 877 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | 878 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 879 AMD_FMT_MOD_SET(PACKERS, pkrs)); 880 881 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 882 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) | 883 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) | 884 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 885 AMD_FMT_MOD_SET(PACKERS, pkrs)); 886 887 /* Only supported for 64bpp, will be filtered in amdgpu_dm_plane_format_mod_supported */ 888 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 889 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) | 890 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); 891 892 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 893 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) | 894 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9)); 895 } 896 897 static void amdgpu_dm_plane_add_gfx11_modifiers(struct amdgpu_device *adev, 898 uint64_t **mods, uint64_t *size, uint64_t *capacity) 899 { 900 int num_pipes = 0; 901 int pipe_xor_bits = 0; 902 int num_pkrs = 0; 903 int pkrs = 0; 904 u32 gb_addr_config; 905 u8 i = 0; 906 unsigned int swizzle_r_x; 907 uint64_t modifier_r_x; 908 uint64_t modifier_dcc_best; 909 uint64_t modifier_dcc_4k; 910 911 /* TODO: GFX11 IP HW init hasnt finish and we get zero if we read from 912 * adev->gfx.config.gb_addr_config_fields.num_{pkrs,pipes} 913 */ 914 gb_addr_config = RREG32_SOC15(GC, 0, regGB_ADDR_CONFIG); 915 ASSERT(gb_addr_config != 0); 916 917 num_pkrs = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PKRS); 918 pkrs = ilog2(num_pkrs); 919 num_pipes = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PIPES); 920 pipe_xor_bits = ilog2(num_pipes); 921 922 for (i = 0; i < 2; i++) { 923 /* Insert the best one first. */ 924 /* R_X swizzle modes are the best for rendering and DCC requires them. */ 925 if (num_pipes > 16) 926 swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX11_256K_R_X : AMD_FMT_MOD_TILE_GFX9_64K_R_X; 927 else 928 swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX9_64K_R_X : AMD_FMT_MOD_TILE_GFX11_256K_R_X; 929 930 modifier_r_x = AMD_FMT_MOD | 931 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) | 932 AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) | 933 AMD_FMT_MOD_SET(TILE, swizzle_r_x) | 934 AMD_FMT_MOD_SET(PACKERS, pkrs); 935 936 /* DCC_CONSTANT_ENCODE is not set because it can't vary with gfx11 (it's implied to be 1). */ 937 modifier_dcc_best = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) | 938 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 0) | 939 AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | 940 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B); 941 942 /* DCC settings for 4K and greater resolutions. (required by display hw) */ 943 modifier_dcc_4k = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) | 944 AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) | 945 AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) | 946 AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B); 947 948 amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_best); 949 amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_4k); 950 951 amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1)); 952 amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1)); 953 954 amdgpu_dm_plane_add_modifier(mods, size, capacity, modifier_r_x); 955 } 956 957 amdgpu_dm_plane_add_modifier(mods, size, capacity, AMD_FMT_MOD | 958 AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) | 959 AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D)); 960 } 961 962 static void amdgpu_dm_plane_add_gfx12_modifiers(struct amdgpu_device *adev, 963 uint64_t **mods, uint64_t *size, uint64_t *capacity) 964 { 965 uint64_t ver = AMD_FMT_MOD | AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX12); 966 uint64_t mod_256k = ver | AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_256K_2D); 967 uint64_t mod_64k = ver | AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_64K_2D); 968 uint64_t mod_4k = ver | AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_4K_2D); 969 uint64_t mod_256b = ver | AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX12_256B_2D); 970 uint64_t dcc = ver | AMD_FMT_MOD_SET(DCC, 1); 971 uint8_t max_comp_block[] = {2, 1, 0}; 972 uint64_t max_comp_block_mod[ARRAY_SIZE(max_comp_block)] = {0}; 973 uint8_t i = 0, j = 0; 974 /* Note, linear (no DCC) gets added to the modifier list for all chips by the caller. */ 975 uint64_t gfx12_modifiers[] = {mod_256k, mod_64k, mod_4k, mod_256b}; 976 977 for (i = 0; i < ARRAY_SIZE(max_comp_block); i++) 978 max_comp_block_mod[i] = AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, max_comp_block[i]); 979 980 /* With DCC: Best choice should be kept first. Hence, add all 256k modifiers of different 981 * max compressed blocks first and then move on to the next smaller sized layouts. 982 */ 983 for (j = 0; j < ARRAY_SIZE(gfx12_modifiers); j++) 984 for (i = 0; i < ARRAY_SIZE(max_comp_block); i++) 985 amdgpu_dm_plane_add_modifier(mods, size, capacity, 986 ver | dcc | max_comp_block_mod[i] | gfx12_modifiers[j]); 987 988 /* Without DCC. */ 989 for (i = 0; i < ARRAY_SIZE(gfx12_modifiers); i++) 990 amdgpu_dm_plane_add_modifier(mods, size, capacity, gfx12_modifiers[i]); 991 992 } 993 994 STATIC_IFN_KUNIT int amdgpu_dm_plane_get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods) 995 { 996 uint64_t size = 0, capacity = 128; 997 *mods = kmalloc_array(capacity, sizeof(uint64_t), GFP_KERNEL); 998 999 if (plane_type == DRM_PLANE_TYPE_CURSOR) { 1000 amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR); 1001 amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID); 1002 return *mods ? 0 : -ENOMEM; 1003 } 1004 1005 switch (adev->family) { 1006 case AMDGPU_FAMILY_SI: 1007 case AMDGPU_FAMILY_CI: 1008 case AMDGPU_FAMILY_KV: 1009 case AMDGPU_FAMILY_VI: 1010 case AMDGPU_FAMILY_CZ: 1011 amdgpu_dm_plane_add_gfx6_modifiers(adev, mods, &size, &capacity); 1012 break; 1013 case AMDGPU_FAMILY_AI: 1014 case AMDGPU_FAMILY_RV: 1015 amdgpu_dm_plane_add_gfx9_modifiers(adev, mods, &size, &capacity); 1016 break; 1017 case AMDGPU_FAMILY_NV: 1018 case AMDGPU_FAMILY_VGH: 1019 case AMDGPU_FAMILY_YC: 1020 case AMDGPU_FAMILY_GC_10_3_6: 1021 case AMDGPU_FAMILY_GC_10_3_7: 1022 if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(10, 3, 0)) 1023 amdgpu_dm_plane_add_gfx10_3_modifiers(adev, mods, &size, &capacity); 1024 else 1025 amdgpu_dm_plane_add_gfx10_1_modifiers(adev, mods, &size, &capacity); 1026 break; 1027 case AMDGPU_FAMILY_GC_11_0_0: 1028 case AMDGPU_FAMILY_GC_11_0_1: 1029 case AMDGPU_FAMILY_GC_11_5_0: 1030 case AMDGPU_FAMILY_GC_11_5_4: 1031 amdgpu_dm_plane_add_gfx11_modifiers(adev, mods, &size, &capacity); 1032 break; 1033 case AMDGPU_FAMILY_GC_12_0_0: 1034 case AMDGPU_FAMILY_GC_13_0_1: 1035 /* GFX13 (DCN6) shares the GFX12 tiling/DCC binary modifier format. */ 1036 amdgpu_dm_plane_add_gfx12_modifiers(adev, mods, &size, &capacity); 1037 break; 1038 } 1039 1040 amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR); 1041 1042 /* INVALID marks the end of the list. */ 1043 amdgpu_dm_plane_add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID); 1044 1045 if (!*mods) 1046 return -ENOMEM; 1047 1048 return 0; 1049 } 1050 EXPORT_IF_KUNIT(amdgpu_dm_plane_get_plane_modifiers); 1051 1052 STATIC_IFN_KUNIT int amdgpu_dm_plane_get_plane_formats(const struct drm_plane *plane, 1053 const struct dc_plane_cap *plane_cap, 1054 uint32_t *formats, int max_formats) 1055 { 1056 int i, num_formats = 0; 1057 1058 /* 1059 * TODO: Query support for each group of formats directly from 1060 * DC plane caps. This will require adding more formats to the 1061 * caps list. 1062 */ 1063 1064 if (plane->type == DRM_PLANE_TYPE_PRIMARY || 1065 (plane_cap && plane_cap->type == DC_PLANE_TYPE_DCN_UNIVERSAL && plane->type != DRM_PLANE_TYPE_CURSOR)) { 1066 for (i = 0; i < ARRAY_SIZE(rgb_formats); ++i) { 1067 if (num_formats >= max_formats) 1068 break; 1069 1070 formats[num_formats++] = rgb_formats[i]; 1071 } 1072 1073 if (plane_cap && plane_cap->pixel_format_support.nv12) 1074 formats[num_formats++] = DRM_FORMAT_NV12; 1075 if (plane_cap && plane_cap->pixel_format_support.p010) 1076 formats[num_formats++] = DRM_FORMAT_P010; 1077 if (plane_cap && plane_cap->pixel_format_support.fp16) { 1078 formats[num_formats++] = DRM_FORMAT_XRGB16161616F; 1079 formats[num_formats++] = DRM_FORMAT_ARGB16161616F; 1080 formats[num_formats++] = DRM_FORMAT_XBGR16161616F; 1081 formats[num_formats++] = DRM_FORMAT_ABGR16161616F; 1082 } 1083 } else { 1084 switch (plane->type) { 1085 case DRM_PLANE_TYPE_OVERLAY: 1086 for (i = 0; i < ARRAY_SIZE(overlay_formats); ++i) { 1087 if (num_formats >= max_formats) 1088 break; 1089 1090 formats[num_formats++] = overlay_formats[i]; 1091 } 1092 break; 1093 1094 case DRM_PLANE_TYPE_CURSOR: 1095 for (i = 0; i < ARRAY_SIZE(cursor_formats); ++i) { 1096 if (num_formats >= max_formats) 1097 break; 1098 1099 formats[num_formats++] = cursor_formats[i]; 1100 } 1101 break; 1102 1103 default: 1104 break; 1105 } 1106 } 1107 1108 return num_formats; 1109 } 1110 EXPORT_IF_KUNIT(amdgpu_dm_plane_get_plane_formats); 1111 1112 int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev, 1113 const struct amdgpu_framebuffer *afb, 1114 const enum surface_pixel_format format, 1115 const enum dc_rotation_angle rotation, 1116 struct dc_tiling_info *tiling_info, 1117 struct plane_size *plane_size, 1118 struct dc_plane_dcc_param *dcc, 1119 struct dc_plane_address *address, 1120 bool tmz_surface) 1121 { 1122 const struct drm_framebuffer *fb = &afb->base; 1123 int ret; 1124 1125 memset(tiling_info, 0, sizeof(*tiling_info)); 1126 memset(plane_size, 0, sizeof(*plane_size)); 1127 memset(dcc, 0, sizeof(*dcc)); 1128 memset(address, 0, sizeof(*address)); 1129 1130 address->tmz_surface = tmz_surface; 1131 1132 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) { 1133 uint64_t addr = afb->address + fb->offsets[0]; 1134 1135 plane_size->surface_size.x = 0; 1136 plane_size->surface_size.y = 0; 1137 plane_size->surface_size.width = fb->width; 1138 plane_size->surface_size.height = fb->height; 1139 plane_size->surface_pitch = 1140 fb->pitches[0] / fb->format->cpp[0]; 1141 1142 address->type = PLN_ADDR_TYPE_GRAPHICS; 1143 address->grph.addr.low_part = lower_32_bits(addr); 1144 address->grph.addr.high_part = upper_32_bits(addr); 1145 } else if (format < SURFACE_PIXEL_FORMAT_INVALID) { 1146 uint64_t luma_addr = afb->address + fb->offsets[0]; 1147 uint64_t chroma_addr = afb->address + fb->offsets[1]; 1148 1149 plane_size->surface_size.x = 0; 1150 plane_size->surface_size.y = 0; 1151 plane_size->surface_size.width = fb->width; 1152 plane_size->surface_size.height = fb->height; 1153 plane_size->surface_pitch = 1154 fb->pitches[0] / fb->format->cpp[0]; 1155 1156 plane_size->chroma_size.x = 0; 1157 plane_size->chroma_size.y = 0; 1158 /* TODO: set these based on surface format */ 1159 plane_size->chroma_size.width = fb->width / 2; 1160 plane_size->chroma_size.height = fb->height / 2; 1161 1162 plane_size->chroma_pitch = 1163 fb->pitches[1] / fb->format->cpp[1]; 1164 1165 address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE; 1166 address->video_progressive.luma_addr.low_part = 1167 lower_32_bits(luma_addr); 1168 address->video_progressive.luma_addr.high_part = 1169 upper_32_bits(luma_addr); 1170 address->video_progressive.chroma_addr.low_part = 1171 lower_32_bits(chroma_addr); 1172 address->video_progressive.chroma_addr.high_part = 1173 upper_32_bits(chroma_addr); 1174 } 1175 1176 if (adev->family == AMDGPU_FAMILY_GC_12_0_0 1177 || adev->family == AMDGPU_FAMILY_GC_13_0_1) { 1178 ret = amdgpu_dm_plane_fill_gfx12_attrs_from_modifiers(adev, afb, format, 1179 rotation, plane_size, 1180 tiling_info, dcc, 1181 address); 1182 if (ret) 1183 return ret; 1184 } else if (adev->family >= AMDGPU_FAMILY_AI) { 1185 ret = amdgpu_dm_plane_fill_gfx9_attrs_from_modifiers(adev, afb, format, 1186 rotation, plane_size, 1187 tiling_info, dcc, 1188 address); 1189 if (ret) 1190 return ret; 1191 } else { 1192 ret = amdgpu_dm_plane_fill_gfx6_tiling_info_from_modifier(tiling_info, 1193 afb->base.modifier); 1194 if (ret) 1195 return ret; 1196 } 1197 1198 return 0; 1199 } 1200 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_plane_buffer_attributes); 1201 1202 static int amdgpu_dm_plane_helper_prepare_fb(struct drm_plane *plane, 1203 struct drm_plane_state *new_state) 1204 { 1205 struct amdgpu_framebuffer *afb; 1206 struct drm_gem_object *obj; 1207 struct amdgpu_device *adev; 1208 struct amdgpu_bo *rbo; 1209 struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old; 1210 uint32_t domain; 1211 int r; 1212 1213 if (!new_state->fb) { 1214 DRM_DEBUG_KMS("No FB bound\n"); 1215 return 0; 1216 } 1217 1218 afb = to_amdgpu_framebuffer(new_state->fb); 1219 obj = drm_gem_fb_get_obj(new_state->fb, 0); 1220 if (!obj) { 1221 DRM_ERROR("Failed to get obj from framebuffer\n"); 1222 return -EINVAL; 1223 } 1224 1225 rbo = gem_to_amdgpu_bo(obj); 1226 adev = amdgpu_ttm_adev(rbo->tbo.bdev); 1227 r = amdgpu_bo_reserve(rbo, true); 1228 if (r) { 1229 drm_err(adev_to_drm(adev), "fail to reserve bo: %pe\n", ERR_PTR(r)); 1230 return r; 1231 } 1232 1233 r = dma_resv_reserve_fences(rbo->tbo.base.resv, TTM_NUM_MOVE_FENCES); 1234 if (r) { 1235 drm_err(adev_to_drm(adev), "reserving fence slot failed: %pe\n", ERR_PTR(r)); 1236 goto error_unlock; 1237 } 1238 1239 if (plane->type != DRM_PLANE_TYPE_CURSOR) 1240 domain = amdgpu_display_supported_domains(adev, rbo->flags); 1241 else 1242 domain = AMDGPU_GEM_DOMAIN_VRAM; 1243 1244 rbo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; 1245 r = amdgpu_bo_pin(rbo, domain); 1246 if (unlikely(r != 0)) { 1247 if (r != -ERESTARTSYS) 1248 DRM_ERROR("Failed to pin framebuffer: %pe\n", ERR_PTR(r)); 1249 goto error_unlock; 1250 } 1251 1252 r = amdgpu_ttm_alloc_gart(&rbo->tbo); 1253 if (unlikely(r != 0)) { 1254 DRM_ERROR("%p bind failed: %pe\n", rbo, ERR_PTR(r)); 1255 goto error_unpin; 1256 } 1257 1258 r = drm_gem_plane_helper_prepare_fb(plane, new_state); 1259 if (unlikely(r != 0)) 1260 goto error_unpin; 1261 1262 amdgpu_bo_unreserve(rbo); 1263 1264 afb->address = amdgpu_bo_gpu_offset(rbo); 1265 1266 amdgpu_bo_ref(rbo); 1267 1268 /** 1269 * We don't do surface updates on planes that have been newly created, 1270 * but we also don't have the afb->address during atomic check. 1271 * 1272 * Fill in buffer attributes depending on the address here, but only on 1273 * newly created planes since they're not being used by DC yet and this 1274 * won't modify global state. 1275 */ 1276 dm_plane_state_old = to_dm_plane_state(plane->state); 1277 dm_plane_state_new = to_dm_plane_state(new_state); 1278 1279 if (dm_plane_state_new->dc_state && 1280 dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) { 1281 struct dc_plane_state *plane_state = 1282 dm_plane_state_new->dc_state; 1283 1284 amdgpu_dm_plane_fill_plane_buffer_attributes( 1285 adev, afb, plane_state->format, plane_state->rotation, 1286 &plane_state->tiling_info, &plane_state->plane_size, 1287 &plane_state->dcc, &plane_state->address, 1288 afb->tmz_surface); 1289 } 1290 1291 return 0; 1292 1293 error_unpin: 1294 amdgpu_bo_unpin(rbo); 1295 1296 error_unlock: 1297 amdgpu_bo_unreserve(rbo); 1298 return r; 1299 } 1300 1301 static void amdgpu_dm_plane_helper_cleanup_fb(struct drm_plane *plane, 1302 struct drm_plane_state *old_state) 1303 { 1304 struct amdgpu_bo *rbo; 1305 int r; 1306 1307 if (!old_state->fb) 1308 return; 1309 1310 rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]); 1311 r = amdgpu_bo_reserve(rbo, false); 1312 if (unlikely(r)) { 1313 DRM_ERROR("failed to reserve rbo before unpin: %pe\n", ERR_PTR(r)); 1314 return; 1315 } 1316 1317 amdgpu_bo_unpin(rbo); 1318 amdgpu_bo_unreserve(rbo); 1319 amdgpu_bo_unref(&rbo); 1320 } 1321 1322 STATIC_IFN_KUNIT void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev, 1323 struct drm_framebuffer *fb, 1324 int *min_downscale, int *max_upscale) 1325 { 1326 struct amdgpu_device *adev = drm_to_adev(dev); 1327 struct dc *dc = adev->dm.dc; 1328 /* Caps for all supported planes are the same on DCE and DCN 1 - 3 */ 1329 struct dc_plane_cap *plane_cap = &dc->caps.planes[0]; 1330 1331 switch (fb->format->format) { 1332 case DRM_FORMAT_P010: 1333 case DRM_FORMAT_NV12: 1334 case DRM_FORMAT_NV21: 1335 *max_upscale = plane_cap->max_upscale_factor.nv12; 1336 *min_downscale = plane_cap->max_downscale_factor.nv12; 1337 break; 1338 1339 /* All 64 bpp formats have the same fp16 scaling limits */ 1340 case DRM_FORMAT_XRGB16161616F: 1341 case DRM_FORMAT_ARGB16161616F: 1342 case DRM_FORMAT_XBGR16161616F: 1343 case DRM_FORMAT_ABGR16161616F: 1344 case DRM_FORMAT_XRGB16161616: 1345 case DRM_FORMAT_ARGB16161616: 1346 case DRM_FORMAT_XBGR16161616: 1347 case DRM_FORMAT_ABGR16161616: 1348 *max_upscale = plane_cap->max_upscale_factor.fp16; 1349 *min_downscale = plane_cap->max_downscale_factor.fp16; 1350 break; 1351 1352 default: 1353 *max_upscale = plane_cap->max_upscale_factor.argb8888; 1354 *min_downscale = plane_cap->max_downscale_factor.argb8888; 1355 break; 1356 } 1357 1358 /* 1359 * A factor of 1 in the plane_cap means to not allow scaling, ie. use a 1360 * scaling factor of 1.0 == 1000 units. 1361 */ 1362 if (*max_upscale == 1) 1363 *max_upscale = 1000; 1364 1365 if (*min_downscale == 1) 1366 *min_downscale = 1000; 1367 } 1368 EXPORT_IF_KUNIT(amdgpu_dm_plane_get_min_max_dc_plane_scaling); 1369 1370 int amdgpu_dm_plane_helper_check_state(struct drm_plane_state *state, 1371 struct drm_crtc_state *new_crtc_state) 1372 { 1373 struct drm_framebuffer *fb = state->fb; 1374 int min_downscale, max_upscale; 1375 int min_scale = 0; 1376 int max_scale = INT_MAX; 1377 1378 /* Plane enabled? Validate viewport and get scaling factors from plane caps. */ 1379 if (fb && state->crtc) { 1380 /* Validate viewport to cover the case when only the position changes */ 1381 if (state->plane->type != DRM_PLANE_TYPE_CURSOR) { 1382 int viewport_width = state->crtc_w; 1383 int viewport_height = state->crtc_h; 1384 1385 if (state->crtc_x < 0) 1386 viewport_width += state->crtc_x; 1387 else if (state->crtc_x + state->crtc_w > new_crtc_state->mode.crtc_hdisplay) 1388 viewport_width = new_crtc_state->mode.crtc_hdisplay - state->crtc_x; 1389 1390 if (state->crtc_y < 0) 1391 viewport_height += state->crtc_y; 1392 else if (state->crtc_y + state->crtc_h > new_crtc_state->mode.crtc_vdisplay) 1393 viewport_height = new_crtc_state->mode.crtc_vdisplay - state->crtc_y; 1394 1395 if (viewport_width < 0 || viewport_height < 0) { 1396 DRM_DEBUG_ATOMIC("Plane completely outside of screen\n"); 1397 return -EINVAL; 1398 } else if (viewport_width < MIN_VIEWPORT_SIZE*2) { /* x2 for width is because of pipe-split. */ 1399 DRM_DEBUG_ATOMIC("Viewport width %d smaller than %d\n", viewport_width, MIN_VIEWPORT_SIZE*2); 1400 return -EINVAL; 1401 } else if (viewport_height < MIN_VIEWPORT_SIZE) { 1402 DRM_DEBUG_ATOMIC("Viewport height %d smaller than %d\n", viewport_height, MIN_VIEWPORT_SIZE); 1403 return -EINVAL; 1404 } 1405 1406 } 1407 1408 /* Get min/max allowed scaling factors from plane caps. */ 1409 amdgpu_dm_plane_get_min_max_dc_plane_scaling(state->crtc->dev, fb, 1410 &min_downscale, &max_upscale); 1411 /* 1412 * Convert to drm convention: 16.16 fixed point, instead of dc's 1413 * 1.0 == 1000. Also drm scaling is src/dst instead of dc's 1414 * dst/src, so min_scale = 1.0 / max_upscale, etc. 1415 */ 1416 min_scale = (1000 << 16) / max_upscale; 1417 max_scale = (1000 << 16) / min_downscale; 1418 } 1419 1420 return drm_atomic_helper_check_plane_state( 1421 state, new_crtc_state, min_scale, max_scale, true, true); 1422 } 1423 EXPORT_IF_KUNIT(amdgpu_dm_plane_helper_check_state); 1424 1425 int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev, 1426 const struct drm_plane_state *state, 1427 struct dc_scaling_info *scaling_info) 1428 { 1429 int scale_w, scale_h, min_downscale, max_upscale; 1430 1431 memset(scaling_info, 0, sizeof(*scaling_info)); 1432 1433 /* Source is fixed 16.16 but we ignore mantissa for now... */ 1434 scaling_info->src_rect.x = state->src_x >> 16; 1435 scaling_info->src_rect.y = state->src_y >> 16; 1436 1437 /* 1438 * For reasons we don't (yet) fully understand a non-zero 1439 * src_y coordinate into an NV12 buffer can cause a 1440 * system hang on DCN1x. 1441 * To avoid hangs (and maybe be overly cautious) 1442 * let's reject both non-zero src_x and src_y. 1443 * 1444 * We currently know of only one use-case to reproduce a 1445 * scenario with non-zero src_x and src_y for NV12, which 1446 * is to gesture the YouTube Android app into full screen 1447 * on ChromeOS. 1448 */ 1449 if (((amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(1, 0, 0)) || 1450 (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(1, 0, 1))) && 1451 (state->fb && state->fb->format->format == DRM_FORMAT_NV12 && 1452 (scaling_info->src_rect.x != 0 || scaling_info->src_rect.y != 0))) 1453 return -EINVAL; 1454 1455 scaling_info->src_rect.width = state->src_w >> 16; 1456 if (scaling_info->src_rect.width == 0) 1457 return -EINVAL; 1458 1459 scaling_info->src_rect.height = state->src_h >> 16; 1460 if (scaling_info->src_rect.height == 0) 1461 return -EINVAL; 1462 1463 scaling_info->dst_rect.x = state->crtc_x; 1464 scaling_info->dst_rect.y = state->crtc_y; 1465 1466 if (state->crtc_w == 0) 1467 return -EINVAL; 1468 1469 scaling_info->dst_rect.width = state->crtc_w; 1470 1471 if (state->crtc_h == 0) 1472 return -EINVAL; 1473 1474 scaling_info->dst_rect.height = state->crtc_h; 1475 1476 /* DRM doesn't specify clipping on destination output. */ 1477 scaling_info->clip_rect = scaling_info->dst_rect; 1478 1479 /* Validate scaling per-format with DC plane caps */ 1480 if (state->plane && state->plane->dev && state->fb) { 1481 amdgpu_dm_plane_get_min_max_dc_plane_scaling(state->plane->dev, state->fb, 1482 &min_downscale, &max_upscale); 1483 } else { 1484 min_downscale = 250; 1485 max_upscale = 16000; 1486 } 1487 1488 scale_w = scaling_info->dst_rect.width * 1000 / 1489 scaling_info->src_rect.width; 1490 1491 if (scale_w < min_downscale || scale_w > max_upscale) 1492 return -EINVAL; 1493 1494 scale_h = scaling_info->dst_rect.height * 1000 / 1495 scaling_info->src_rect.height; 1496 1497 if (scale_h < min_downscale || scale_h > max_upscale) 1498 return -EINVAL; 1499 1500 /* 1501 * The "scaling_quality" can be ignored for now, quality = 0 has DC 1502 * assume reasonable defaults based on the format. 1503 */ 1504 1505 return 0; 1506 } 1507 EXPORT_IF_KUNIT(amdgpu_dm_plane_fill_dc_scaling_info); 1508 1509 STATIC_IFN_KUNIT int amdgpu_dm_plane_atomic_check(struct drm_plane *plane, 1510 struct drm_atomic_commit *state) 1511 { 1512 struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, 1513 plane); 1514 struct amdgpu_device *adev = drm_to_adev(plane->dev); 1515 struct dc *dc = adev->dm.dc; 1516 struct dm_plane_state *dm_plane_state; 1517 struct dc_scaling_info scaling_info; 1518 struct drm_crtc_state *new_crtc_state; 1519 int ret; 1520 1521 trace_amdgpu_dm_plane_atomic_check(new_plane_state); 1522 1523 dm_plane_state = to_dm_plane_state(new_plane_state); 1524 1525 if (!dm_plane_state->dc_state) 1526 return 0; 1527 1528 new_crtc_state = 1529 drm_atomic_get_new_crtc_state(state, 1530 new_plane_state->crtc); 1531 if (!new_crtc_state) 1532 return -EINVAL; 1533 1534 ret = amdgpu_dm_plane_helper_check_state(new_plane_state, new_crtc_state); 1535 if (ret) 1536 return ret; 1537 1538 /* Reject commits that attempt to use both COLOR_PIPELINE and CRTC DEGAMMA_LUT */ 1539 if (new_plane_state->color_pipeline && new_crtc_state->degamma_lut) { 1540 drm_dbg_atomic(plane->dev, 1541 "[PLANE:%d:%s] COLOR_PIPELINE and CRTC DEGAMMA_LUT cannot be enabled simultaneously\n", 1542 plane->base.id, plane->name); 1543 return -EINVAL; 1544 } 1545 1546 ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info); 1547 if (ret) 1548 return ret; 1549 1550 if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK) 1551 return 0; 1552 1553 return -EINVAL; 1554 } 1555 EXPORT_IF_KUNIT(amdgpu_dm_plane_atomic_check); 1556 1557 STATIC_IFN_KUNIT int amdgpu_dm_plane_atomic_async_check(struct drm_plane *plane, 1558 struct drm_atomic_commit *state, bool flip) 1559 { 1560 struct drm_crtc_state *new_crtc_state; 1561 struct drm_plane_state *new_plane_state; 1562 struct dm_crtc_state *dm_new_crtc_state; 1563 1564 if (flip) { 1565 if (plane->type != DRM_PLANE_TYPE_OVERLAY) 1566 return -EINVAL; 1567 } else if (plane->type != DRM_PLANE_TYPE_CURSOR) { 1568 return -EINVAL; 1569 } 1570 1571 new_plane_state = drm_atomic_get_new_plane_state(state, plane); 1572 new_crtc_state = drm_atomic_get_new_crtc_state(state, new_plane_state->crtc); 1573 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); 1574 /* Reject overlay cursors for now*/ 1575 if (!flip && dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) 1576 return -EINVAL; 1577 1578 return 0; 1579 } 1580 EXPORT_IF_KUNIT(amdgpu_dm_plane_atomic_async_check); 1581 1582 int amdgpu_dm_plane_get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, 1583 struct dc_cursor_position *position) 1584 { 1585 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 1586 struct amdgpu_device *adev = drm_to_adev(plane->dev); 1587 int x, y; 1588 int xorigin = 0, yorigin = 0; 1589 1590 if (!crtc || !plane->state->fb) 1591 return 0; 1592 1593 if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) || 1594 (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) { 1595 DRM_ERROR("%s: bad cursor width or height %d x %d\n", 1596 __func__, 1597 plane->state->crtc_w, 1598 plane->state->crtc_h); 1599 return -EINVAL; 1600 } 1601 1602 x = plane->state->crtc_x; 1603 y = plane->state->crtc_y; 1604 1605 if (x <= -amdgpu_crtc->max_cursor_width || 1606 y <= -amdgpu_crtc->max_cursor_height) 1607 return 0; 1608 1609 if (x < 0) { 1610 xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1); 1611 x = 0; 1612 } 1613 if (y < 0) { 1614 yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1); 1615 y = 0; 1616 } 1617 position->enable = true; 1618 position->x = x; 1619 position->y = y; 1620 position->x_hotspot = xorigin; 1621 position->y_hotspot = yorigin; 1622 1623 if (amdgpu_ip_version(adev, DCE_HWIP, 0) < IP_VERSION(4, 0, 1)) 1624 position->translate_by_source = true; 1625 1626 return 0; 1627 } 1628 EXPORT_IF_KUNIT(amdgpu_dm_plane_get_cursor_position); 1629 1630 void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane, 1631 struct drm_plane_state *old_plane_state) 1632 { 1633 struct amdgpu_device *adev = drm_to_adev(plane->dev); 1634 struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb); 1635 struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc; 1636 struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL; 1637 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 1638 uint64_t address = afb ? afb->address : 0; 1639 struct dc_cursor_position position = {0}; 1640 struct dc_cursor_attributes attributes; 1641 int ret; 1642 1643 if (!plane->state->fb && !old_plane_state->fb) 1644 return; 1645 1646 drm_dbg_atomic(plane->dev, "crtc_id=%d with size %d to %d\n", 1647 amdgpu_crtc->crtc_id, plane->state->crtc_w, 1648 plane->state->crtc_h); 1649 1650 ret = amdgpu_dm_plane_get_cursor_position(plane, crtc, &position); 1651 if (ret) 1652 return; 1653 1654 if (!position.enable) { 1655 /* turn off cursor */ 1656 if (crtc_state && crtc_state->stream) { 1657 mutex_lock(&adev->dm.dc_lock); 1658 amdgpu_dm_ism_commit_event( 1659 &amdgpu_crtc->ism, 1660 DM_ISM_EVENT_BEGIN_CURSOR_UPDATE); 1661 1662 dc_stream_program_cursor_position(crtc_state->stream, 1663 &position); 1664 1665 amdgpu_dm_ism_commit_event( 1666 &amdgpu_crtc->ism, 1667 DM_ISM_EVENT_END_CURSOR_UPDATE); 1668 mutex_unlock(&adev->dm.dc_lock); 1669 } 1670 return; 1671 } 1672 1673 amdgpu_crtc->cursor_width = plane->state->crtc_w; 1674 amdgpu_crtc->cursor_height = plane->state->crtc_h; 1675 1676 memset(&attributes, 0, sizeof(attributes)); 1677 attributes.address.high_part = upper_32_bits(address); 1678 attributes.address.low_part = lower_32_bits(address); 1679 attributes.width = plane->state->crtc_w; 1680 attributes.height = plane->state->crtc_h; 1681 attributes.color_format = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA; 1682 attributes.rotation_angle = 0; 1683 attributes.attribute_flags.value = 0; 1684 1685 /* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM 1686 * legacy gamma setup. 1687 */ 1688 if (crtc_state->cm_is_degamma_srgb && 1689 adev->dm.dc->caps.color.dpp.gamma_corr) 1690 attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1; 1691 1692 if (afb) 1693 attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0]; 1694 1695 if (crtc_state->stream) { 1696 mutex_lock(&adev->dm.dc_lock); 1697 amdgpu_dm_ism_commit_event( 1698 &amdgpu_crtc->ism, 1699 DM_ISM_EVENT_BEGIN_CURSOR_UPDATE); 1700 1701 if (!dc_stream_program_cursor_attributes(crtc_state->stream, 1702 &attributes)) 1703 DRM_ERROR("DC failed to set cursor attributes\n"); 1704 1705 if (!dc_stream_program_cursor_position(crtc_state->stream, 1706 &position)) 1707 DRM_ERROR("DC failed to set cursor position\n"); 1708 1709 amdgpu_dm_ism_commit_event( 1710 &amdgpu_crtc->ism, 1711 DM_ISM_EVENT_END_CURSOR_UPDATE); 1712 mutex_unlock(&adev->dm.dc_lock); 1713 } 1714 } 1715 1716 static void amdgpu_dm_plane_atomic_async_update(struct drm_plane *plane, 1717 struct drm_atomic_commit *state) 1718 { 1719 struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, 1720 plane); 1721 struct drm_plane_state *old_state = 1722 drm_atomic_get_old_plane_state(state, plane); 1723 1724 trace_amdgpu_dm_atomic_update_cursor(new_state); 1725 1726 swap(plane->state->fb, new_state->fb); 1727 1728 plane->state->src_x = new_state->src_x; 1729 plane->state->src_y = new_state->src_y; 1730 plane->state->src_w = new_state->src_w; 1731 plane->state->src_h = new_state->src_h; 1732 plane->state->crtc_x = new_state->crtc_x; 1733 plane->state->crtc_y = new_state->crtc_y; 1734 plane->state->crtc_w = new_state->crtc_w; 1735 plane->state->crtc_h = new_state->crtc_h; 1736 1737 amdgpu_dm_plane_handle_cursor_update(plane, old_state); 1738 } 1739 1740 STATIC_IFN_KUNIT void amdgpu_dm_plane_panic_flush(struct drm_plane *plane) 1741 { 1742 struct dm_plane_state *dm_plane_state = to_dm_plane_state(plane->state); 1743 struct drm_framebuffer *fb = plane->state->fb; 1744 struct dc_plane_state *dc_plane_state; 1745 1746 if (!dm_plane_state || !dm_plane_state->dc_state) 1747 return; 1748 1749 dc_plane_state = dm_plane_state->dc_state; 1750 1751 dc_plane_force_dcc_and_tiling_disable(dc_plane_state, fb->modifier ? true : false); 1752 } 1753 EXPORT_IF_KUNIT(amdgpu_dm_plane_panic_flush); 1754 1755 static const struct drm_plane_helper_funcs dm_plane_helper_funcs = { 1756 .prepare_fb = amdgpu_dm_plane_helper_prepare_fb, 1757 .cleanup_fb = amdgpu_dm_plane_helper_cleanup_fb, 1758 .atomic_check = amdgpu_dm_plane_atomic_check, 1759 .atomic_async_check = amdgpu_dm_plane_atomic_async_check, 1760 .atomic_async_update = amdgpu_dm_plane_atomic_async_update 1761 }; 1762 1763 static const struct drm_plane_helper_funcs dm_primary_plane_helper_funcs = { 1764 .prepare_fb = amdgpu_dm_plane_helper_prepare_fb, 1765 .cleanup_fb = amdgpu_dm_plane_helper_cleanup_fb, 1766 .atomic_check = amdgpu_dm_plane_atomic_check, 1767 .atomic_async_check = amdgpu_dm_plane_atomic_async_check, 1768 .atomic_async_update = amdgpu_dm_plane_atomic_async_update, 1769 .get_scanout_buffer = amdgpu_display_get_scanout_buffer, 1770 .panic_flush = amdgpu_dm_plane_panic_flush, 1771 }; 1772 1773 STATIC_IFN_KUNIT void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane) 1774 { 1775 struct dm_plane_state *amdgpu_state; 1776 1777 amdgpu_state = kzalloc_obj(*amdgpu_state); 1778 if (!amdgpu_state) 1779 return; 1780 1781 if (plane->state) 1782 plane->funcs->atomic_destroy_state(plane, plane->state); 1783 1784 __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); 1785 amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; 1786 amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT; 1787 amdgpu_state->shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; 1788 amdgpu_state->blend_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; 1789 } 1790 EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_reset); 1791 1792 STATIC_IFN_KUNIT struct drm_plane_state * 1793 amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane) 1794 { 1795 struct dm_plane_state *dm_plane_state, *old_dm_plane_state; 1796 1797 old_dm_plane_state = to_dm_plane_state(plane->state); 1798 dm_plane_state = kzalloc_obj(*dm_plane_state); 1799 if (!dm_plane_state) 1800 return NULL; 1801 1802 __drm_atomic_helper_plane_duplicate_state(plane, &dm_plane_state->base); 1803 1804 if (old_dm_plane_state->dc_state) { 1805 dm_plane_state->dc_state = old_dm_plane_state->dc_state; 1806 dc_plane_state_retain(dm_plane_state->dc_state); 1807 } 1808 1809 if (old_dm_plane_state->degamma_lut) 1810 dm_plane_state->degamma_lut = 1811 drm_property_blob_get(old_dm_plane_state->degamma_lut); 1812 if (old_dm_plane_state->ctm) 1813 dm_plane_state->ctm = 1814 drm_property_blob_get(old_dm_plane_state->ctm); 1815 if (old_dm_plane_state->shaper_lut) 1816 dm_plane_state->shaper_lut = 1817 drm_property_blob_get(old_dm_plane_state->shaper_lut); 1818 if (old_dm_plane_state->lut3d) 1819 dm_plane_state->lut3d = 1820 drm_property_blob_get(old_dm_plane_state->lut3d); 1821 if (old_dm_plane_state->blend_lut) 1822 dm_plane_state->blend_lut = 1823 drm_property_blob_get(old_dm_plane_state->blend_lut); 1824 1825 dm_plane_state->degamma_tf = old_dm_plane_state->degamma_tf; 1826 dm_plane_state->hdr_mult = old_dm_plane_state->hdr_mult; 1827 dm_plane_state->shaper_tf = old_dm_plane_state->shaper_tf; 1828 dm_plane_state->blend_tf = old_dm_plane_state->blend_tf; 1829 1830 return &dm_plane_state->base; 1831 } 1832 EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_duplicate_state); 1833 1834 STATIC_IFN_KUNIT bool amdgpu_dm_plane_format_mod_supported(struct drm_plane *plane, 1835 uint32_t format, 1836 uint64_t modifier) 1837 { 1838 struct amdgpu_device *adev = drm_to_adev(plane->dev); 1839 const struct drm_format_info *info = drm_format_info(format); 1840 const u32 bpp = drm_format_info_bpp(info, 0); 1841 int i; 1842 1843 if (!info) 1844 return false; 1845 1846 /* 1847 * We always have to allow these modifiers: 1848 * 1. Core DRM checks for LINEAR support if userspace does not provide modifiers. 1849 * 2. Not passing any modifiers is the same as explicitly passing INVALID. 1850 */ 1851 if (modifier == DRM_FORMAT_MOD_LINEAR || 1852 modifier == DRM_FORMAT_MOD_INVALID) { 1853 return true; 1854 } 1855 1856 /* Check that the modifier is on the list of the plane's supported modifiers. */ 1857 for (i = 0; i < plane->modifier_count; i++) { 1858 if (modifier == plane->modifiers[i]) 1859 break; 1860 } 1861 if (i == plane->modifier_count) 1862 return false; 1863 1864 if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == AMD_FMT_MOD_TILE_VER_GFX6) 1865 return amdgpu_dm_plane_gfx6_format_mod_supported(adev, bpp, modifier); 1866 1867 /* GFX9+ modifers are not supported on GFX8 and older. */ 1868 if (adev->family < AMDGPU_FAMILY_AI) 1869 return false; 1870 1871 /* GFX12 doesn't have these limitations. */ 1872 if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) <= AMD_FMT_MOD_TILE_VER_GFX11) { 1873 enum dm_micro_swizzle microtile = amdgpu_dm_plane_modifier_gfx9_swizzle_mode(modifier) & 3; 1874 1875 /* 1876 * For D swizzle the canonical modifier depends on the bpp, so check 1877 * it here. 1878 */ 1879 if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == AMD_FMT_MOD_TILE_VER_GFX9 && 1880 adev->family >= AMDGPU_FAMILY_NV) { 1881 if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4) 1882 return false; 1883 } 1884 1885 if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D && 1886 info->cpp[0] < 8) 1887 return false; 1888 1889 if (amdgpu_dm_plane_modifier_has_dcc(modifier)) { 1890 /* Per radeonsi comments 16/64 bpp are more complicated. */ 1891 if (info->cpp[0] != 4) 1892 return false; 1893 /* We support multi-planar formats, but not when combined with 1894 * additional DCC metadata planes. 1895 */ 1896 if (info->num_planes > 1) 1897 return false; 1898 } 1899 } 1900 1901 return true; 1902 } 1903 EXPORT_IF_KUNIT(amdgpu_dm_plane_format_mod_supported); 1904 1905 STATIC_IFN_KUNIT void amdgpu_dm_plane_drm_plane_destroy_state(struct drm_plane *plane, 1906 struct drm_plane_state *state) 1907 { 1908 struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); 1909 1910 if (dm_plane_state->degamma_lut) 1911 drm_property_blob_put(dm_plane_state->degamma_lut); 1912 if (dm_plane_state->ctm) 1913 drm_property_blob_put(dm_plane_state->ctm); 1914 if (dm_plane_state->lut3d) 1915 drm_property_blob_put(dm_plane_state->lut3d); 1916 if (dm_plane_state->shaper_lut) 1917 drm_property_blob_put(dm_plane_state->shaper_lut); 1918 if (dm_plane_state->blend_lut) 1919 drm_property_blob_put(dm_plane_state->blend_lut); 1920 1921 if (dm_plane_state->dc_state) 1922 dc_plane_state_release(dm_plane_state->dc_state); 1923 1924 drm_atomic_helper_plane_destroy_state(plane, state); 1925 } 1926 EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_destroy_state); 1927 1928 #ifdef AMD_PRIVATE_COLOR 1929 static void 1930 dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, 1931 struct drm_plane *plane) 1932 { 1933 struct amdgpu_mode_info mode_info = dm->adev->mode_info; 1934 struct dpp_color_caps dpp_color_caps = dm->dc->caps.color.dpp; 1935 1936 /* Check HW color pipeline capabilities on DPP block (pre-blending) 1937 * before exposing related properties. 1938 */ 1939 if (dpp_color_caps.dgam_ram || dpp_color_caps.gamma_corr) { 1940 drm_object_attach_property(&plane->base, 1941 mode_info.plane_degamma_lut_property, 1942 0); 1943 drm_object_attach_property(&plane->base, 1944 mode_info.plane_degamma_lut_size_property, 1945 MAX_COLOR_LUT_ENTRIES); 1946 drm_object_attach_property(&plane->base, 1947 dm->adev->mode_info.plane_degamma_tf_property, 1948 AMDGPU_TRANSFER_FUNCTION_DEFAULT); 1949 } 1950 /* HDR MULT is always available */ 1951 drm_object_attach_property(&plane->base, 1952 dm->adev->mode_info.plane_hdr_mult_property, 1953 AMDGPU_HDR_MULT_DEFAULT); 1954 1955 /* Only enable plane CTM if both DPP and MPC gamut remap is available. */ 1956 if (dm->dc->caps.color.mpc.gamut_remap) 1957 drm_object_attach_property(&plane->base, 1958 dm->adev->mode_info.plane_ctm_property, 0); 1959 1960 if (dpp_color_caps.hw_3d_lut || dm->dc->caps.color.mpc.preblend) { 1961 drm_object_attach_property(&plane->base, 1962 mode_info.plane_shaper_lut_property, 0); 1963 drm_object_attach_property(&plane->base, 1964 mode_info.plane_shaper_lut_size_property, 1965 MAX_COLOR_LUT_ENTRIES); 1966 drm_object_attach_property(&plane->base, 1967 mode_info.plane_shaper_tf_property, 1968 AMDGPU_TRANSFER_FUNCTION_DEFAULT); 1969 drm_object_attach_property(&plane->base, 1970 mode_info.plane_lut3d_property, 0); 1971 drm_object_attach_property(&plane->base, 1972 mode_info.plane_lut3d_size_property, 1973 MAX_COLOR_3DLUT_SIZE); 1974 } 1975 1976 if (dpp_color_caps.ogam_ram || dm->dc->caps.color.mpc.preblend) { 1977 drm_object_attach_property(&plane->base, 1978 mode_info.plane_blend_lut_property, 0); 1979 drm_object_attach_property(&plane->base, 1980 mode_info.plane_blend_lut_size_property, 1981 MAX_COLOR_LUT_ENTRIES); 1982 drm_object_attach_property(&plane->base, 1983 mode_info.plane_blend_tf_property, 1984 AMDGPU_TRANSFER_FUNCTION_DEFAULT); 1985 } 1986 } 1987 1988 static int 1989 dm_atomic_plane_set_property(struct drm_plane *plane, 1990 struct drm_plane_state *state, 1991 struct drm_property *property, 1992 uint64_t val) 1993 { 1994 struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); 1995 struct amdgpu_device *adev = drm_to_adev(plane->dev); 1996 bool replaced = false; 1997 int ret; 1998 1999 if (property == adev->mode_info.plane_degamma_lut_property) { 2000 ret = drm_property_replace_blob_from_id(plane->dev, 2001 &dm_plane_state->degamma_lut, 2002 val, 2003 -1, -1, sizeof(struct drm_color_lut), 2004 &replaced); 2005 dm_plane_state->base.color_mgmt_changed |= replaced; 2006 return ret; 2007 } else if (property == adev->mode_info.plane_degamma_tf_property) { 2008 if (dm_plane_state->degamma_tf != val) { 2009 dm_plane_state->degamma_tf = val; 2010 dm_plane_state->base.color_mgmt_changed = 1; 2011 } 2012 } else if (property == adev->mode_info.plane_hdr_mult_property) { 2013 if (dm_plane_state->hdr_mult != val) { 2014 dm_plane_state->hdr_mult = val; 2015 dm_plane_state->base.color_mgmt_changed = 1; 2016 } 2017 } else if (property == adev->mode_info.plane_ctm_property) { 2018 ret = drm_property_replace_blob_from_id(plane->dev, 2019 &dm_plane_state->ctm, 2020 val, 2021 -1, sizeof(struct drm_color_ctm_3x4), -1, 2022 &replaced); 2023 dm_plane_state->base.color_mgmt_changed |= replaced; 2024 return ret; 2025 } else if (property == adev->mode_info.plane_shaper_lut_property) { 2026 ret = drm_property_replace_blob_from_id(plane->dev, 2027 &dm_plane_state->shaper_lut, 2028 val, 2029 -1, -1, sizeof(struct drm_color_lut), 2030 &replaced); 2031 dm_plane_state->base.color_mgmt_changed |= replaced; 2032 return ret; 2033 } else if (property == adev->mode_info.plane_shaper_tf_property) { 2034 if (dm_plane_state->shaper_tf != val) { 2035 dm_plane_state->shaper_tf = val; 2036 dm_plane_state->base.color_mgmt_changed = 1; 2037 } 2038 } else if (property == adev->mode_info.plane_lut3d_property) { 2039 ret = drm_property_replace_blob_from_id(plane->dev, 2040 &dm_plane_state->lut3d, 2041 val, 2042 -1, -1, sizeof(struct drm_color_lut), 2043 &replaced); 2044 dm_plane_state->base.color_mgmt_changed |= replaced; 2045 return ret; 2046 } else if (property == adev->mode_info.plane_blend_lut_property) { 2047 ret = drm_property_replace_blob_from_id(plane->dev, 2048 &dm_plane_state->blend_lut, 2049 val, 2050 -1, -1, sizeof(struct drm_color_lut), 2051 &replaced); 2052 dm_plane_state->base.color_mgmt_changed |= replaced; 2053 return ret; 2054 } else if (property == adev->mode_info.plane_blend_tf_property) { 2055 if (dm_plane_state->blend_tf != val) { 2056 dm_plane_state->blend_tf = val; 2057 dm_plane_state->base.color_mgmt_changed = 1; 2058 } 2059 } else { 2060 drm_dbg_atomic(plane->dev, 2061 "[PLANE:%d:%s] unknown property [PROP:%d:%s]]\n", 2062 plane->base.id, plane->name, 2063 property->base.id, property->name); 2064 return -EINVAL; 2065 } 2066 2067 return 0; 2068 } 2069 2070 static int 2071 dm_atomic_plane_get_property(struct drm_plane *plane, 2072 const struct drm_plane_state *state, 2073 struct drm_property *property, 2074 uint64_t *val) 2075 { 2076 struct dm_plane_state *dm_plane_state = to_dm_plane_state(state); 2077 struct amdgpu_device *adev = drm_to_adev(plane->dev); 2078 2079 if (property == adev->mode_info.plane_degamma_lut_property) { 2080 *val = (dm_plane_state->degamma_lut) ? 2081 dm_plane_state->degamma_lut->base.id : 0; 2082 } else if (property == adev->mode_info.plane_degamma_tf_property) { 2083 *val = dm_plane_state->degamma_tf; 2084 } else if (property == adev->mode_info.plane_hdr_mult_property) { 2085 *val = dm_plane_state->hdr_mult; 2086 } else if (property == adev->mode_info.plane_ctm_property) { 2087 *val = (dm_plane_state->ctm) ? 2088 dm_plane_state->ctm->base.id : 0; 2089 } else if (property == adev->mode_info.plane_shaper_lut_property) { 2090 *val = (dm_plane_state->shaper_lut) ? 2091 dm_plane_state->shaper_lut->base.id : 0; 2092 } else if (property == adev->mode_info.plane_shaper_tf_property) { 2093 *val = dm_plane_state->shaper_tf; 2094 } else if (property == adev->mode_info.plane_lut3d_property) { 2095 *val = (dm_plane_state->lut3d) ? 2096 dm_plane_state->lut3d->base.id : 0; 2097 } else if (property == adev->mode_info.plane_blend_lut_property) { 2098 *val = (dm_plane_state->blend_lut) ? 2099 dm_plane_state->blend_lut->base.id : 0; 2100 } else if (property == adev->mode_info.plane_blend_tf_property) { 2101 *val = dm_plane_state->blend_tf; 2102 2103 } else { 2104 return -EINVAL; 2105 } 2106 2107 return 0; 2108 } 2109 #else 2110 2111 #define MAX_COLOR_PIPELINES 5 2112 2113 static int 2114 dm_plane_init_colorops(struct drm_plane *plane) 2115 { 2116 struct drm_prop_enum_list pipelines[MAX_COLOR_PIPELINES] = {}; 2117 struct drm_device *dev = plane->dev; 2118 struct amdgpu_device *adev = drm_to_adev(dev); 2119 struct dc *dc = adev->dm.dc; 2120 int len = 0; 2121 int ret = 0; 2122 int i; 2123 2124 if (plane->type == DRM_PLANE_TYPE_CURSOR) 2125 return 0; 2126 2127 /* initialize pipeline */ 2128 if (dc->ctx->dce_version >= DCN_VERSION_3_0) { 2129 ret = amdgpu_dm_initialize_default_pipeline(plane, &pipelines[len]); 2130 if (ret) { 2131 drm_err(plane->dev, "Failed to create color pipeline for plane %d: %pe\n", 2132 plane->base.id, ERR_PTR(ret)); 2133 goto out; 2134 } 2135 len++; 2136 2137 /* Create COLOR_PIPELINE property and attach */ 2138 drm_plane_create_color_pipeline_property(plane, pipelines, len); 2139 } 2140 2141 out: 2142 for (i = 0; i < len; i++) 2143 kfree(pipelines[i].name); 2144 2145 return ret; 2146 } 2147 #endif 2148 2149 static const struct drm_plane_funcs dm_plane_funcs = { 2150 .update_plane = drm_atomic_helper_update_plane, 2151 .disable_plane = drm_atomic_helper_disable_plane, 2152 .destroy = drm_plane_helper_destroy, 2153 .reset = amdgpu_dm_plane_drm_plane_reset, 2154 .atomic_duplicate_state = amdgpu_dm_plane_drm_plane_duplicate_state, 2155 .atomic_destroy_state = amdgpu_dm_plane_drm_plane_destroy_state, 2156 .format_mod_supported = amdgpu_dm_plane_format_mod_supported, 2157 .format_mod_supported_async = amdgpu_dm_plane_format_mod_supported, 2158 #ifdef AMD_PRIVATE_COLOR 2159 .atomic_set_property = dm_atomic_plane_set_property, 2160 .atomic_get_property = dm_atomic_plane_get_property, 2161 #endif 2162 }; 2163 2164 int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, 2165 struct drm_plane *plane, 2166 unsigned long possible_crtcs, 2167 const struct dc_plane_cap *plane_cap) 2168 { 2169 uint32_t formats[32]; 2170 int num_formats; 2171 int res = -EPERM; 2172 unsigned int supported_rotations; 2173 uint64_t *modifiers = NULL; 2174 unsigned int primary_zpos = dm->dc->caps.max_slave_planes; 2175 2176 num_formats = amdgpu_dm_plane_get_plane_formats(plane, plane_cap, formats, 2177 ARRAY_SIZE(formats)); 2178 2179 res = amdgpu_dm_plane_get_plane_modifiers(dm->adev, plane->type, &modifiers); 2180 if (res) 2181 return res; 2182 2183 if (modifiers == NULL) 2184 adev_to_drm(dm->adev)->mode_config.fb_modifiers_not_supported = true; 2185 2186 res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs, 2187 &dm_plane_funcs, formats, num_formats, 2188 modifiers, plane->type, NULL); 2189 kfree(modifiers); 2190 if (res) 2191 return res; 2192 2193 /* Blend mode support varies on DCE generations according to HW caps 2194 * and number of planes per CRTC. However, as current driver 2195 * implementation only creates one primary and one cursor plane per 2196 * CRTC for DCE (overlay is only created if 2197 * DC_PLANE_TYPE_DCN_UNIVERSAL), the primary plane blend mode is 2198 * ignored across DCE versions. Keep PREMULTI to avoid uAPI 2199 * regressions: it was the default/mandatory mode for many years and, 2200 * with no overlay plane, primary composes on top of a black 2201 * background, where PREMULTI and PIXEL_NONE are equivalent. 2202 */ 2203 if (plane_cap && plane_cap->type != DC_PLANE_TYPE_DCN_UNIVERSAL) { 2204 unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | 2205 BIT(DRM_MODE_BLEND_PREMULTI); 2206 2207 drm_plane_create_blend_mode_property(plane, blend_caps); 2208 } else if ((plane->type == DRM_PLANE_TYPE_OVERLAY || 2209 plane->type == DRM_PLANE_TYPE_PRIMARY) && 2210 plane_cap && plane_cap->per_pixel_alpha) { 2211 unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) | 2212 BIT(DRM_MODE_BLEND_PREMULTI) | 2213 BIT(DRM_MODE_BLEND_COVERAGE); 2214 2215 drm_plane_create_blend_mode_property(plane, blend_caps); 2216 2217 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 2218 drm_plane_create_alpha_property(plane); 2219 } 2220 2221 /* Cursor color format is set to CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA 2222 * by default, so only advertise DRM_MODE_BLEND_PREMULTI blend mode for 2223 * this type of plane. 2224 */ 2225 if (plane->type == DRM_PLANE_TYPE_CURSOR) 2226 drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_PREMULTI)); 2227 2228 if (plane->type == DRM_PLANE_TYPE_PRIMARY) { 2229 /* 2230 * Allow OVERLAY planes to be used as underlays by assigning an 2231 * immutable zpos = # of OVERLAY planes to the PRIMARY plane. 2232 */ 2233 drm_plane_create_zpos_immutable_property(plane, primary_zpos); 2234 } else if (plane->type == DRM_PLANE_TYPE_OVERLAY) { 2235 /* 2236 * OVERLAY planes can be below or above the PRIMARY, but cannot 2237 * be above the CURSOR plane. 2238 */ 2239 unsigned int zpos = primary_zpos + 1 + drm_plane_index(plane); 2240 2241 drm_plane_create_zpos_property(plane, zpos, 0, 254); 2242 } else if (plane->type == DRM_PLANE_TYPE_CURSOR) { 2243 drm_plane_create_zpos_immutable_property(plane, 255); 2244 } 2245 2246 if ((plane->type == DRM_PLANE_TYPE_PRIMARY || 2247 plane->type == DRM_PLANE_TYPE_OVERLAY) && 2248 plane_cap && 2249 (plane_cap->pixel_format_support.nv12 || 2250 plane_cap->pixel_format_support.p010)) { 2251 /* This only affects YUV formats. */ 2252 drm_plane_create_color_properties( 2253 plane, 2254 BIT(DRM_COLOR_YCBCR_BT601) | 2255 BIT(DRM_COLOR_YCBCR_BT709) | 2256 BIT(DRM_COLOR_YCBCR_BT2020), 2257 BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 2258 BIT(DRM_COLOR_YCBCR_FULL_RANGE), 2259 DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE); 2260 } 2261 2262 supported_rotations = 2263 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 | 2264 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270; 2265 2266 if (dm->adev->asic_type >= CHIP_BONAIRE && 2267 plane->type != DRM_PLANE_TYPE_CURSOR) 2268 drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, 2269 supported_rotations); 2270 2271 if (amdgpu_ip_version(dm->adev, DCE_HWIP, 0) > IP_VERSION(3, 0, 1) && 2272 plane->type != DRM_PLANE_TYPE_CURSOR) 2273 drm_plane_enable_fb_damage_clips(plane); 2274 2275 if (plane->type == DRM_PLANE_TYPE_PRIMARY) 2276 drm_plane_helper_add(plane, &dm_primary_plane_helper_funcs); 2277 else 2278 drm_plane_helper_add(plane, &dm_plane_helper_funcs); 2279 2280 #ifdef AMD_PRIVATE_COLOR 2281 dm_atomic_plane_attach_color_mgmt_properties(dm, plane); 2282 #else 2283 res = dm_plane_init_colorops(plane); 2284 if (res) 2285 return res; 2286 #endif 2287 2288 /* Create (reset) the plane state */ 2289 if (plane->funcs->reset) 2290 plane->funcs->reset(plane); 2291 2292 return 0; 2293 } 2294 2295 bool amdgpu_dm_plane_is_video_format(uint32_t format) 2296 { 2297 int i; 2298 2299 for (i = 0; i < ARRAY_SIZE(video_formats); i++) 2300 if (format == video_formats[i]) 2301 return true; 2302 2303 return false; 2304 } 2305 EXPORT_IF_KUNIT(amdgpu_dm_plane_is_video_format); 2306 2307