]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
Merge tag 'input-for-v6.4-rc0' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor...
[linux.git] / drivers / gpu / drm / amd / display / amdgpu_dm / amdgpu_dm_plane.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2022 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_gem_atomic_helper.h>
30 #include <drm/drm_plane_helper.h>
31 #include <drm/drm_fourcc.h>
32
33 #include "amdgpu.h"
34 #include "dal_asic_id.h"
35 #include "amdgpu_display.h"
36 #include "amdgpu_dm_trace.h"
37 #include "amdgpu_dm_plane.h"
38 #include "gc/gc_11_0_0_offset.h"
39 #include "gc/gc_11_0_0_sh_mask.h"
40
41 /*
42  * TODO: these are currently initialized to rgb formats only.
43  * For future use cases we should either initialize them dynamically based on
44  * plane capabilities, or initialize this array to all formats, so internal drm
45  * check will succeed, and let DC implement proper check
46  */
47 static const uint32_t rgb_formats[] = {
48         DRM_FORMAT_XRGB8888,
49         DRM_FORMAT_ARGB8888,
50         DRM_FORMAT_RGBA8888,
51         DRM_FORMAT_XRGB2101010,
52         DRM_FORMAT_XBGR2101010,
53         DRM_FORMAT_ARGB2101010,
54         DRM_FORMAT_ABGR2101010,
55         DRM_FORMAT_XRGB16161616,
56         DRM_FORMAT_XBGR16161616,
57         DRM_FORMAT_ARGB16161616,
58         DRM_FORMAT_ABGR16161616,
59         DRM_FORMAT_XBGR8888,
60         DRM_FORMAT_ABGR8888,
61         DRM_FORMAT_RGB565,
62 };
63
64 static const uint32_t overlay_formats[] = {
65         DRM_FORMAT_XRGB8888,
66         DRM_FORMAT_ARGB8888,
67         DRM_FORMAT_RGBA8888,
68         DRM_FORMAT_XBGR8888,
69         DRM_FORMAT_ABGR8888,
70         DRM_FORMAT_RGB565,
71         DRM_FORMAT_NV21,
72         DRM_FORMAT_NV12,
73         DRM_FORMAT_P010
74 };
75
76 static const uint32_t video_formats[] = {
77         DRM_FORMAT_NV21,
78         DRM_FORMAT_NV12,
79         DRM_FORMAT_P010
80 };
81
82 static const u32 cursor_formats[] = {
83         DRM_FORMAT_ARGB8888
84 };
85
86 enum dm_micro_swizzle {
87         MICRO_SWIZZLE_Z = 0,
88         MICRO_SWIZZLE_S = 1,
89         MICRO_SWIZZLE_D = 2,
90         MICRO_SWIZZLE_R = 3
91 };
92
93 const struct drm_format_info *amdgpu_dm_plane_get_format_info(const struct drm_mode_fb_cmd2 *cmd)
94 {
95         return amdgpu_lookup_format_info(cmd->pixel_format, cmd->modifier[0]);
96 }
97
98 void amdgpu_dm_plane_fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
99                                bool *per_pixel_alpha, bool *pre_multiplied_alpha,
100                                bool *global_alpha, int *global_alpha_value)
101 {
102         *per_pixel_alpha = false;
103         *pre_multiplied_alpha = true;
104         *global_alpha = false;
105         *global_alpha_value = 0xff;
106
107         if (plane_state->plane->type != DRM_PLANE_TYPE_OVERLAY)
108                 return;
109
110         if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI ||
111                 plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) {
112                 static const uint32_t alpha_formats[] = {
113                         DRM_FORMAT_ARGB8888,
114                         DRM_FORMAT_RGBA8888,
115                         DRM_FORMAT_ABGR8888,
116                 };
117                 uint32_t format = plane_state->fb->format->format;
118                 unsigned int i;
119
120                 for (i = 0; i < ARRAY_SIZE(alpha_formats); ++i) {
121                         if (format == alpha_formats[i]) {
122                                 *per_pixel_alpha = true;
123                                 break;
124                         }
125                 }
126
127                 if (*per_pixel_alpha && plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE)
128                         *pre_multiplied_alpha = false;
129         }
130
131         if (plane_state->alpha < 0xffff) {
132                 *global_alpha = true;
133                 *global_alpha_value = plane_state->alpha >> 8;
134         }
135 }
136
137 static void add_modifier(uint64_t **mods, uint64_t *size, uint64_t *cap, uint64_t mod)
138 {
139         if (!*mods)
140                 return;
141
142         if (*cap - *size < 1) {
143                 uint64_t new_cap = *cap * 2;
144                 uint64_t *new_mods = kmalloc(new_cap * sizeof(uint64_t), GFP_KERNEL);
145
146                 if (!new_mods) {
147                         kfree(*mods);
148                         *mods = NULL;
149                         return;
150                 }
151
152                 memcpy(new_mods, *mods, sizeof(uint64_t) * *size);
153                 kfree(*mods);
154                 *mods = new_mods;
155                 *cap = new_cap;
156         }
157
158         (*mods)[*size] = mod;
159         *size += 1;
160 }
161
162 static bool modifier_has_dcc(uint64_t modifier)
163 {
164         return IS_AMD_FMT_MOD(modifier) && AMD_FMT_MOD_GET(DCC, modifier);
165 }
166
167 static unsigned modifier_gfx9_swizzle_mode(uint64_t modifier)
168 {
169         if (modifier == DRM_FORMAT_MOD_LINEAR)
170                 return 0;
171
172         return AMD_FMT_MOD_GET(TILE, modifier);
173 }
174
175 static void fill_gfx8_tiling_info_from_flags(union dc_tiling_info *tiling_info,
176                                  uint64_t tiling_flags)
177 {
178         /* Fill GFX8 params */
179         if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE) == DC_ARRAY_2D_TILED_THIN1) {
180                 unsigned int bankw, bankh, mtaspect, tile_split, num_banks;
181
182                 bankw = AMDGPU_TILING_GET(tiling_flags, BANK_WIDTH);
183                 bankh = AMDGPU_TILING_GET(tiling_flags, BANK_HEIGHT);
184                 mtaspect = AMDGPU_TILING_GET(tiling_flags, MACRO_TILE_ASPECT);
185                 tile_split = AMDGPU_TILING_GET(tiling_flags, TILE_SPLIT);
186                 num_banks = AMDGPU_TILING_GET(tiling_flags, NUM_BANKS);
187
188                 /* XXX fix me for VI */
189                 tiling_info->gfx8.num_banks = num_banks;
190                 tiling_info->gfx8.array_mode =
191                                 DC_ARRAY_2D_TILED_THIN1;
192                 tiling_info->gfx8.tile_split = tile_split;
193                 tiling_info->gfx8.bank_width = bankw;
194                 tiling_info->gfx8.bank_height = bankh;
195                 tiling_info->gfx8.tile_aspect = mtaspect;
196                 tiling_info->gfx8.tile_mode =
197                                 DC_ADDR_SURF_MICRO_TILING_DISPLAY;
198         } else if (AMDGPU_TILING_GET(tiling_flags, ARRAY_MODE)
199                         == DC_ARRAY_1D_TILED_THIN1) {
200                 tiling_info->gfx8.array_mode = DC_ARRAY_1D_TILED_THIN1;
201         }
202
203         tiling_info->gfx8.pipe_config =
204                         AMDGPU_TILING_GET(tiling_flags, PIPE_CONFIG);
205 }
206
207 static void fill_gfx9_tiling_info_from_device(const struct amdgpu_device *adev,
208                                   union dc_tiling_info *tiling_info)
209 {
210         /* Fill GFX9 params */
211         tiling_info->gfx9.num_pipes =
212                 adev->gfx.config.gb_addr_config_fields.num_pipes;
213         tiling_info->gfx9.num_banks =
214                 adev->gfx.config.gb_addr_config_fields.num_banks;
215         tiling_info->gfx9.pipe_interleave =
216                 adev->gfx.config.gb_addr_config_fields.pipe_interleave_size;
217         tiling_info->gfx9.num_shader_engines =
218                 adev->gfx.config.gb_addr_config_fields.num_se;
219         tiling_info->gfx9.max_compressed_frags =
220                 adev->gfx.config.gb_addr_config_fields.max_compress_frags;
221         tiling_info->gfx9.num_rb_per_se =
222                 adev->gfx.config.gb_addr_config_fields.num_rb_per_se;
223         tiling_info->gfx9.shaderEnable = 1;
224         if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
225                 tiling_info->gfx9.num_pkrs = adev->gfx.config.gb_addr_config_fields.num_pkrs;
226 }
227
228 static void fill_gfx9_tiling_info_from_modifier(const struct amdgpu_device *adev,
229                                     union dc_tiling_info *tiling_info,
230                                     uint64_t modifier)
231 {
232         unsigned int mod_bank_xor_bits = AMD_FMT_MOD_GET(BANK_XOR_BITS, modifier);
233         unsigned int mod_pipe_xor_bits = AMD_FMT_MOD_GET(PIPE_XOR_BITS, modifier);
234         unsigned int pkrs_log2 = AMD_FMT_MOD_GET(PACKERS, modifier);
235         unsigned int pipes_log2;
236
237         pipes_log2 = min(5u, mod_pipe_xor_bits);
238
239         fill_gfx9_tiling_info_from_device(adev, tiling_info);
240
241         if (!IS_AMD_FMT_MOD(modifier))
242                 return;
243
244         tiling_info->gfx9.num_pipes = 1u << pipes_log2;
245         tiling_info->gfx9.num_shader_engines = 1u << (mod_pipe_xor_bits - pipes_log2);
246
247         if (adev->family >= AMDGPU_FAMILY_NV) {
248                 tiling_info->gfx9.num_pkrs = 1u << pkrs_log2;
249         } else {
250                 tiling_info->gfx9.num_banks = 1u << mod_bank_xor_bits;
251
252                 /* for DCC we know it isn't rb aligned, so rb_per_se doesn't matter. */
253         }
254 }
255
256 static int validate_dcc(struct amdgpu_device *adev,
257              const enum surface_pixel_format format,
258              const enum dc_rotation_angle rotation,
259              const union dc_tiling_info *tiling_info,
260              const struct dc_plane_dcc_param *dcc,
261              const struct dc_plane_address *address,
262              const struct plane_size *plane_size)
263 {
264         struct dc *dc = adev->dm.dc;
265         struct dc_dcc_surface_param input;
266         struct dc_surface_dcc_cap output;
267
268         memset(&input, 0, sizeof(input));
269         memset(&output, 0, sizeof(output));
270
271         if (!dcc->enable)
272                 return 0;
273
274         if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN ||
275             !dc->cap_funcs.get_dcc_compression_cap)
276                 return -EINVAL;
277
278         input.format = format;
279         input.surface_size.width = plane_size->surface_size.width;
280         input.surface_size.height = plane_size->surface_size.height;
281         input.swizzle_mode = tiling_info->gfx9.swizzle;
282
283         if (rotation == ROTATION_ANGLE_0 || rotation == ROTATION_ANGLE_180)
284                 input.scan = SCAN_DIRECTION_HORIZONTAL;
285         else if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270)
286                 input.scan = SCAN_DIRECTION_VERTICAL;
287
288         if (!dc->cap_funcs.get_dcc_compression_cap(dc, &input, &output))
289                 return -EINVAL;
290
291         if (!output.capable)
292                 return -EINVAL;
293
294         if (dcc->independent_64b_blks == 0 &&
295             output.grph.rgb.independent_64b_blks != 0)
296                 return -EINVAL;
297
298         return 0;
299 }
300
301 static int fill_gfx9_plane_attributes_from_modifiers(struct amdgpu_device *adev,
302                                           const struct amdgpu_framebuffer *afb,
303                                           const enum surface_pixel_format format,
304                                           const enum dc_rotation_angle rotation,
305                                           const struct plane_size *plane_size,
306                                           union dc_tiling_info *tiling_info,
307                                           struct dc_plane_dcc_param *dcc,
308                                           struct dc_plane_address *address,
309                                           const bool force_disable_dcc)
310 {
311         const uint64_t modifier = afb->base.modifier;
312         int ret = 0;
313
314         fill_gfx9_tiling_info_from_modifier(adev, tiling_info, modifier);
315         tiling_info->gfx9.swizzle = modifier_gfx9_swizzle_mode(modifier);
316
317         if (modifier_has_dcc(modifier) && !force_disable_dcc) {
318                 uint64_t dcc_address = afb->address + afb->base.offsets[1];
319                 bool independent_64b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_64B, modifier);
320                 bool independent_128b_blks = AMD_FMT_MOD_GET(DCC_INDEPENDENT_128B, modifier);
321
322                 dcc->enable = 1;
323                 dcc->meta_pitch = afb->base.pitches[1];
324                 dcc->independent_64b_blks = independent_64b_blks;
325                 if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) >= AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) {
326                         if (independent_64b_blks && independent_128b_blks)
327                                 dcc->dcc_ind_blk = hubp_ind_block_64b_no_128bcl;
328                         else if (independent_128b_blks)
329                                 dcc->dcc_ind_blk = hubp_ind_block_128b;
330                         else if (independent_64b_blks && !independent_128b_blks)
331                                 dcc->dcc_ind_blk = hubp_ind_block_64b;
332                         else
333                                 dcc->dcc_ind_blk = hubp_ind_block_unconstrained;
334                 } else {
335                         if (independent_64b_blks)
336                                 dcc->dcc_ind_blk = hubp_ind_block_64b;
337                         else
338                                 dcc->dcc_ind_blk = hubp_ind_block_unconstrained;
339                 }
340
341                 address->grph.meta_addr.low_part = lower_32_bits(dcc_address);
342                 address->grph.meta_addr.high_part = upper_32_bits(dcc_address);
343         }
344
345         ret = validate_dcc(adev, format, rotation, tiling_info, dcc, address, plane_size);
346         if (ret)
347                 drm_dbg_kms(adev_to_drm(adev), "validate_dcc: returned error: %d\n", ret);
348
349         return ret;
350 }
351
352 static void add_gfx10_1_modifiers(const struct amdgpu_device *adev,
353                       uint64_t **mods, uint64_t *size, uint64_t *capacity)
354 {
355         int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
356
357         add_modifier(mods, size, capacity, AMD_FMT_MOD |
358                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
359                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
360                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
361                     AMD_FMT_MOD_SET(DCC, 1) |
362                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
363                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
364                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
365
366         add_modifier(mods, size, capacity, AMD_FMT_MOD |
367                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
368                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
369                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
370                     AMD_FMT_MOD_SET(DCC, 1) |
371                     AMD_FMT_MOD_SET(DCC_RETILE, 1) |
372                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
373                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
374                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
375
376         add_modifier(mods, size, capacity, AMD_FMT_MOD |
377                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
378                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
379                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
380
381         add_modifier(mods, size, capacity, AMD_FMT_MOD |
382                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
383                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10) |
384                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits));
385
386
387         /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
388         add_modifier(mods, size, capacity, AMD_FMT_MOD |
389                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
390                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
391
392         add_modifier(mods, size, capacity, AMD_FMT_MOD |
393                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
394                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
395 }
396
397 static void add_gfx9_modifiers(const struct amdgpu_device *adev,
398                    uint64_t **mods, uint64_t *size, uint64_t *capacity)
399 {
400         int pipes = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
401         int pipe_xor_bits = min(8, pipes +
402                                 ilog2(adev->gfx.config.gb_addr_config_fields.num_se));
403         int bank_xor_bits = min(8 - pipe_xor_bits,
404                                 ilog2(adev->gfx.config.gb_addr_config_fields.num_banks));
405         int rb = ilog2(adev->gfx.config.gb_addr_config_fields.num_se) +
406                  ilog2(adev->gfx.config.gb_addr_config_fields.num_rb_per_se);
407
408
409         if (adev->family == AMDGPU_FAMILY_RV) {
410                 /* Raven2 and later */
411                 bool has_constant_encode = adev->asic_type > CHIP_RAVEN || adev->external_rev_id >= 0x81;
412
413                 /*
414                  * No _D DCC swizzles yet because we only allow 32bpp, which
415                  * doesn't support _D on DCN
416                  */
417
418                 if (has_constant_encode) {
419                         add_modifier(mods, size, capacity, AMD_FMT_MOD |
420                                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
421                                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
422                                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
423                                     AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
424                                     AMD_FMT_MOD_SET(DCC, 1) |
425                                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
426                                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
427                                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1));
428                 }
429
430                 add_modifier(mods, size, capacity, AMD_FMT_MOD |
431                             AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
432                             AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
433                             AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
434                             AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
435                             AMD_FMT_MOD_SET(DCC, 1) |
436                             AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
437                             AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
438                             AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0));
439
440                 if (has_constant_encode) {
441                         add_modifier(mods, size, capacity, AMD_FMT_MOD |
442                                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
443                                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
444                                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
445                                     AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
446                                     AMD_FMT_MOD_SET(DCC, 1) |
447                                     AMD_FMT_MOD_SET(DCC_RETILE, 1) |
448                                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
449                                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
450
451                                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
452                                     AMD_FMT_MOD_SET(RB, rb) |
453                                     AMD_FMT_MOD_SET(PIPE, pipes));
454                 }
455
456                 add_modifier(mods, size, capacity, AMD_FMT_MOD |
457                             AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
458                             AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
459                             AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
460                             AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits) |
461                             AMD_FMT_MOD_SET(DCC, 1) |
462                             AMD_FMT_MOD_SET(DCC_RETILE, 1) |
463                             AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
464                             AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B) |
465                             AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 0) |
466                             AMD_FMT_MOD_SET(RB, rb) |
467                             AMD_FMT_MOD_SET(PIPE, pipes));
468         }
469
470         /*
471          * Only supported for 64bpp on Raven, will be filtered on format in
472          * dm_plane_format_mod_supported.
473          */
474         add_modifier(mods, size, capacity, AMD_FMT_MOD |
475                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D_X) |
476                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
477                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
478                     AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
479
480         if (adev->family == AMDGPU_FAMILY_RV) {
481                 add_modifier(mods, size, capacity, AMD_FMT_MOD |
482                             AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
483                             AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9) |
484                             AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
485                             AMD_FMT_MOD_SET(BANK_XOR_BITS, bank_xor_bits));
486         }
487
488         /*
489          * Only supported for 64bpp on Raven, will be filtered on format in
490          * dm_plane_format_mod_supported.
491          */
492         add_modifier(mods, size, capacity, AMD_FMT_MOD |
493                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
494                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
495
496         if (adev->family == AMDGPU_FAMILY_RV) {
497                 add_modifier(mods, size, capacity, AMD_FMT_MOD |
498                             AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
499                             AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
500         }
501 }
502
503 static void add_gfx10_3_modifiers(const struct amdgpu_device *adev,
504                       uint64_t **mods, uint64_t *size, uint64_t *capacity)
505 {
506         int pipe_xor_bits = ilog2(adev->gfx.config.gb_addr_config_fields.num_pipes);
507         int pkrs = ilog2(adev->gfx.config.gb_addr_config_fields.num_pkrs);
508
509         add_modifier(mods, size, capacity, AMD_FMT_MOD |
510                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
511                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
512                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
513                     AMD_FMT_MOD_SET(PACKERS, pkrs) |
514                     AMD_FMT_MOD_SET(DCC, 1) |
515                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
516                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
517                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
518                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
519
520         add_modifier(mods, size, capacity, AMD_FMT_MOD |
521                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
522                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
523                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
524                     AMD_FMT_MOD_SET(PACKERS, pkrs) |
525                     AMD_FMT_MOD_SET(DCC, 1) |
526                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
527                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
528                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
529
530         add_modifier(mods, size, capacity, AMD_FMT_MOD |
531                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
532                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
533                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
534                     AMD_FMT_MOD_SET(PACKERS, pkrs) |
535                     AMD_FMT_MOD_SET(DCC, 1) |
536                     AMD_FMT_MOD_SET(DCC_RETILE, 1) |
537                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
538                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
539                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
540                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B));
541
542         add_modifier(mods, size, capacity, AMD_FMT_MOD |
543                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
544                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
545                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
546                     AMD_FMT_MOD_SET(PACKERS, pkrs) |
547                     AMD_FMT_MOD_SET(DCC, 1) |
548                     AMD_FMT_MOD_SET(DCC_RETILE, 1) |
549                     AMD_FMT_MOD_SET(DCC_CONSTANT_ENCODE, 1) |
550                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
551                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B));
552
553         add_modifier(mods, size, capacity, AMD_FMT_MOD |
554                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_R_X) |
555                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
556                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
557                     AMD_FMT_MOD_SET(PACKERS, pkrs));
558
559         add_modifier(mods, size, capacity, AMD_FMT_MOD |
560                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S_X) |
561                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX10_RBPLUS) |
562                     AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
563                     AMD_FMT_MOD_SET(PACKERS, pkrs));
564
565         /* Only supported for 64bpp, will be filtered in dm_plane_format_mod_supported */
566         add_modifier(mods, size, capacity, AMD_FMT_MOD |
567                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D) |
568                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
569
570         add_modifier(mods, size, capacity, AMD_FMT_MOD |
571                     AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_S) |
572                     AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX9));
573 }
574
575 static void add_gfx11_modifiers(struct amdgpu_device *adev,
576                       uint64_t **mods, uint64_t *size, uint64_t *capacity)
577 {
578         int num_pipes = 0;
579         int pipe_xor_bits = 0;
580         int num_pkrs = 0;
581         int pkrs = 0;
582         u32 gb_addr_config;
583         u8 i = 0;
584         unsigned swizzle_r_x;
585         uint64_t modifier_r_x;
586         uint64_t modifier_dcc_best;
587         uint64_t modifier_dcc_4k;
588
589         /* TODO: GFX11 IP HW init hasnt finish and we get zero if we read from
590          * adev->gfx.config.gb_addr_config_fields.num_{pkrs,pipes}
591          */
592         gb_addr_config = RREG32_SOC15(GC, 0, regGB_ADDR_CONFIG);
593         ASSERT(gb_addr_config != 0);
594
595         num_pkrs = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PKRS);
596         pkrs = ilog2(num_pkrs);
597         num_pipes = 1 << REG_GET_FIELD(gb_addr_config, GB_ADDR_CONFIG, NUM_PIPES);
598         pipe_xor_bits = ilog2(num_pipes);
599
600         for (i = 0; i < 2; i++) {
601                 /* Insert the best one first. */
602                 /* R_X swizzle modes are the best for rendering and DCC requires them. */
603                 if (num_pipes > 16)
604                         swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX11_256K_R_X : AMD_FMT_MOD_TILE_GFX9_64K_R_X;
605                 else
606                         swizzle_r_x = !i ? AMD_FMT_MOD_TILE_GFX9_64K_R_X : AMD_FMT_MOD_TILE_GFX11_256K_R_X;
607
608                 modifier_r_x = AMD_FMT_MOD |
609                                AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
610                                AMD_FMT_MOD_SET(PIPE_XOR_BITS, pipe_xor_bits) |
611                                AMD_FMT_MOD_SET(TILE, swizzle_r_x) |
612                                AMD_FMT_MOD_SET(PACKERS, pkrs);
613
614                 /* DCC_CONSTANT_ENCODE is not set because it can't vary with gfx11 (it's implied to be 1). */
615                 modifier_dcc_best = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) |
616                                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 0) |
617                                     AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
618                                     AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_128B);
619
620                 /* DCC settings for 4K and greater resolutions. (required by display hw) */
621                 modifier_dcc_4k = modifier_r_x | AMD_FMT_MOD_SET(DCC, 1) |
622                                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_64B, 1) |
623                                   AMD_FMT_MOD_SET(DCC_INDEPENDENT_128B, 1) |
624                                   AMD_FMT_MOD_SET(DCC_MAX_COMPRESSED_BLOCK, AMD_FMT_MOD_DCC_BLOCK_64B);
625
626                 add_modifier(mods, size, capacity, modifier_dcc_best);
627                 add_modifier(mods, size, capacity, modifier_dcc_4k);
628
629                 add_modifier(mods, size, capacity, modifier_dcc_best | AMD_FMT_MOD_SET(DCC_RETILE, 1));
630                 add_modifier(mods, size, capacity, modifier_dcc_4k | AMD_FMT_MOD_SET(DCC_RETILE, 1));
631
632                 add_modifier(mods, size, capacity, modifier_r_x);
633         }
634
635         add_modifier(mods, size, capacity, AMD_FMT_MOD |
636                         AMD_FMT_MOD_SET(TILE_VERSION, AMD_FMT_MOD_TILE_VER_GFX11) |
637                         AMD_FMT_MOD_SET(TILE, AMD_FMT_MOD_TILE_GFX9_64K_D));
638 }
639
640 static int get_plane_modifiers(struct amdgpu_device *adev, unsigned int plane_type, uint64_t **mods)
641 {
642         uint64_t size = 0, capacity = 128;
643         *mods = NULL;
644
645         /* We have not hooked up any pre-GFX9 modifiers. */
646         if (adev->family < AMDGPU_FAMILY_AI)
647                 return 0;
648
649         *mods = kmalloc(capacity * sizeof(uint64_t), GFP_KERNEL);
650
651         if (plane_type == DRM_PLANE_TYPE_CURSOR) {
652                 add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
653                 add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
654                 return *mods ? 0 : -ENOMEM;
655         }
656
657         switch (adev->family) {
658         case AMDGPU_FAMILY_AI:
659         case AMDGPU_FAMILY_RV:
660                 add_gfx9_modifiers(adev, mods, &size, &capacity);
661                 break;
662         case AMDGPU_FAMILY_NV:
663         case AMDGPU_FAMILY_VGH:
664         case AMDGPU_FAMILY_YC:
665         case AMDGPU_FAMILY_GC_10_3_6:
666         case AMDGPU_FAMILY_GC_10_3_7:
667                 if (adev->ip_versions[GC_HWIP][0] >= IP_VERSION(10, 3, 0))
668                         add_gfx10_3_modifiers(adev, mods, &size, &capacity);
669                 else
670                         add_gfx10_1_modifiers(adev, mods, &size, &capacity);
671                 break;
672         case AMDGPU_FAMILY_GC_11_0_0:
673         case AMDGPU_FAMILY_GC_11_0_1:
674                 add_gfx11_modifiers(adev, mods, &size, &capacity);
675                 break;
676         }
677
678         add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_LINEAR);
679
680         /* INVALID marks the end of the list. */
681         add_modifier(mods, &size, &capacity, DRM_FORMAT_MOD_INVALID);
682
683         if (!*mods)
684                 return -ENOMEM;
685
686         return 0;
687 }
688
689 static int get_plane_formats(const struct drm_plane *plane,
690                              const struct dc_plane_cap *plane_cap,
691                              uint32_t *formats, int max_formats)
692 {
693         int i, num_formats = 0;
694
695         /*
696          * TODO: Query support for each group of formats directly from
697          * DC plane caps. This will require adding more formats to the
698          * caps list.
699          */
700
701         switch (plane->type) {
702         case DRM_PLANE_TYPE_PRIMARY:
703                 for (i = 0; i < ARRAY_SIZE(rgb_formats); ++i) {
704                         if (num_formats >= max_formats)
705                                 break;
706
707                         formats[num_formats++] = rgb_formats[i];
708                 }
709
710                 if (plane_cap && plane_cap->pixel_format_support.nv12)
711                         formats[num_formats++] = DRM_FORMAT_NV12;
712                 if (plane_cap && plane_cap->pixel_format_support.p010)
713                         formats[num_formats++] = DRM_FORMAT_P010;
714                 if (plane_cap && plane_cap->pixel_format_support.fp16) {
715                         formats[num_formats++] = DRM_FORMAT_XRGB16161616F;
716                         formats[num_formats++] = DRM_FORMAT_ARGB16161616F;
717                         formats[num_formats++] = DRM_FORMAT_XBGR16161616F;
718                         formats[num_formats++] = DRM_FORMAT_ABGR16161616F;
719                 }
720                 break;
721
722         case DRM_PLANE_TYPE_OVERLAY:
723                 for (i = 0; i < ARRAY_SIZE(overlay_formats); ++i) {
724                         if (num_formats >= max_formats)
725                                 break;
726
727                         formats[num_formats++] = overlay_formats[i];
728                 }
729                 break;
730
731         case DRM_PLANE_TYPE_CURSOR:
732                 for (i = 0; i < ARRAY_SIZE(cursor_formats); ++i) {
733                         if (num_formats >= max_formats)
734                                 break;
735
736                         formats[num_formats++] = cursor_formats[i];
737                 }
738                 break;
739         }
740
741         return num_formats;
742 }
743
744 int amdgpu_dm_plane_fill_plane_buffer_attributes(struct amdgpu_device *adev,
745                              const struct amdgpu_framebuffer *afb,
746                              const enum surface_pixel_format format,
747                              const enum dc_rotation_angle rotation,
748                              const uint64_t tiling_flags,
749                              union dc_tiling_info *tiling_info,
750                              struct plane_size *plane_size,
751                              struct dc_plane_dcc_param *dcc,
752                              struct dc_plane_address *address,
753                              bool tmz_surface,
754                              bool force_disable_dcc)
755 {
756         const struct drm_framebuffer *fb = &afb->base;
757         int ret;
758
759         memset(tiling_info, 0, sizeof(*tiling_info));
760         memset(plane_size, 0, sizeof(*plane_size));
761         memset(dcc, 0, sizeof(*dcc));
762         memset(address, 0, sizeof(*address));
763
764         address->tmz_surface = tmz_surface;
765
766         if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
767                 uint64_t addr = afb->address + fb->offsets[0];
768
769                 plane_size->surface_size.x = 0;
770                 plane_size->surface_size.y = 0;
771                 plane_size->surface_size.width = fb->width;
772                 plane_size->surface_size.height = fb->height;
773                 plane_size->surface_pitch =
774                         fb->pitches[0] / fb->format->cpp[0];
775
776                 address->type = PLN_ADDR_TYPE_GRAPHICS;
777                 address->grph.addr.low_part = lower_32_bits(addr);
778                 address->grph.addr.high_part = upper_32_bits(addr);
779         } else if (format < SURFACE_PIXEL_FORMAT_INVALID) {
780                 uint64_t luma_addr = afb->address + fb->offsets[0];
781                 uint64_t chroma_addr = afb->address + fb->offsets[1];
782
783                 plane_size->surface_size.x = 0;
784                 plane_size->surface_size.y = 0;
785                 plane_size->surface_size.width = fb->width;
786                 plane_size->surface_size.height = fb->height;
787                 plane_size->surface_pitch =
788                         fb->pitches[0] / fb->format->cpp[0];
789
790                 plane_size->chroma_size.x = 0;
791                 plane_size->chroma_size.y = 0;
792                 /* TODO: set these based on surface format */
793                 plane_size->chroma_size.width = fb->width / 2;
794                 plane_size->chroma_size.height = fb->height / 2;
795
796                 plane_size->chroma_pitch =
797                         fb->pitches[1] / fb->format->cpp[1];
798
799                 address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
800                 address->video_progressive.luma_addr.low_part =
801                         lower_32_bits(luma_addr);
802                 address->video_progressive.luma_addr.high_part =
803                         upper_32_bits(luma_addr);
804                 address->video_progressive.chroma_addr.low_part =
805                         lower_32_bits(chroma_addr);
806                 address->video_progressive.chroma_addr.high_part =
807                         upper_32_bits(chroma_addr);
808         }
809
810         if (adev->family >= AMDGPU_FAMILY_AI) {
811                 ret = fill_gfx9_plane_attributes_from_modifiers(adev, afb, format,
812                                                                 rotation, plane_size,
813                                                                 tiling_info, dcc,
814                                                                 address,
815                                                                 force_disable_dcc);
816                 if (ret)
817                         return ret;
818         } else {
819                 fill_gfx8_tiling_info_from_flags(tiling_info, tiling_flags);
820         }
821
822         return 0;
823 }
824
825 static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
826                                       struct drm_plane_state *new_state)
827 {
828         struct amdgpu_framebuffer *afb;
829         struct drm_gem_object *obj;
830         struct amdgpu_device *adev;
831         struct amdgpu_bo *rbo;
832         struct dm_plane_state *dm_plane_state_new, *dm_plane_state_old;
833         uint32_t domain;
834         int r;
835
836         if (!new_state->fb) {
837                 DRM_DEBUG_KMS("No FB bound\n");
838                 return 0;
839         }
840
841         afb = to_amdgpu_framebuffer(new_state->fb);
842         obj = new_state->fb->obj[0];
843         rbo = gem_to_amdgpu_bo(obj);
844         adev = amdgpu_ttm_adev(rbo->tbo.bdev);
845
846         r = amdgpu_bo_reserve(rbo, true);
847         if (r) {
848                 dev_err(adev->dev, "fail to reserve bo (%d)\n", r);
849                 return r;
850         }
851
852         r = dma_resv_reserve_fences(rbo->tbo.base.resv, 1);
853         if (r) {
854                 dev_err(adev->dev, "reserving fence slot failed (%d)\n", r);
855                 goto error_unlock;
856         }
857
858         if (plane->type != DRM_PLANE_TYPE_CURSOR)
859                 domain = amdgpu_display_supported_domains(adev, rbo->flags);
860         else
861                 domain = AMDGPU_GEM_DOMAIN_VRAM;
862
863         r = amdgpu_bo_pin(rbo, domain);
864         if (unlikely(r != 0)) {
865                 if (r != -ERESTARTSYS)
866                         DRM_ERROR("Failed to pin framebuffer with error %d\n", r);
867                 goto error_unlock;
868         }
869
870         r = amdgpu_ttm_alloc_gart(&rbo->tbo);
871         if (unlikely(r != 0)) {
872                 DRM_ERROR("%p bind failed\n", rbo);
873                 goto error_unpin;
874         }
875
876         r = drm_gem_plane_helper_prepare_fb(plane, new_state);
877         if (unlikely(r != 0))
878                 goto error_unpin;
879
880         amdgpu_bo_unreserve(rbo);
881
882         afb->address = amdgpu_bo_gpu_offset(rbo);
883
884         amdgpu_bo_ref(rbo);
885
886         /**
887          * We don't do surface updates on planes that have been newly created,
888          * but we also don't have the afb->address during atomic check.
889          *
890          * Fill in buffer attributes depending on the address here, but only on
891          * newly created planes since they're not being used by DC yet and this
892          * won't modify global state.
893          */
894         dm_plane_state_old = to_dm_plane_state(plane->state);
895         dm_plane_state_new = to_dm_plane_state(new_state);
896
897         if (dm_plane_state_new->dc_state &&
898             dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
899                 struct dc_plane_state *plane_state =
900                         dm_plane_state_new->dc_state;
901                 bool force_disable_dcc = !plane_state->dcc.enable;
902
903                 amdgpu_dm_plane_fill_plane_buffer_attributes(
904                         adev, afb, plane_state->format, plane_state->rotation,
905                         afb->tiling_flags,
906                         &plane_state->tiling_info, &plane_state->plane_size,
907                         &plane_state->dcc, &plane_state->address,
908                         afb->tmz_surface, force_disable_dcc);
909         }
910
911         return 0;
912
913 error_unpin:
914         amdgpu_bo_unpin(rbo);
915
916 error_unlock:
917         amdgpu_bo_unreserve(rbo);
918         return r;
919 }
920
921 static void dm_plane_helper_cleanup_fb(struct drm_plane *plane,
922                                        struct drm_plane_state *old_state)
923 {
924         struct amdgpu_bo *rbo;
925         int r;
926
927         if (!old_state->fb)
928                 return;
929
930         rbo = gem_to_amdgpu_bo(old_state->fb->obj[0]);
931         r = amdgpu_bo_reserve(rbo, false);
932         if (unlikely(r)) {
933                 DRM_ERROR("failed to reserve rbo before unpin\n");
934                 return;
935         }
936
937         amdgpu_bo_unpin(rbo);
938         amdgpu_bo_unreserve(rbo);
939         amdgpu_bo_unref(&rbo);
940 }
941
942 static void get_min_max_dc_plane_scaling(struct drm_device *dev,
943                                          struct drm_framebuffer *fb,
944                                          int *min_downscale, int *max_upscale)
945 {
946         struct amdgpu_device *adev = drm_to_adev(dev);
947         struct dc *dc = adev->dm.dc;
948         /* Caps for all supported planes are the same on DCE and DCN 1 - 3 */
949         struct dc_plane_cap *plane_cap = &dc->caps.planes[0];
950
951         switch (fb->format->format) {
952         case DRM_FORMAT_P010:
953         case DRM_FORMAT_NV12:
954         case DRM_FORMAT_NV21:
955                 *max_upscale = plane_cap->max_upscale_factor.nv12;
956                 *min_downscale = plane_cap->max_downscale_factor.nv12;
957                 break;
958
959         case DRM_FORMAT_XRGB16161616F:
960         case DRM_FORMAT_ARGB16161616F:
961         case DRM_FORMAT_XBGR16161616F:
962         case DRM_FORMAT_ABGR16161616F:
963                 *max_upscale = plane_cap->max_upscale_factor.fp16;
964                 *min_downscale = plane_cap->max_downscale_factor.fp16;
965                 break;
966
967         default:
968                 *max_upscale = plane_cap->max_upscale_factor.argb8888;
969                 *min_downscale = plane_cap->max_downscale_factor.argb8888;
970                 break;
971         }
972
973         /*
974          * A factor of 1 in the plane_cap means to not allow scaling, ie. use a
975          * scaling factor of 1.0 == 1000 units.
976          */
977         if (*max_upscale == 1)
978                 *max_upscale = 1000;
979
980         if (*min_downscale == 1)
981                 *min_downscale = 1000;
982 }
983
984 int amdgpu_dm_plane_helper_check_state(struct drm_plane_state *state,
985                                        struct drm_crtc_state *new_crtc_state)
986 {
987         struct drm_framebuffer *fb = state->fb;
988         int min_downscale, max_upscale;
989         int min_scale = 0;
990         int max_scale = INT_MAX;
991
992         /* Plane enabled? Validate viewport and get scaling factors from plane caps. */
993         if (fb && state->crtc) {
994                 /* Validate viewport to cover the case when only the position changes */
995                 if (state->plane->type != DRM_PLANE_TYPE_CURSOR) {
996                         int viewport_width = state->crtc_w;
997                         int viewport_height = state->crtc_h;
998
999                         if (state->crtc_x < 0)
1000                                 viewport_width += state->crtc_x;
1001                         else if (state->crtc_x + state->crtc_w > new_crtc_state->mode.crtc_hdisplay)
1002                                 viewport_width = new_crtc_state->mode.crtc_hdisplay - state->crtc_x;
1003
1004                         if (state->crtc_y < 0)
1005                                 viewport_height += state->crtc_y;
1006                         else if (state->crtc_y + state->crtc_h > new_crtc_state->mode.crtc_vdisplay)
1007                                 viewport_height = new_crtc_state->mode.crtc_vdisplay - state->crtc_y;
1008
1009                         if (viewport_width < 0 || viewport_height < 0) {
1010                                 DRM_DEBUG_ATOMIC("Plane completely outside of screen\n");
1011                                 return -EINVAL;
1012                         } else if (viewport_width < MIN_VIEWPORT_SIZE*2) { /* x2 for width is because of pipe-split. */
1013                                 DRM_DEBUG_ATOMIC("Viewport width %d smaller than %d\n", viewport_width, MIN_VIEWPORT_SIZE*2);
1014                                 return -EINVAL;
1015                         } else if (viewport_height < MIN_VIEWPORT_SIZE) {
1016                                 DRM_DEBUG_ATOMIC("Viewport height %d smaller than %d\n", viewport_height, MIN_VIEWPORT_SIZE);
1017                                 return -EINVAL;
1018                         }
1019
1020                 }
1021
1022                 /* Get min/max allowed scaling factors from plane caps. */
1023                 get_min_max_dc_plane_scaling(state->crtc->dev, fb,
1024                                              &min_downscale, &max_upscale);
1025                 /*
1026                  * Convert to drm convention: 16.16 fixed point, instead of dc's
1027                  * 1.0 == 1000. Also drm scaling is src/dst instead of dc's
1028                  * dst/src, so min_scale = 1.0 / max_upscale, etc.
1029                  */
1030                 min_scale = (1000 << 16) / max_upscale;
1031                 max_scale = (1000 << 16) / min_downscale;
1032         }
1033
1034         return drm_atomic_helper_check_plane_state(
1035                 state, new_crtc_state, min_scale, max_scale, true, true);
1036 }
1037
1038 int amdgpu_dm_plane_fill_dc_scaling_info(struct amdgpu_device *adev,
1039                                 const struct drm_plane_state *state,
1040                                 struct dc_scaling_info *scaling_info)
1041 {
1042         int scale_w, scale_h, min_downscale, max_upscale;
1043
1044         memset(scaling_info, 0, sizeof(*scaling_info));
1045
1046         /* Source is fixed 16.16 but we ignore mantissa for now... */
1047         scaling_info->src_rect.x = state->src_x >> 16;
1048         scaling_info->src_rect.y = state->src_y >> 16;
1049
1050         /*
1051          * For reasons we don't (yet) fully understand a non-zero
1052          * src_y coordinate into an NV12 buffer can cause a
1053          * system hang on DCN1x.
1054          * To avoid hangs (and maybe be overly cautious)
1055          * let's reject both non-zero src_x and src_y.
1056          *
1057          * We currently know of only one use-case to reproduce a
1058          * scenario with non-zero src_x and src_y for NV12, which
1059          * is to gesture the YouTube Android app into full screen
1060          * on ChromeOS.
1061          */
1062         if (((adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 0)) ||
1063             (adev->ip_versions[DCE_HWIP][0] == IP_VERSION(1, 0, 1))) &&
1064             (state->fb && state->fb->format->format == DRM_FORMAT_NV12 &&
1065             (scaling_info->src_rect.x != 0 || scaling_info->src_rect.y != 0)))
1066                 return -EINVAL;
1067
1068         scaling_info->src_rect.width = state->src_w >> 16;
1069         if (scaling_info->src_rect.width == 0)
1070                 return -EINVAL;
1071
1072         scaling_info->src_rect.height = state->src_h >> 16;
1073         if (scaling_info->src_rect.height == 0)
1074                 return -EINVAL;
1075
1076         scaling_info->dst_rect.x = state->crtc_x;
1077         scaling_info->dst_rect.y = state->crtc_y;
1078
1079         if (state->crtc_w == 0)
1080                 return -EINVAL;
1081
1082         scaling_info->dst_rect.width = state->crtc_w;
1083
1084         if (state->crtc_h == 0)
1085                 return -EINVAL;
1086
1087         scaling_info->dst_rect.height = state->crtc_h;
1088
1089         /* DRM doesn't specify clipping on destination output. */
1090         scaling_info->clip_rect = scaling_info->dst_rect;
1091
1092         /* Validate scaling per-format with DC plane caps */
1093         if (state->plane && state->plane->dev && state->fb) {
1094                 get_min_max_dc_plane_scaling(state->plane->dev, state->fb,
1095                                              &min_downscale, &max_upscale);
1096         } else {
1097                 min_downscale = 250;
1098                 max_upscale = 16000;
1099         }
1100
1101         scale_w = scaling_info->dst_rect.width * 1000 /
1102                   scaling_info->src_rect.width;
1103
1104         if (scale_w < min_downscale || scale_w > max_upscale)
1105                 return -EINVAL;
1106
1107         scale_h = scaling_info->dst_rect.height * 1000 /
1108                   scaling_info->src_rect.height;
1109
1110         if (scale_h < min_downscale || scale_h > max_upscale)
1111                 return -EINVAL;
1112
1113         /*
1114          * The "scaling_quality" can be ignored for now, quality = 0 has DC
1115          * assume reasonable defaults based on the format.
1116          */
1117
1118         return 0;
1119 }
1120
1121 static int dm_plane_atomic_check(struct drm_plane *plane,
1122                                  struct drm_atomic_state *state)
1123 {
1124         struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
1125                                                                                  plane);
1126         struct amdgpu_device *adev = drm_to_adev(plane->dev);
1127         struct dc *dc = adev->dm.dc;
1128         struct dm_plane_state *dm_plane_state;
1129         struct dc_scaling_info scaling_info;
1130         struct drm_crtc_state *new_crtc_state;
1131         int ret;
1132
1133         trace_amdgpu_dm_plane_atomic_check(new_plane_state);
1134
1135         dm_plane_state = to_dm_plane_state(new_plane_state);
1136
1137         if (!dm_plane_state->dc_state)
1138                 return 0;
1139
1140         new_crtc_state =
1141                 drm_atomic_get_new_crtc_state(state,
1142                                               new_plane_state->crtc);
1143         if (!new_crtc_state)
1144                 return -EINVAL;
1145
1146         ret = amdgpu_dm_plane_helper_check_state(new_plane_state, new_crtc_state);
1147         if (ret)
1148                 return ret;
1149
1150         ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info);
1151         if (ret)
1152                 return ret;
1153
1154         if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
1155                 return 0;
1156
1157         return -EINVAL;
1158 }
1159
1160 static int dm_plane_atomic_async_check(struct drm_plane *plane,
1161                                        struct drm_atomic_state *state)
1162 {
1163         /* Only support async updates on cursor planes. */
1164         if (plane->type != DRM_PLANE_TYPE_CURSOR)
1165                 return -EINVAL;
1166
1167         return 0;
1168 }
1169
1170 static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc,
1171                                struct dc_cursor_position *position)
1172 {
1173         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1174         int x, y;
1175         int xorigin = 0, yorigin = 0;
1176
1177         if (!crtc || !plane->state->fb)
1178                 return 0;
1179
1180         if ((plane->state->crtc_w > amdgpu_crtc->max_cursor_width) ||
1181             (plane->state->crtc_h > amdgpu_crtc->max_cursor_height)) {
1182                 DRM_ERROR("%s: bad cursor width or height %d x %d\n",
1183                           __func__,
1184                           plane->state->crtc_w,
1185                           plane->state->crtc_h);
1186                 return -EINVAL;
1187         }
1188
1189         x = plane->state->crtc_x;
1190         y = plane->state->crtc_y;
1191
1192         if (x <= -amdgpu_crtc->max_cursor_width ||
1193             y <= -amdgpu_crtc->max_cursor_height)
1194                 return 0;
1195
1196         if (x < 0) {
1197                 xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1);
1198                 x = 0;
1199         }
1200         if (y < 0) {
1201                 yorigin = min(-y, amdgpu_crtc->max_cursor_height - 1);
1202                 y = 0;
1203         }
1204         position->enable = true;
1205         position->translate_by_source = true;
1206         position->x = x;
1207         position->y = y;
1208         position->x_hotspot = xorigin;
1209         position->y_hotspot = yorigin;
1210
1211         return 0;
1212 }
1213
1214 void amdgpu_dm_plane_handle_cursor_update(struct drm_plane *plane,
1215                                  struct drm_plane_state *old_plane_state)
1216 {
1217         struct amdgpu_device *adev = drm_to_adev(plane->dev);
1218         struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(plane->state->fb);
1219         struct drm_crtc *crtc = afb ? plane->state->crtc : old_plane_state->crtc;
1220         struct dm_crtc_state *crtc_state = crtc ? to_dm_crtc_state(crtc->state) : NULL;
1221         struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
1222         uint64_t address = afb ? afb->address : 0;
1223         struct dc_cursor_position position = {0};
1224         struct dc_cursor_attributes attributes;
1225         int ret;
1226
1227         if (!plane->state->fb && !old_plane_state->fb)
1228                 return;
1229
1230         DC_LOG_CURSOR("%s: crtc_id=%d with size %d to %d\n",
1231                       __func__,
1232                       amdgpu_crtc->crtc_id,
1233                       plane->state->crtc_w,
1234                       plane->state->crtc_h);
1235
1236         ret = get_cursor_position(plane, crtc, &position);
1237         if (ret)
1238                 return;
1239
1240         if (!position.enable) {
1241                 /* turn off cursor */
1242                 if (crtc_state && crtc_state->stream) {
1243                         mutex_lock(&adev->dm.dc_lock);
1244                         dc_stream_set_cursor_position(crtc_state->stream,
1245                                                       &position);
1246                         mutex_unlock(&adev->dm.dc_lock);
1247                 }
1248                 return;
1249         }
1250
1251         amdgpu_crtc->cursor_width = plane->state->crtc_w;
1252         amdgpu_crtc->cursor_height = plane->state->crtc_h;
1253
1254         memset(&attributes, 0, sizeof(attributes));
1255         attributes.address.high_part = upper_32_bits(address);
1256         attributes.address.low_part  = lower_32_bits(address);
1257         attributes.width             = plane->state->crtc_w;
1258         attributes.height            = plane->state->crtc_h;
1259         attributes.color_format      = CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA;
1260         attributes.rotation_angle    = 0;
1261         attributes.attribute_flags.value = 0;
1262
1263         attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0];
1264
1265         if (crtc_state->stream) {
1266                 mutex_lock(&adev->dm.dc_lock);
1267                 if (!dc_stream_set_cursor_attributes(crtc_state->stream,
1268                                                          &attributes))
1269                         DRM_ERROR("DC failed to set cursor attributes\n");
1270
1271                 if (!dc_stream_set_cursor_position(crtc_state->stream,
1272                                                    &position))
1273                         DRM_ERROR("DC failed to set cursor position\n");
1274                 mutex_unlock(&adev->dm.dc_lock);
1275         }
1276 }
1277
1278 static void dm_plane_atomic_async_update(struct drm_plane *plane,
1279                                          struct drm_atomic_state *state)
1280 {
1281         struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
1282                                                                            plane);
1283         struct drm_plane_state *old_state =
1284                 drm_atomic_get_old_plane_state(state, plane);
1285
1286         trace_amdgpu_dm_atomic_update_cursor(new_state);
1287
1288         swap(plane->state->fb, new_state->fb);
1289
1290         plane->state->src_x = new_state->src_x;
1291         plane->state->src_y = new_state->src_y;
1292         plane->state->src_w = new_state->src_w;
1293         plane->state->src_h = new_state->src_h;
1294         plane->state->crtc_x = new_state->crtc_x;
1295         plane->state->crtc_y = new_state->crtc_y;
1296         plane->state->crtc_w = new_state->crtc_w;
1297         plane->state->crtc_h = new_state->crtc_h;
1298
1299         amdgpu_dm_plane_handle_cursor_update(plane, old_state);
1300 }
1301
1302 static const struct drm_plane_helper_funcs dm_plane_helper_funcs = {
1303         .prepare_fb = dm_plane_helper_prepare_fb,
1304         .cleanup_fb = dm_plane_helper_cleanup_fb,
1305         .atomic_check = dm_plane_atomic_check,
1306         .atomic_async_check = dm_plane_atomic_async_check,
1307         .atomic_async_update = dm_plane_atomic_async_update
1308 };
1309
1310 static void dm_drm_plane_reset(struct drm_plane *plane)
1311 {
1312         struct dm_plane_state *amdgpu_state = NULL;
1313
1314         if (plane->state)
1315                 plane->funcs->atomic_destroy_state(plane, plane->state);
1316
1317         amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL);
1318         WARN_ON(amdgpu_state == NULL);
1319
1320         if (amdgpu_state)
1321                 __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base);
1322 }
1323
1324 static struct drm_plane_state *
1325 dm_drm_plane_duplicate_state(struct drm_plane *plane)
1326 {
1327         struct dm_plane_state *dm_plane_state, *old_dm_plane_state;
1328
1329         old_dm_plane_state = to_dm_plane_state(plane->state);
1330         dm_plane_state = kzalloc(sizeof(*dm_plane_state), GFP_KERNEL);
1331         if (!dm_plane_state)
1332                 return NULL;
1333
1334         __drm_atomic_helper_plane_duplicate_state(plane, &dm_plane_state->base);
1335
1336         if (old_dm_plane_state->dc_state) {
1337                 dm_plane_state->dc_state = old_dm_plane_state->dc_state;
1338                 dc_plane_state_retain(dm_plane_state->dc_state);
1339         }
1340
1341         return &dm_plane_state->base;
1342 }
1343
1344 static bool dm_plane_format_mod_supported(struct drm_plane *plane,
1345                                           uint32_t format,
1346                                           uint64_t modifier)
1347 {
1348         struct amdgpu_device *adev = drm_to_adev(plane->dev);
1349         const struct drm_format_info *info = drm_format_info(format);
1350         int i;
1351
1352         enum dm_micro_swizzle microtile = modifier_gfx9_swizzle_mode(modifier) & 3;
1353
1354         if (!info)
1355                 return false;
1356
1357         /*
1358          * We always have to allow these modifiers:
1359          * 1. Core DRM checks for LINEAR support if userspace does not provide modifiers.
1360          * 2. Not passing any modifiers is the same as explicitly passing INVALID.
1361          */
1362         if (modifier == DRM_FORMAT_MOD_LINEAR ||
1363             modifier == DRM_FORMAT_MOD_INVALID) {
1364                 return true;
1365         }
1366
1367         /* Check that the modifier is on the list of the plane's supported modifiers. */
1368         for (i = 0; i < plane->modifier_count; i++) {
1369                 if (modifier == plane->modifiers[i])
1370                         break;
1371         }
1372         if (i == plane->modifier_count)
1373                 return false;
1374
1375         /*
1376          * For D swizzle the canonical modifier depends on the bpp, so check
1377          * it here.
1378          */
1379         if (AMD_FMT_MOD_GET(TILE_VERSION, modifier) == AMD_FMT_MOD_TILE_VER_GFX9 &&
1380             adev->family >= AMDGPU_FAMILY_NV) {
1381                 if (microtile == MICRO_SWIZZLE_D && info->cpp[0] == 4)
1382                         return false;
1383         }
1384
1385         if (adev->family >= AMDGPU_FAMILY_RV && microtile == MICRO_SWIZZLE_D &&
1386             info->cpp[0] < 8)
1387                 return false;
1388
1389         if (modifier_has_dcc(modifier)) {
1390                 /* Per radeonsi comments 16/64 bpp are more complicated. */
1391                 if (info->cpp[0] != 4)
1392                         return false;
1393                 /* We support multi-planar formats, but not when combined with
1394                  * additional DCC metadata planes.
1395                  */
1396                 if (info->num_planes > 1)
1397                         return false;
1398         }
1399
1400         return true;
1401 }
1402
1403 static void dm_drm_plane_destroy_state(struct drm_plane *plane,
1404                                 struct drm_plane_state *state)
1405 {
1406         struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
1407
1408         if (dm_plane_state->dc_state)
1409                 dc_plane_state_release(dm_plane_state->dc_state);
1410
1411         drm_atomic_helper_plane_destroy_state(plane, state);
1412 }
1413
1414 static const struct drm_plane_funcs dm_plane_funcs = {
1415         .update_plane   = drm_atomic_helper_update_plane,
1416         .disable_plane  = drm_atomic_helper_disable_plane,
1417         .destroy        = drm_plane_helper_destroy,
1418         .reset = dm_drm_plane_reset,
1419         .atomic_duplicate_state = dm_drm_plane_duplicate_state,
1420         .atomic_destroy_state = dm_drm_plane_destroy_state,
1421         .format_mod_supported = dm_plane_format_mod_supported,
1422 };
1423
1424 int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
1425                                 struct drm_plane *plane,
1426                                 unsigned long possible_crtcs,
1427                                 const struct dc_plane_cap *plane_cap)
1428 {
1429         uint32_t formats[32];
1430         int num_formats;
1431         int res = -EPERM;
1432         unsigned int supported_rotations;
1433         uint64_t *modifiers = NULL;
1434
1435         num_formats = get_plane_formats(plane, plane_cap, formats,
1436                                         ARRAY_SIZE(formats));
1437
1438         res = get_plane_modifiers(dm->adev, plane->type, &modifiers);
1439         if (res)
1440                 return res;
1441
1442         if (modifiers == NULL)
1443                 adev_to_drm(dm->adev)->mode_config.fb_modifiers_not_supported = true;
1444
1445         res = drm_universal_plane_init(adev_to_drm(dm->adev), plane, possible_crtcs,
1446                                        &dm_plane_funcs, formats, num_formats,
1447                                        modifiers, plane->type, NULL);
1448         kfree(modifiers);
1449         if (res)
1450                 return res;
1451
1452         if (plane->type == DRM_PLANE_TYPE_OVERLAY &&
1453             plane_cap && plane_cap->per_pixel_alpha) {
1454                 unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
1455                                           BIT(DRM_MODE_BLEND_PREMULTI) |
1456                                           BIT(DRM_MODE_BLEND_COVERAGE);
1457
1458                 drm_plane_create_alpha_property(plane);
1459                 drm_plane_create_blend_mode_property(plane, blend_caps);
1460         }
1461
1462         if (plane->type == DRM_PLANE_TYPE_PRIMARY &&
1463             plane_cap &&
1464             (plane_cap->pixel_format_support.nv12 ||
1465              plane_cap->pixel_format_support.p010)) {
1466                 /* This only affects YUV formats. */
1467                 drm_plane_create_color_properties(
1468                         plane,
1469                         BIT(DRM_COLOR_YCBCR_BT601) |
1470                         BIT(DRM_COLOR_YCBCR_BT709) |
1471                         BIT(DRM_COLOR_YCBCR_BT2020),
1472                         BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1473                         BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1474                         DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE);
1475         }
1476
1477         supported_rotations =
1478                 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
1479                 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
1480
1481         if (dm->adev->asic_type >= CHIP_BONAIRE &&
1482             plane->type != DRM_PLANE_TYPE_CURSOR)
1483                 drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0,
1484                                                    supported_rotations);
1485
1486         if (dm->adev->ip_versions[DCE_HWIP][0] > IP_VERSION(3, 0, 1) &&
1487             plane->type != DRM_PLANE_TYPE_CURSOR)
1488                 drm_plane_enable_fb_damage_clips(plane);
1489
1490         drm_plane_helper_add(plane, &dm_plane_helper_funcs);
1491
1492         /* Create (reset) the plane state */
1493         if (plane->funcs->reset)
1494                 plane->funcs->reset(plane);
1495
1496         return 0;
1497 }
1498
1499 bool is_video_format(uint32_t format)
1500 {
1501         int i;
1502
1503         for (i = 0; i < ARRAY_SIZE(video_formats); i++)
1504                 if (format == video_formats[i])
1505                         return true;
1506
1507         return false;
1508 }
1509
This page took 0.125377 seconds and 4 git commands to generate.