History

Merge branch 'drm-next-5.2' of git://people.freedesktop.org/~agd5f/linux into drm-next

- Add the amdgpu specific bits for timeline support - Add internal interfaces for xgmi pstate support - DC Z ordering fixes for planes - Add support for NV12 planes in DC - Add colorspace properties for planes in DC - eDP optimizations if the GOP driver already initialized eDP - DC bandwidth validation tracing support

Dave Airlie committed 7 years ago

Commit 42f1a012 parents 6e865c7 f55be0b27 files · +944 −361Browse files

Unified · Split

27 files
  1. drivers/gpu/drm/amd/amdgpu/amdgpu.h +8 −2
  2. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +128 −24
  3. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +2 −1
  4. drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +17 −7
  5. drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +12 −1
  6. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +451 −294
  7. drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c +22 −2
  8. drivers/gpu/drm/amd/display/dc/core/dc.c +1 −1
  9. drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +31 −2
  10. drivers/gpu/drm/amd/display/dc/core/dc_resource.c +4 −2
  11. drivers/gpu/drm/amd/display/dc/core/dc_stream.c +2 −1
  12. drivers/gpu/drm/amd/display/dc/dc.h +81 −4
  13. drivers/gpu/drm/amd/display/dc/dc_link.h +1 −1
  14. drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +18 −0
  15. drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c +20 −2
  16. drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c +38 −3
  17. drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c +20 −2
  18. drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h +2 −1
  19. drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c +18 −1
  20. drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c +20 −2
  21. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h +6 −3
  22. drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c +18 −2
  23. drivers/gpu/drm/amd/display/dc/inc/core_types.h +2 −1
  24. drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h +2 −1
  25. drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h +4 −0
  26. drivers/gpu/drm/amd/powerplay/smu_v11_0.c +8 −1
  27. include/uapi/drm/amdgpu_drm.h +8 −0
drivers/gpu/drm/amd/amdgpu/amdgpu.h+8−2
@@ -436,6 +436,12 @@ struct amdgpu_cs_chunk { · 435 unmodified lines
436436 void *kdata;
437437 };
438438
439+struct amdgpu_cs_post_dep {
440+ struct drm_syncobj *syncobj;
441+ struct dma_fence_chain *chain;
442+ u64 point;
443+};
444+
439445 struct amdgpu_cs_parser {
440446 struct amdgpu_device *adev;
441447 struct drm_file *filp;
@@ -465,8 +471,8 @@ struct amdgpu_cs_parser { · 23 unmodified lines
465471 /* user fence */
466472 struct amdgpu_bo_list_entry uf_entry;
467473
468− unsigned num_post_dep_syncobjs;
469− struct drm_syncobj **post_dep_syncobjs;
474+ unsigned num_post_deps;
475+ struct amdgpu_cs_post_dep *post_deps;
470476 };
471477
472478 static inline u32 amdgpu_get_ib_value(struct amdgpu_cs_parser *p,
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+128−24
@@ -215,6 +215,8 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs · 214 unmodified lines
215215 case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
216216 case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
217217 case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
218+ case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
219+ case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
218220 break;
219221
220222 default:
@@ -804,9 +806,11 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, · 583 unmodified lines
804806 ttm_eu_backoff_reservation(&parser->ticket,
805807 &parser->validated);
806808
807− for (i = 0; i < parser->num_post_dep_syncobjs; i++)
808− drm_syncobj_put(parser->post_dep_syncobjs[i]);
809− kfree(parser->post_dep_syncobjs);
809+ for (i = 0; i < parser->num_post_deps; i++) {
810+ drm_syncobj_put(parser->post_deps[i].syncobj);
811+ kfree(parser->post_deps[i].chain);
812+ }
813+ kfree(parser->post_deps);
810814
811815 dma_fence_put(parser->fence);
812816
@@ -1117,13 +1121,18 @@ static int amdgpu_cs_process_fence_dep(struct amdgpu_cs_parser *p, · 304 unmodified lines
11171121 }
11181122
11191123 static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p,
1120− uint32_t handle)
1124+ uint32_t handle, u64 point,
1125+ u64 flags)
11211126 {
1122− int r;
11231127 struct dma_fence *fence;
1124− r = drm_syncobj_find_fence(p->filp, handle, 0, 0, &fence);
1125− if (r)
1128+ int r;
1129+
1130+ r = drm_syncobj_find_fence(p->filp, handle, point, flags, &fence);
1131+ if (r) {
1132+ DRM_ERROR("syncobj %u failed to find fence @ %llu (%d)!\n",
1133+ handle, point, r);
11261134 return r;
1135+ }
11271136
11281137 r = amdgpu_sync_fence(p->adev, &p->job->sync, fence, true);
11291138 dma_fence_put(fence);
@@ -1134,46 +1143,118 @@ static int amdgpu_syncobj_lookup_and_add_to_sync(struct amdgpu_cs_parser *p, · 4 unmodified lines
11341143 static int amdgpu_cs_process_syncobj_in_dep(struct amdgpu_cs_parser *p,
11351144 struct amdgpu_cs_chunk *chunk)
11361145 {
1146+ struct drm_amdgpu_cs_chunk_sem *deps;
11371147 unsigned num_deps;
11381148 int i, r;
1139− struct drm_amdgpu_cs_chunk_sem *deps;
11401149
11411150 deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
11421151 num_deps = chunk->length_dw * 4 /
11431152 sizeof(struct drm_amdgpu_cs_chunk_sem);
1153+ for (i = 0; i < num_deps; ++i) {
1154+ r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle,
1155+ 0, 0);
1156+ if (r)
1157+ return r;
1158+ }
1159+
1160+ return 0;
1161+}
1162+
11441163
1164+static int amdgpu_cs_process_syncobj_timeline_in_dep(struct amdgpu_cs_parser *p,
1165+ struct amdgpu_cs_chunk *chunk)
1166+{
1167+ struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
1168+ unsigned num_deps;
1169+ int i, r;
1170+
1171+ syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
1172+ num_deps = chunk->length_dw * 4 /
1173+ sizeof(struct drm_amdgpu_cs_chunk_syncobj);
11451174 for (i = 0; i < num_deps; ++i) {
1146− r = amdgpu_syncobj_lookup_and_add_to_sync(p, deps[i].handle);
1175+ r = amdgpu_syncobj_lookup_and_add_to_sync(p,
1176+ syncobj_deps[i].handle,
1177+ syncobj_deps[i].point,
1178+ syncobj_deps[i].flags);
11471179 if (r)
11481180 return r;
11491181 }
1182+
11501183 return 0;
11511184 }
11521185
11531186 static int amdgpu_cs_process_syncobj_out_dep(struct amdgpu_cs_parser *p,
11541187 struct amdgpu_cs_chunk *chunk)
11551188 {
1189+ struct drm_amdgpu_cs_chunk_sem *deps;
11561190 unsigned num_deps;
11571191 int i;
1158− struct drm_amdgpu_cs_chunk_sem *deps;
1192+
11591193 deps = (struct drm_amdgpu_cs_chunk_sem *)chunk->kdata;
11601194 num_deps = chunk->length_dw * 4 /
11611195 sizeof(struct drm_amdgpu_cs_chunk_sem);
11621196
1163− p->post_dep_syncobjs = kmalloc_array(num_deps,
1164− sizeof(struct drm_syncobj *),
1165− GFP_KERNEL);
1166− p->num_post_dep_syncobjs = 0;
1197+ p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
1198+ GFP_KERNEL);
1199+ p->num_post_deps = 0;
11671200
1168− if (!p->post_dep_syncobjs)
1201+ if (!p->post_deps)
11691202 return -ENOMEM;
11701203
1204+
11711205 for (i = 0; i < num_deps; ++i) {
1172− p->post_dep_syncobjs[i] = drm_syncobj_find(p->filp, deps[i].handle);
1173− if (!p->post_dep_syncobjs[i])
1206+ p->post_deps[i].syncobj =
1207+ drm_syncobj_find(p->filp, deps[i].handle);
1208+ if (!p->post_deps[i].syncobj)
11741209 return -EINVAL;
1175− p->num_post_dep_syncobjs++;
1210+ p->post_deps[i].chain = NULL;
1211+ p->post_deps[i].point = 0;
1212+ p->num_post_deps++;
11761213 }
1214+
1215+ return 0;
1216+}
1217+
1218+
1219+static int amdgpu_cs_process_syncobj_timeline_out_dep(struct amdgpu_cs_parser *p,
1220+ struct amdgpu_cs_chunk
1221+ *chunk)
1222+{
1223+ struct drm_amdgpu_cs_chunk_syncobj *syncobj_deps;
1224+ unsigned num_deps;
1225+ int i;
1226+
1227+ syncobj_deps = (struct drm_amdgpu_cs_chunk_syncobj *)chunk->kdata;
1228+ num_deps = chunk->length_dw * 4 /
1229+ sizeof(struct drm_amdgpu_cs_chunk_syncobj);
1230+
1231+ p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps),
1232+ GFP_KERNEL);
1233+ p->num_post_deps = 0;
1234+
1235+ if (!p->post_deps)
1236+ return -ENOMEM;
1237+
1238+ for (i = 0; i < num_deps; ++i) {
1239+ struct amdgpu_cs_post_dep *dep = &p->post_deps[i];
1240+
1241+ dep->chain = NULL;
1242+ if (syncobj_deps[i].point) {
1243+ dep->chain = kmalloc(sizeof(*dep->chain), GFP_KERNEL);
1244+ if (!dep->chain)
1245+ return -ENOMEM;
1246+ }
1247+
1248+ dep->syncobj = drm_syncobj_find(p->filp,
1249+ syncobj_deps[i].handle);
1250+ if (!dep->syncobj) {
1251+ kfree(dep->chain);
1252+ return -EINVAL;
1253+ }
1254+ dep->point = syncobj_deps[i].point;
1255+ p->num_post_deps++;
1256+ }
1257+
11771258 return 0;
11781259 }
11791260
@@ -1187,19 +1268,33 @@ static int amdgpu_cs_dependencies(struct amdgpu_device *adev, · 7 unmodified lines
11871268
11881269 chunk = &p->chunks[i];
11891270
1190− if (chunk->chunk_id == AMDGPU_CHUNK_ID_DEPENDENCIES ||
1191− chunk->chunk_id == AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES) {
1271+ switch (chunk->chunk_id) {
1272+ case AMDGPU_CHUNK_ID_DEPENDENCIES:
1273+ case AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES:
11921274 r = amdgpu_cs_process_fence_dep(p, chunk);
11931275 if (r)
11941276 return r;
1195− } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_IN) {
1277+ break;
1278+ case AMDGPU_CHUNK_ID_SYNCOBJ_IN:
11961279 r = amdgpu_cs_process_syncobj_in_dep(p, chunk);
11971280 if (r)
11981281 return r;
1199− } else if (chunk->chunk_id == AMDGPU_CHUNK_ID_SYNCOBJ_OUT) {
1282+ break;
1283+ case AMDGPU_CHUNK_ID_SYNCOBJ_OUT:
12001284 r = amdgpu_cs_process_syncobj_out_dep(p, chunk);
12011285 if (r)
12021286 return r;
1287+ break;
1288+ case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT:
1289+ r = amdgpu_cs_process_syncobj_timeline_in_dep(p, chunk);
1290+ if (r)
1291+ return r;
1292+ break;
1293+ case AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL:
1294+ r = amdgpu_cs_process_syncobj_timeline_out_dep(p, chunk);
1295+ if (r)
1296+ return r;
1297+ break;
12031298 }
12041299 }
12051300
@@ -1210,8 +1305,17 @@ static void amdgpu_cs_post_dependencies(struct amdgpu_cs_parser *p) · 4 unmodified lines
12101305 {
12111306 int i;
12121307
1213− for (i = 0; i < p->num_post_dep_syncobjs; ++i)
1214− drm_syncobj_replace_fence(p->post_dep_syncobjs[i], p->fence);
1308+ for (i = 0; i < p->num_post_deps; ++i) {
1309+ if (p->post_deps[i].chain && p->post_deps[i].point) {
1310+ drm_syncobj_add_point(p->post_deps[i].syncobj,
1311+ p->post_deps[i].chain,
1312+ p->fence, p->post_deps[i].point);
1313+ p->post_deps[i].chain = NULL;
1314+ } else {
1315+ drm_syncobj_replace_fence(p->post_deps[i].syncobj,
1316+ p->fence);
1317+ }
1318+ }
12151319 }
12161320
12171321 static int amdgpu_cs_submit(struct amdgpu_cs_parser *p,
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+2−1
@@ -75,9 +75,10 @@ · 74 unmodified lines
7575 * - 3.29.0 - Add AMDGPU_IB_FLAG_RESET_GDS_MAX_WAVE_ID
7676 * - 3.30.0 - Add AMDGPU_SCHED_OP_CONTEXT_PRIORITY_OVERRIDE.
7777 * - 3.31.0 - Add support for per-flip tiling attribute changes with DC
78+ * - 3.32.0 - Add syncobj timeline support to AMDGPU_CS.
7879 */
7980 #define KMS_DRIVER_MAJOR 3
80−#define KMS_DRIVER_MINOR 31
81+#define KMS_DRIVER_MINOR 32
8182 #define KMS_DRIVER_PATCHLEVEL 0
8283
8384 int amdgpu_vram_limit = 0;
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c+17−7
@@ -136,8 +136,9 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, · 135 unmodified lines
136136 {
137137 struct amdgpu_device *adev = ring->adev;
138138 struct amdgpu_fence *fence;
139− struct dma_fence *old, **ptr;
139+ struct dma_fence __rcu **ptr;
140140 uint32_t seq;
141+ int r;
141142
142143 fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_KERNEL);
143144 if (fence == NULL)
@@ -153,15 +154,24 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct dma_fence **f, · 9 unmodified lines
153154 seq, flags | AMDGPU_FENCE_FLAG_INT);
154155
155156 ptr = &ring->fence_drv.fences[seq & ring->fence_drv.num_fences_mask];
157+ if (unlikely(rcu_dereference_protected(*ptr, 1))) {
158+ struct dma_fence *old;
159+
160+ rcu_read_lock();
161+ old = dma_fence_get_rcu_safe(ptr);
162+ rcu_read_unlock();
163+
164+ if (old) {
165+ r = dma_fence_wait(old, false);
166+ dma_fence_put(old);
167+ if (r)
168+ return r;
169+ }
170+ }
171+
156172 /* This function can't be called concurrently anyway, otherwise
157173 * emitting the fence would mess up the hardware ring buffer.
158174 */
159− old = rcu_dereference_protected(*ptr, 1);
160− if (old && !dma_fence_is_signaled(old)) {
161− DRM_INFO("rcu slot is busy\n");
162− dma_fence_wait(old, false);
163− }
164−
165175 rcu_assign_pointer(*ptr, dma_fence_get(&fence->base));
166176
167177 *f = &fence->base;
drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c+12−1
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 #include <linux/list.h>
2525 #include "amdgpu.h"
2626 #include "amdgpu_xgmi.h"
27+#include "amdgpu_smu.h"
2728
2829
2930 static DEFINE_MUTEX(xgmi_mutex);
@@ -216,7 +217,17 @@ int amdgpu_xgmi_set_pstate(struct amdgpu_device *adev, int pstate) · 186 unmodified lines
216217
217218 if (hive->pstate == pstate)
218219 return 0;
219− /* Todo : sent the message to SMU for pstate change */
220+
221+ dev_dbg(adev->dev, "Set xgmi pstate %d.\n", pstate);
222+
223+ if (is_support_sw_smu(adev))
224+ ret = smu_set_xgmi_pstate(&adev->smu, pstate);
225+ if (ret)
226+ dev_err(adev->dev,
227+ "XGMI: Set pstate failure on device %llx, hive %llx, ret %d",
228+ adev->gmc.xgmi.node_id,
229+ adev->gmc.xgmi.hive_id, ret);
230+
220231 return ret;
221232 }
222233
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+451−294
@@ -2085,7 +2085,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) · 2084 unmodified lines
20852085 if (!plane->blends_with_above || !plane->blends_with_below)
20862086 continue;
20872087
2088− if (!plane->supports_argb8888)
2088+ if (!plane->pixel_format_support.argb8888)
20892089 continue;
20902090
20912091 if (initialize_plane(dm, NULL, primary_planes + i,
@@ -2385,56 +2385,63 @@ static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { · 293 unmodified lines
23852385 .destroy = amdgpu_dm_encoder_destroy,
23862386 };
23872387
2388−static bool fill_rects_from_plane_state(const struct drm_plane_state *state,
2389− struct dc_plane_state *plane_state)
2388+
2389+static int fill_dc_scaling_info(const struct drm_plane_state *state,
2390+ struct dc_scaling_info *scaling_info)
23902391 {
2391− plane_state->src_rect.x = state->src_x >> 16;
2392− plane_state->src_rect.y = state->src_y >> 16;
2393− /* we ignore the mantissa for now and do not deal with floating pixels :( */
2394− plane_state->src_rect.width = state->src_w >> 16;
2392+ int scale_w, scale_h;
23952393
2396− if (plane_state->src_rect.width == 0)
2397− return false;
2394+ memset(scaling_info, 0, sizeof(*scaling_info));
23982395
2399− plane_state->src_rect.height = state->src_h >> 16;
2400− if (plane_state->src_rect.height == 0)
2401− return false;
2396+ /* Source is fixed 16.16 but we ignore mantissa for now... */
2397+ scaling_info->src_rect.x = state->src_x >> 16;
2398+ scaling_info->src_rect.y = state->src_y >> 16;
24022399
2403− plane_state->dst_rect.x = state->crtc_x;
2404− plane_state->dst_rect.y = state->crtc_y;
2400+ scaling_info->src_rect.width = state->src_w >> 16;
2401+ if (scaling_info->src_rect.width == 0)
2402+ return -EINVAL;
2403+
2404+ scaling_info->src_rect.height = state->src_h >> 16;
2405+ if (scaling_info->src_rect.height == 0)
2406+ return -EINVAL;
2407+
2408+ scaling_info->dst_rect.x = state->crtc_x;
2409+ scaling_info->dst_rect.y = state->crtc_y;
24052410
24062411 if (state->crtc_w == 0)
2407− return false;
2412+ return -EINVAL;
24082413
2409− plane_state->dst_rect.width = state->crtc_w;
2414+ scaling_info->dst_rect.width = state->crtc_w;
24102415
24112416 if (state->crtc_h == 0)
2412− return false;
2417+ return -EINVAL;
24132418
2414− plane_state->dst_rect.height = state->crtc_h;
2419+ scaling_info->dst_rect.height = state->crtc_h;
24152420
2416− plane_state->clip_rect = plane_state->dst_rect;
2421+ /* DRM doesn't specify clipping on destination output. */
2422+ scaling_info->clip_rect = scaling_info->dst_rect;
24172423
2418− switch (state->rotation & DRM_MODE_ROTATE_MASK) {
2419− case DRM_MODE_ROTATE_0:
2420− plane_state->rotation = ROTATION_ANGLE_0;
2421− break;
2422− case DRM_MODE_ROTATE_90:
2423− plane_state->rotation = ROTATION_ANGLE_90;
2424− break;
2425− case DRM_MODE_ROTATE_180:
2426− plane_state->rotation = ROTATION_ANGLE_180;
2427− break;
2428− case DRM_MODE_ROTATE_270:
2429− plane_state->rotation = ROTATION_ANGLE_270;
2430− break;
2431− default:
2432− plane_state->rotation = ROTATION_ANGLE_0;
2433− break;
2434− }
2424+ /* TODO: Validate scaling per-format with DC plane caps */
2425+ scale_w = scaling_info->dst_rect.width * 1000 /
2426+ scaling_info->src_rect.width;
24352427
2436− return true;
2428+ if (scale_w < 250 || scale_w > 16000)
2429+ return -EINVAL;
2430+
2431+ scale_h = scaling_info->dst_rect.height * 1000 /
2432+ scaling_info->src_rect.height;
2433+
2434+ if (scale_h < 250 || scale_h > 16000)
2435+ return -EINVAL;
2436+
2437+ /*
2438+ * The "scaling_quality" can be ignored for now, quality = 0 has DC
2439+ * assume reasonable defaults based on the format.
2440+ */
2441+
2442+ return 0;
24372443 }
2444+
24382445 static int get_fb_info(const struct amdgpu_framebuffer *amdgpu_fb,
24392446 uint64_t *tiling_flags)
24402447 {
@@ -2463,12 +2470,16 @@ static inline uint64_t get_dcc_address(uint64_t address, uint64_t tiling_flags) · 22 unmodified lines
24632470 return offset ? (address + offset * 256) : 0;
24642471 }
24652472
2466−static int fill_plane_dcc_attributes(struct amdgpu_device *adev,
2467− const struct amdgpu_framebuffer *afb,
2468− const struct dc_plane_state *plane_state,
2469− struct dc_plane_dcc_param *dcc,
2470− struct dc_plane_address *address,
2471− uint64_t info)
2473+static int
2474+fill_plane_dcc_attributes(struct amdgpu_device *adev,
2475+ const struct amdgpu_framebuffer *afb,
2476+ const enum surface_pixel_format format,
2477+ const enum dc_rotation_angle rotation,
2478+ const union plane_size *plane_size,
2479+ const union dc_tiling_info *tiling_info,
2480+ const uint64_t info,
2481+ struct dc_plane_dcc_param *dcc,
2482+ struct dc_plane_address *address)
24722483 {
24732484 struct dc *dc = adev->dm.dc;
24742485 struct dc_dcc_surface_param input;
@@ -2483,24 +2494,20 @@ static int fill_plane_dcc_attributes(struct amdgpu_device *adev, · 8 unmodified lines
24832494 if (!offset)
24842495 return 0;
24852496
2486− if (plane_state->address.type != PLN_ADDR_TYPE_GRAPHICS)
2497+ if (format >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
24872498 return 0;
24882499
24892500 if (!dc->cap_funcs.get_dcc_compression_cap)
24902501 return -EINVAL;
24912502
2492− input.format = plane_state->format;
2493− input.surface_size.width =
2494− plane_state->plane_size.grph.surface_size.width;
2495− input.surface_size.height =
2496− plane_state->plane_size.grph.surface_size.height;
2497− input.swizzle_mode = plane_state->tiling_info.gfx9.swizzle;
2503+ input.format = format;
2504+ input.surface_size.width = plane_size->grph.surface_size.width;
2505+ input.surface_size.height = plane_size->grph.surface_size.height;
2506+ input.swizzle_mode = tiling_info->gfx9.swizzle;
24982507
2499− if (plane_state->rotation == ROTATION_ANGLE_0 ||
2500− plane_state->rotation == ROTATION_ANGLE_180)
2508+ if (rotation == ROTATION_ANGLE_0 || rotation == ROTATION_ANGLE_180)
25012509 input.scan = SCAN_DIRECTION_HORIZONTAL;
2502− else if (plane_state->rotation == ROTATION_ANGLE_90 ||
2503− plane_state->rotation == ROTATION_ANGLE_270)
2510+ else if (rotation == ROTATION_ANGLE_90 || rotation == ROTATION_ANGLE_270)
25042511 input.scan = SCAN_DIRECTION_VERTICAL;
25052512
25062513 if (!dc->cap_funcs.get_dcc_compression_cap(dc, &input, &output))
@@ -2525,28 +2532,54 @@ static int fill_plane_dcc_attributes(struct amdgpu_device *adev, · 18 unmodified lines
25252532 }
25262533
25272534 static int
2528−fill_plane_tiling_attributes(struct amdgpu_device *adev,
2535+fill_plane_buffer_attributes(struct amdgpu_device *adev,
25292536 const struct amdgpu_framebuffer *afb,
2530− const struct dc_plane_state *plane_state,
2537+ const enum surface_pixel_format format,
2538+ const enum dc_rotation_angle rotation,
2539+ const uint64_t tiling_flags,
25312540 union dc_tiling_info *tiling_info,
2541+ union plane_size *plane_size,
25322542 struct dc_plane_dcc_param *dcc,
2533− struct dc_plane_address *address,
2534− uint64_t tiling_flags)
2543+ struct dc_plane_address *address)
25352544 {
2545+ const struct drm_framebuffer *fb = &afb->base;
25362546 int ret;
25372547
25382548 memset(tiling_info, 0, sizeof(*tiling_info));
2549+ memset(plane_size, 0, sizeof(*plane_size));
25392550 memset(dcc, 0, sizeof(*dcc));
25402551 memset(address, 0, sizeof(*address));
25412552
2542− if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
2553+ if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
2554+ plane_size->grph.surface_size.x = 0;
2555+ plane_size->grph.surface_size.y = 0;
2556+ plane_size->grph.surface_size.width = fb->width;
2557+ plane_size->grph.surface_size.height = fb->height;
2558+ plane_size->grph.surface_pitch =
2559+ fb->pitches[0] / fb->format->cpp[0];
2560+
25432561 address->type = PLN_ADDR_TYPE_GRAPHICS;
25442562 address->grph.addr.low_part = lower_32_bits(afb->address);
25452563 address->grph.addr.high_part = upper_32_bits(afb->address);
25462564 } else {
2547− const struct drm_framebuffer *fb = &afb->base;
25482565 uint64_t chroma_addr = afb->address + fb->offsets[1];
25492566
2567+ plane_size->video.luma_size.x = 0;
2568+ plane_size->video.luma_size.y = 0;
2569+ plane_size->video.luma_size.width = fb->width;
2570+ plane_size->video.luma_size.height = fb->height;
2571+ plane_size->video.luma_pitch =
2572+ fb->pitches[0] / fb->format->cpp[0];
2573+
2574+ plane_size->video.chroma_size.x = 0;
2575+ plane_size->video.chroma_size.y = 0;
2576+ /* TODO: set these based on surface format */
2577+ plane_size->video.chroma_size.width = fb->width / 2;
2578+ plane_size->video.chroma_size.height = fb->height / 2;
2579+
2580+ plane_size->video.chroma_pitch =
2581+ fb->pitches[1] / fb->format->cpp[1];
2582+
25502583 address->type = PLN_ADDR_TYPE_VIDEO_PROGRESSIVE;
25512584 address->video_progressive.luma_addr.low_part =
25522585 lower_32_bits(afb->address);
@@ -2607,8 +2640,9 @@ fill_plane_tiling_attributes(struct amdgpu_device *adev, · 54 unmodified lines
26072640 AMDGPU_TILING_GET(tiling_flags, SWIZZLE_MODE);
26082641 tiling_info->gfx9.shaderEnable = 1;
26092642
2610− ret = fill_plane_dcc_attributes(adev, afb, plane_state, dcc,
2611− address, tiling_flags);
2643+ ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
2644+ plane_size, tiling_info,
2645+ tiling_flags, dcc, address);
26122646 if (ret)
26132647 return ret;
26142648 }
@@ -2616,112 +2650,8 @@ fill_plane_tiling_attributes(struct amdgpu_device *adev, · 1 unmodified line
26162650 return 0;
26172651 }
26182652
2619−static int fill_plane_attributes_from_fb(struct amdgpu_device *adev,
2620− struct dc_plane_state *plane_state,
2621− const struct amdgpu_framebuffer *amdgpu_fb)
2622−{
2623− uint64_t tiling_flags;
2624− const struct drm_framebuffer *fb = &amdgpu_fb->base;
2625− int ret = 0;
2626− struct drm_format_name_buf format_name;
2627−
2628− ret = get_fb_info(
2629− amdgpu_fb,
2630− &tiling_flags);
2631−
2632− if (ret)
2633− return ret;
2634−
2635− switch (fb->format->format) {
2636− case DRM_FORMAT_C8:
2637− plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS;
2638− break;
2639− case DRM_FORMAT_RGB565:
2640− plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_RGB565;
2641− break;
2642− case DRM_FORMAT_XRGB8888:
2643− case DRM_FORMAT_ARGB8888:
2644− plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888;
2645− break;
2646− case DRM_FORMAT_XRGB2101010:
2647− case DRM_FORMAT_ARGB2101010:
2648− plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010;
2649− break;
2650− case DRM_FORMAT_XBGR2101010:
2651− case DRM_FORMAT_ABGR2101010:
2652− plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010;
2653− break;
2654− case DRM_FORMAT_XBGR8888:
2655− case DRM_FORMAT_ABGR8888:
2656− plane_state->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR8888;
2657− break;
2658− case DRM_FORMAT_NV21:
2659− plane_state->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr;
2660− break;
2661− case DRM_FORMAT_NV12:
2662− plane_state->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb;
2663− break;
2664− default:
2665− DRM_ERROR("Unsupported screen format %s\n",
2666− drm_get_format_name(fb->format->format, &format_name));
2667− return -EINVAL;
2668− }
2669−
2670− memset(&plane_state->address, 0, sizeof(plane_state->address));
2671−
2672− if (plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) {
2673− plane_state->plane_size.grph.surface_size.x = 0;
2674− plane_state->plane_size.grph.surface_size.y = 0;
2675− plane_state->plane_size.grph.surface_size.width = fb->width;
2676− plane_state->plane_size.grph.surface_size.height = fb->height;
2677− plane_state->plane_size.grph.surface_pitch =
2678− fb->pitches[0] / fb->format->cpp[0];
2679− /* TODO: unhardcode */
2680− plane_state->color_space = COLOR_SPACE_SRGB;
2681−
2682− } else {
2683− plane_state->plane_size.video.luma_size.x = 0;
2684− plane_state->plane_size.video.luma_size.y = 0;
2685− plane_state->plane_size.video.luma_size.width = fb->width;
2686− plane_state->plane_size.video.luma_size.height = fb->height;
2687− plane_state->plane_size.video.luma_pitch =
2688− fb->pitches[0] / fb->format->cpp[0];
2689−
2690− plane_state->plane_size.video.chroma_size.x = 0;
2691− plane_state->plane_size.video.chroma_size.y = 0;
2692− /* TODO: set these based on surface format */
2693− plane_state->plane_size.video.chroma_size.width = fb->width / 2;
2694− plane_state->plane_size.video.chroma_size.height = fb->height / 2;
2695−
2696− plane_state->plane_size.video.chroma_pitch =
2697− fb->pitches[1] / fb->format->cpp[1];
2698−
2699− /* TODO: unhardcode */
2700− plane_state->color_space = COLOR_SPACE_YCBCR709;
2701− }
2702−
2703− fill_plane_tiling_attributes(adev, amdgpu_fb, plane_state,
2704− &plane_state->tiling_info,
2705− &plane_state->dcc,
2706− &plane_state->address,
2707− tiling_flags);
2708−
2709− plane_state->visible = true;
2710− plane_state->scaling_quality.h_taps_c = 0;
2711− plane_state->scaling_quality.v_taps_c = 0;
2712−
2713− /* is this needed? is plane_state zeroed at allocation? */
2714− plane_state->scaling_quality.h_taps = 0;
2715− plane_state->scaling_quality.v_taps = 0;
2716− plane_state->stereo_format = PLANE_STEREO_FORMAT_NONE;
2717−
2718− return ret;
2719−
2720−}
2721−
27222653 static void
2723−fill_blending_from_plane_state(struct drm_plane_state *plane_state,
2724− const struct dc_plane_state *dc_plane_state,
2654+fill_blending_from_plane_state(const struct drm_plane_state *plane_state,
27252655 bool *per_pixel_alpha, bool *global_alpha,
27262656 int *global_alpha_value)
27272657 {
@@ -2757,7 +2687,7 @@ fill_blending_from_plane_state(struct drm_plane_state *plane_state, · 29 unmodified lines
27572687
27582688 static int
27592689 fill_plane_color_attributes(const struct drm_plane_state *plane_state,
2760− const struct dc_plane_state *dc_plane_state,
2690+ const enum surface_pixel_format format,
27612691 enum dc_color_space *color_space)
27622692 {
27632693 bool full_range;
@@ -2765,7 +2695,7 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state, · 1 unmodified line
27652695 *color_space = COLOR_SPACE_SRGB;
27662696
27672697 /* DRM color properties only affect non-RGB formats. */
2768− if (dc_plane_state->format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
2698+ if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
27692699 return 0;
27702700
27712701 full_range = (plane_state->color_range == DRM_COLOR_YCBCR_FULL_RANGE);
@@ -2799,32 +2729,144 @@ fill_plane_color_attributes(const struct drm_plane_state *plane_state, · 27 unmodified lines
27992729 return 0;
28002730 }
28012731
2802−static int fill_plane_attributes(struct amdgpu_device *adev,
2803− struct dc_plane_state *dc_plane_state,
2804− struct drm_plane_state *plane_state,
2805− struct drm_crtc_state *crtc_state)
2732+static int
2733+fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
2734+ const struct drm_plane_state *plane_state,
2735+ const uint64_t tiling_flags,
2736+ struct dc_plane_info *plane_info,
2737+ struct dc_plane_address *address)
2738+{
2739+ const struct drm_framebuffer *fb = plane_state->fb;
2740+ const struct amdgpu_framebuffer *afb =
2741+ to_amdgpu_framebuffer(plane_state->fb);
2742+ struct drm_format_name_buf format_name;
2743+ int ret;
2744+
2745+ memset(plane_info, 0, sizeof(*plane_info));
2746+
2747+ switch (fb->format->format) {
2748+ case DRM_FORMAT_C8:
2749+ plane_info->format =
2750+ SURFACE_PIXEL_FORMAT_GRPH_PALETA_256_COLORS;
2751+ break;
2752+ case DRM_FORMAT_RGB565:
2753+ plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_RGB565;
2754+ break;
2755+ case DRM_FORMAT_XRGB8888:
2756+ case DRM_FORMAT_ARGB8888:
2757+ plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB8888;
2758+ break;
2759+ case DRM_FORMAT_XRGB2101010:
2760+ case DRM_FORMAT_ARGB2101010:
2761+ plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010;
2762+ break;
2763+ case DRM_FORMAT_XBGR2101010:
2764+ case DRM_FORMAT_ABGR2101010:
2765+ plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010;
2766+ break;
2767+ case DRM_FORMAT_XBGR8888:
2768+ case DRM_FORMAT_ABGR8888:
2769+ plane_info->format = SURFACE_PIXEL_FORMAT_GRPH_ABGR8888;
2770+ break;
2771+ case DRM_FORMAT_NV21:
2772+ plane_info->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr;
2773+ break;
2774+ case DRM_FORMAT_NV12:
2775+ plane_info->format = SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb;
2776+ break;
2777+ default:
2778+ DRM_ERROR(
2779+ "Unsupported screen format %s\n",
2780+ drm_get_format_name(fb->format->format, &format_name));
2781+ return -EINVAL;
2782+ }
2783+
2784+ switch (plane_state->rotation & DRM_MODE_ROTATE_MASK) {
2785+ case DRM_MODE_ROTATE_0:
2786+ plane_info->rotation = ROTATION_ANGLE_0;
2787+ break;
2788+ case DRM_MODE_ROTATE_90:
2789+ plane_info->rotation = ROTATION_ANGLE_90;
2790+ break;
2791+ case DRM_MODE_ROTATE_180:
2792+ plane_info->rotation = ROTATION_ANGLE_180;
2793+ break;
2794+ case DRM_MODE_ROTATE_270:
2795+ plane_info->rotation = ROTATION_ANGLE_270;
2796+ break;
2797+ default:
2798+ plane_info->rotation = ROTATION_ANGLE_0;
2799+ break;
2800+ }
2801+
2802+ plane_info->visible = true;
2803+ plane_info->stereo_format = PLANE_STEREO_FORMAT_NONE;
2804+
2805+ ret = fill_plane_color_attributes(plane_state, plane_info->format,
2806+ &plane_info->color_space);
2807+ if (ret)
2808+ return ret;
2809+
2810+ ret = fill_plane_buffer_attributes(adev, afb, plane_info->format,
2811+ plane_info->rotation, tiling_flags,
2812+ &plane_info->tiling_info,
2813+ &plane_info->plane_size,
2814+ &plane_info->dcc, address);
2815+ if (ret)
2816+ return ret;
2817+
2818+ fill_blending_from_plane_state(
2819+ plane_state, &plane_info->per_pixel_alpha,
2820+ &plane_info->global_alpha, &plane_info->global_alpha_value);
2821+
2822+ return 0;
2823+}
2824+
2825+static int fill_dc_plane_attributes(struct amdgpu_device *adev,
2826+ struct dc_plane_state *dc_plane_state,
2827+ struct drm_plane_state *plane_state,
2828+ struct drm_crtc_state *crtc_state)
28062829 {
28072830 const struct amdgpu_framebuffer *amdgpu_fb =
28082831 to_amdgpu_framebuffer(plane_state->fb);
2809− const struct drm_crtc *crtc = plane_state->crtc;
2810− int ret = 0;
2832+ struct dc_scaling_info scaling_info;
2833+ struct dc_plane_info plane_info;
2834+ uint64_t tiling_flags;
2835+ int ret;
28112836
2812− if (!fill_rects_from_plane_state(plane_state, dc_plane_state))
2813− return -EINVAL;
2837+ ret = fill_dc_scaling_info(plane_state, &scaling_info);
2838+ if (ret)
2839+ return ret;
28142840
2815− ret = fill_plane_attributes_from_fb(
2816− crtc->dev->dev_private,
2817− dc_plane_state,
2818− amdgpu_fb);
2841+ dc_plane_state->src_rect = scaling_info.src_rect;
2842+ dc_plane_state->dst_rect = scaling_info.dst_rect;
2843+ dc_plane_state->clip_rect = scaling_info.clip_rect;
2844+ dc_plane_state->scaling_quality = scaling_info.scaling_quality;
28192845
2846+ ret = get_fb_info(amdgpu_fb, &tiling_flags);
28202847 if (ret)
28212848 return ret;
28222849
2823− ret = fill_plane_color_attributes(plane_state, dc_plane_state,
2824− &dc_plane_state->color_space);
2850+ ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
2851+ &plane_info,
2852+ &dc_plane_state->address);
28252853 if (ret)
28262854 return ret;
28272855
2856+ dc_plane_state->format = plane_info.format;
2857+ dc_plane_state->color_space = plane_info.color_space;
2858+ dc_plane_state->format = plane_info.format;
2859+ dc_plane_state->plane_size = plane_info.plane_size;
2860+ dc_plane_state->rotation = plane_info.rotation;
2861+ dc_plane_state->horizontal_mirror = plane_info.horizontal_mirror;
2862+ dc_plane_state->stereo_format = plane_info.stereo_format;
2863+ dc_plane_state->tiling_info = plane_info.tiling_info;
2864+ dc_plane_state->visible = plane_info.visible;
2865+ dc_plane_state->per_pixel_alpha = plane_info.per_pixel_alpha;
2866+ dc_plane_state->global_alpha = plane_info.global_alpha;
2867+ dc_plane_state->global_alpha_value = plane_info.global_alpha_value;
2868+ dc_plane_state->dcc = plane_info.dcc;
2869+
28282870 /*
28292871 * Always set input transfer function, since plane state is refreshed
28302872 * every time.
@@ -2835,11 +2877,6 @@ static int fill_plane_attributes(struct amdgpu_device *adev, · 4 unmodified lines
28352877 dc_plane_state->in_transfer_func = NULL;
28362878 }
28372879
2838− fill_blending_from_plane_state(plane_state, dc_plane_state,
2839− &dc_plane_state->per_pixel_alpha,
2840− &dc_plane_state->global_alpha,
2841− &dc_plane_state->global_alpha_value);
2842−
28432880 return ret;
28442881 }
28452882
@@ -3825,6 +3862,38 @@ static void dm_crtc_helper_disable(struct drm_crtc *crtc) · 979 unmodified lines
38253862 {
38263863 }
38273864
3865+static bool does_crtc_have_active_plane(struct drm_crtc_state *new_crtc_state)
3866+{
3867+ struct drm_atomic_state *state = new_crtc_state->state;
3868+ struct drm_plane *plane;
3869+ int num_active = 0;
3870+
3871+ drm_for_each_plane_mask(plane, state->dev, new_crtc_state->plane_mask) {
3872+ struct drm_plane_state *new_plane_state;
3873+
3874+ /* Cursor planes are "fake". */
3875+ if (plane->type == DRM_PLANE_TYPE_CURSOR)
3876+ continue;
3877+
3878+ new_plane_state = drm_atomic_get_new_plane_state(state, plane);
3879+
3880+ if (!new_plane_state) {
3881+ /*
3882+ * The plane is enable on the CRTC and hasn't changed
3883+ * state. This means that it previously passed
3884+ * validation and is therefore enabled.
3885+ */
3886+ num_active += 1;
3887+ continue;
3888+ }
3889+
3890+ /* We need a framebuffer to be considered enabled. */
3891+ num_active += (new_plane_state->fb != NULL);
3892+ }
3893+
3894+ return num_active > 0;
3895+}
3896+
38283897 static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
38293898 struct drm_crtc_state *state)
38303899 {
@@ -3843,6 +3912,11 @@ static int dm_crtc_helper_atomic_check(struct drm_crtc *crtc, · 12 unmodified lines
38433912 if (!dm_crtc_state->stream)
38443913 return 0;
38453914
3915+ /* We want at least one hardware plane enabled to use the stream. */
3916+ if (state->enable && state->active &&
3917+ !does_crtc_have_active_plane(state))
3918+ return -EINVAL;
3919+
38463920 if (dc_validate_stream(dc, dm_crtc_state->stream) == DC_OK)
38473921 return 0;
38483922
@@ -3994,9 +4068,11 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane, · 145 unmodified lines
39944068 dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
39954069 struct dc_plane_state *plane_state = dm_plane_state_new->dc_state;
39964070
3997− fill_plane_tiling_attributes(
3998− adev, afb, plane_state, &plane_state->tiling_info,
3999− &plane_state->dcc, &plane_state->address, tiling_flags);
4071+ fill_plane_buffer_attributes(
4072+ adev, afb, plane_state->format, plane_state->rotation,
4073+ tiling_flags, &plane_state->tiling_info,
4074+ &plane_state->plane_size, &plane_state->dcc,
4075+ &plane_state->address);
40004076 }
40014077
40024078 return 0;
@@ -4028,13 +4104,18 @@ static int dm_plane_atomic_check(struct drm_plane *plane, · 25 unmodified lines
40284104 {
40294105 struct amdgpu_device *adev = plane->dev->dev_private;
40304106 struct dc *dc = adev->dm.dc;
4031− struct dm_plane_state *dm_plane_state = to_dm_plane_state(state);
4107+ struct dm_plane_state *dm_plane_state;
4108+ struct dc_scaling_info scaling_info;
4109+ int ret;
4110+
4111+ dm_plane_state = to_dm_plane_state(state);
40324112
40334113 if (!dm_plane_state->dc_state)
40344114 return 0;
40354115
4036− if (!fill_rects_from_plane_state(state, dm_plane_state->dc_state))
4037− return -EINVAL;
4116+ ret = fill_dc_scaling_info(state, &scaling_info);
4117+ if (ret)
4118+ return ret;
40384119
40394120 if (dc_validate_plane(dc, dm_plane_state->dc_state) == DC_OK)
40404121 return 0;
@@ -4121,46 +4202,71 @@ static const u32 cursor_formats[] = { · 80 unmodified lines
41214202 DRM_FORMAT_ARGB8888
41224203 };
41234204
4124−static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
4125− struct drm_plane *plane,
4126− unsigned long possible_crtcs,
4127− const struct dc_plane_cap *plane_cap)
4205+static int get_plane_formats(const struct drm_plane *plane,
4206+ const struct dc_plane_cap *plane_cap,
4207+ uint32_t *formats, int max_formats)
41284208 {
4129− int res = -EPERM;
4209+ int i, num_formats = 0;
4210+
4211+ /*
4212+ * TODO: Query support for each group of formats directly from
4213+ * DC plane caps. This will require adding more formats to the
4214+ * caps list.
4215+ */
41304216
41314217 switch (plane->type) {
41324218 case DRM_PLANE_TYPE_PRIMARY:
4133− res = drm_universal_plane_init(
4134− dm->adev->ddev,
4135− plane,
4136− possible_crtcs,
4137− &dm_plane_funcs,
4138− rgb_formats,
4139− ARRAY_SIZE(rgb_formats),
4140− NULL, plane->type, NULL);
4219+ for (i = 0; i < ARRAY_SIZE(rgb_formats); ++i) {
4220+ if (num_formats >= max_formats)
4221+ break;
4222+
4223+ formats[num_formats++] = rgb_formats[i];
4224+ }
4225+
4226+ if (plane_cap && plane_cap->pixel_format_support.nv12)
4227+ formats[num_formats++] = DRM_FORMAT_NV12;
41414228 break;
4229+
41424230 case DRM_PLANE_TYPE_OVERLAY:
4143− res = drm_universal_plane_init(
4144− dm->adev->ddev,
4145− plane,
4146− possible_crtcs,
4147− &dm_plane_funcs,
4148− overlay_formats,
4149− ARRAY_SIZE(overlay_formats),
4150− NULL, plane->type, NULL);
4231+ for (i = 0; i < ARRAY_SIZE(overlay_formats); ++i) {
4232+ if (num_formats >= max_formats)
4233+ break;
4234+
4235+ formats[num_formats++] = overlay_formats[i];
4236+ }
41514237 break;
4238+
41524239 case DRM_PLANE_TYPE_CURSOR:
4153− res = drm_universal_plane_init(
4154− dm->adev->ddev,
4155− plane,
4156− possible_crtcs,
4157− &dm_plane_funcs,
4158− cursor_formats,
4159− ARRAY_SIZE(cursor_formats),
4160− NULL, plane->type, NULL);
4240+ for (i = 0; i < ARRAY_SIZE(cursor_formats); ++i) {
4241+ if (num_formats >= max_formats)
4242+ break;
4243+
4244+ formats[num_formats++] = cursor_formats[i];
4245+ }
41614246 break;
41624247 }
41634248
4249+ return num_formats;
4250+}
4251+
4252+static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
4253+ struct drm_plane *plane,
4254+ unsigned long possible_crtcs,
4255+ const struct dc_plane_cap *plane_cap)
4256+{
4257+ uint32_t formats[32];
4258+ int num_formats;
4259+ int res = -EPERM;
4260+
4261+ num_formats = get_plane_formats(plane, plane_cap, formats,
4262+ ARRAY_SIZE(formats));
4263+
4264+ res = drm_universal_plane_init(dm->adev->ddev, plane, possible_crtcs,
4265+ &dm_plane_funcs, formats, num_formats,
4266+ NULL, plane->type, NULL);
4267+ if (res)
4268+ return res;
4269+
41644270 if (plane->type == DRM_PLANE_TYPE_OVERLAY &&
41654271 plane_cap && plane_cap->per_pixel_alpha) {
41664272 unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
@@ -4170,14 +4276,25 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, · 3 unmodified lines
41704276 drm_plane_create_blend_mode_property(plane, blend_caps);
41714277 }
41724278
4279+ if (plane->type == DRM_PLANE_TYPE_PRIMARY &&
4280+ plane_cap && plane_cap->pixel_format_support.nv12) {
4281+ /* This only affects YUV formats. */
4282+ drm_plane_create_color_properties(
4283+ plane,
4284+ BIT(DRM_COLOR_YCBCR_BT601) |
4285+ BIT(DRM_COLOR_YCBCR_BT709),
4286+ BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
4287+ BIT(DRM_COLOR_YCBCR_FULL_RANGE),
4288+ DRM_COLOR_YCBCR_BT709, DRM_COLOR_YCBCR_LIMITED_RANGE);
4289+ }
4290+
41734291 drm_plane_helper_add(plane, &dm_plane_helper_funcs);
41744292
41754293 /* Create (reset) the plane state */
41764294 if (plane->funcs->reset)
41774295 plane->funcs->reset(plane);
41784296
4179−
4180− return res;
4297+ return 0;
41814298 }
41824299
41834300 static int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm,
@@ -4769,9 +4886,13 @@ static int get_cursor_position(struct drm_plane *plane, struct drm_crtc *crtc, · 585 unmodified lines
47694886
47704887 x = plane->state->crtc_x;
47714888 y = plane->state->crtc_y;
4772− /* avivo cursor are offset into the total surface */
4773− x += crtc->primary->state->src_x >> 16;
4774− y += crtc->primary->state->src_y >> 16;
4889+
4890+ if (crtc->primary->state) {
4891+ /* avivo cursor are offset into the total surface */
4892+ x += crtc->primary->state->src_x >> 16;
4893+ y += crtc->primary->state->src_y >> 16;
4894+ }
4895+
47754896 if (x < 0) {
47764897 xorigin = min(-x, amdgpu_crtc->max_cursor_width - 1);
47774898 x = 0;
@@ -5046,7 +5167,6 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 268 unmodified lines
50465167 struct drm_crtc *crtc = new_plane_state->crtc;
50475168 struct drm_crtc_state *new_crtc_state;
50485169 struct drm_framebuffer *fb = new_plane_state->fb;
5049− struct amdgpu_framebuffer *afb = to_amdgpu_framebuffer(fb);
50505170 bool plane_needs_flip;
50515171 struct dc_plane_state *dc_plane;
50525172 struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state);
@@ -5070,29 +5190,11 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 17 unmodified lines
50705190 bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
50715191 }
50725192
5193+ fill_dc_scaling_info(new_plane_state,
5194+ &bundle->scaling_infos[planes_count]);
50735195
5074− bundle->scaling_infos[planes_count].scaling_quality = dc_plane->scaling_quality;
5075− bundle->scaling_infos[planes_count].src_rect = dc_plane->src_rect;
5076− bundle->scaling_infos[planes_count].dst_rect = dc_plane->dst_rect;
5077− bundle->scaling_infos[planes_count].clip_rect = dc_plane->clip_rect;
5078− bundle->surface_updates[planes_count].scaling_info = &bundle->scaling_infos[planes_count];
5079−
5080− fill_plane_color_attributes(
5081− new_plane_state, dc_plane,
5082− &bundle->plane_infos[planes_count].color_space);
5083−
5084− bundle->plane_infos[planes_count].format = dc_plane->format;
5085− bundle->plane_infos[planes_count].plane_size = dc_plane->plane_size;
5086− bundle->plane_infos[planes_count].rotation = dc_plane->rotation;
5087− bundle->plane_infos[planes_count].horizontal_mirror = dc_plane->horizontal_mirror;
5088− bundle->plane_infos[planes_count].stereo_format = dc_plane->stereo_format;
5089− bundle->plane_infos[planes_count].tiling_info = dc_plane->tiling_info;
5090− bundle->plane_infos[planes_count].visible = dc_plane->visible;
5091− bundle->plane_infos[planes_count].global_alpha = dc_plane->global_alpha;
5092− bundle->plane_infos[planes_count].global_alpha_value = dc_plane->global_alpha_value;
5093− bundle->plane_infos[planes_count].per_pixel_alpha = dc_plane->per_pixel_alpha;
5094− bundle->plane_infos[planes_count].dcc = dc_plane->dcc;
5095− bundle->surface_updates[planes_count].plane_info = &bundle->plane_infos[planes_count];
5196+ bundle->surface_updates[planes_count].scaling_info =
5197+ &bundle->scaling_infos[planes_count];
50965198
50975199 plane_needs_flip = old_plane_state->fb && new_plane_state->fb;
50985200
@@ -5124,11 +5226,13 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, · 25 unmodified lines
51245226
51255227 amdgpu_bo_unreserve(abo);
51265228
5127− fill_plane_tiling_attributes(dm->adev, afb, dc_plane,
5128− &bundle->plane_infos[planes_count].tiling_info,
5129− &bundle->plane_infos[planes_count].dcc,
5130− &bundle->flip_addrs[planes_count].address,
5131− tiling_flags);
5229+ fill_dc_plane_info_and_addr(
5230+ dm->adev, new_plane_state, tiling_flags,
5231+ &bundle->plane_infos[planes_count],
5232+ &bundle->flip_addrs[planes_count].address);
5233+
5234+ bundle->surface_updates[planes_count].plane_info =
5235+ &bundle->plane_infos[planes_count];
51325236
51335237 bundle->flip_addrs[planes_count].flip_immediate =
51345238 (crtc->state->pageflip_flags & DRM_MODE_PAGE_FLIP_ASYNC) != 0;
@@ -5812,21 +5916,12 @@ static int dm_update_crtc_state(struct amdgpu_display_manager *dm, · 677 unmodified lines
58125916 struct amdgpu_dm_connector *aconnector = NULL;
58135917 struct drm_connector_state *drm_new_conn_state = NULL, *drm_old_conn_state = NULL;
58145918 struct dm_connector_state *dm_new_conn_state = NULL, *dm_old_conn_state = NULL;
5815− struct drm_plane_state *new_plane_state = NULL;
58165919
58175920 new_stream = NULL;
58185921
58195922 dm_old_crtc_state = to_dm_crtc_state(old_crtc_state);
58205923 dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
58215924 acrtc = to_amdgpu_crtc(crtc);
5822−
5823− new_plane_state = drm_atomic_get_new_plane_state(state, new_crtc_state->crtc->primary);
5824−
5825− if (new_crtc_state->enable && new_plane_state && !new_plane_state->fb) {
5826− ret = -EINVAL;
5827− goto fail;
5828− }
5829−
58305925 aconnector = amdgpu_dm_find_first_crtc_matching_connector(state, crtc);
58315926
58325927 /* TODO This hack should go away */
@@ -6016,6 +6111,69 @@ fail: · 183 unmodified lines
60166111 return ret;
60176112 }
60186113
6114+static bool should_reset_plane(struct drm_atomic_state *state,
6115+ struct drm_plane *plane,
6116+ struct drm_plane_state *old_plane_state,
6117+ struct drm_plane_state *new_plane_state)
6118+{
6119+ struct drm_plane *other;
6120+ struct drm_plane_state *old_other_state, *new_other_state;
6121+ struct drm_crtc_state *new_crtc_state;
6122+ int i;
6123+
6124+ /*
6125+ * TODO: Remove this hack once the checks below are sufficient
6126+ * enough to determine when we need to reset all the planes on
6127+ * the stream.
6128+ */
6129+ if (state->allow_modeset)
6130+ return true;
6131+
6132+ /* Exit early if we know that we're adding or removing the plane. */
6133+ if (old_plane_state->crtc != new_plane_state->crtc)
6134+ return true;
6135+
6136+ /* old crtc == new_crtc == NULL, plane not in context. */
6137+ if (!new_plane_state->crtc)
6138+ return false;
6139+
6140+ new_crtc_state =
6141+ drm_atomic_get_new_crtc_state(state, new_plane_state->crtc);
6142+
6143+ if (!new_crtc_state)
6144+ return true;
6145+
6146+ if (drm_atomic_crtc_needs_modeset(new_crtc_state))
6147+ return true;
6148+
6149+ /*
6150+ * If there are any new primary or overlay planes being added or
6151+ * removed then the z-order can potentially change. To ensure
6152+ * correct z-order and pipe acquisition the current DC architecture
6153+ * requires us to remove and recreate all existing planes.
6154+ *
6155+ * TODO: Come up with a more elegant solution for this.
6156+ */
6157+ for_each_oldnew_plane_in_state(state, other, old_other_state, new_other_state, i) {
6158+ if (other->type == DRM_PLANE_TYPE_CURSOR)
6159+ continue;
6160+
6161+ if (old_other_state->crtc != new_plane_state->crtc &&
6162+ new_other_state->crtc != new_plane_state->crtc)
6163+ continue;
6164+
6165+ if (old_other_state->crtc != new_other_state->crtc)
6166+ return true;
6167+
6168+ /* TODO: Remove this once we can handle fast format changes. */
6169+ if (old_other_state->fb && new_other_state->fb &&
6170+ old_other_state->fb->format != new_other_state->fb->format)
6171+ return true;
6172+ }
6173+
6174+ return false;
6175+}
6176+
60196177 static int dm_update_plane_state(struct dc *dc,
60206178 struct drm_atomic_state *state,
60216179 struct drm_plane *plane,
@@ -6030,8 +6188,7 @@ static int dm_update_plane_state(struct dc *dc, · 8 unmodified lines
60306188 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
60316189 struct dm_crtc_state *dm_new_crtc_state, *dm_old_crtc_state;
60326190 struct dm_plane_state *dm_new_plane_state, *dm_old_plane_state;
6033− /* TODO return page_flip_needed() function */
6034− bool pflip_needed = !state->allow_modeset;
6191+ bool needs_reset;
60356192 int ret = 0;
60366193
60376194
@@ -6044,10 +6201,12 @@ static int dm_update_plane_state(struct dc *dc, · 6 unmodified lines
60446201 if (plane->type == DRM_PLANE_TYPE_CURSOR)
60456202 return 0;
60466203
6204+ needs_reset = should_reset_plane(state, plane, old_plane_state,
6205+ new_plane_state);
6206+
60476207 /* Remove any changed/removed planes */
60486208 if (!enable) {
6049− if (pflip_needed &&
6050− plane->type != DRM_PLANE_TYPE_OVERLAY)
6209+ if (!needs_reset)
60516210 return 0;
60526211
60536212 if (!old_plane_crtc)
@@ -6098,7 +6257,7 @@ static int dm_update_plane_state(struct dc *dc, · 44 unmodified lines
60986257 if (!dm_new_crtc_state->stream)
60996258 return 0;
61006259
6101− if (pflip_needed && plane->type != DRM_PLANE_TYPE_OVERLAY)
6260+ if (!needs_reset)
61026261 return 0;
61036262
61046263 WARN_ON(dm_new_plane_state->dc_state);
@@ -6110,7 +6269,7 @@ static int dm_update_plane_state(struct dc *dc, · 5 unmodified lines
61106269 DRM_DEBUG_DRIVER("Enabling DRM plane: %d on DRM crtc %d\n",
61116270 plane->base.id, new_plane_crtc->base.id);
61126271
6113− ret = fill_plane_attributes(
6272+ ret = fill_dc_plane_attributes(
61146273 new_plane_crtc->dev->dev_private,
61156274 dc_new_plane_state,
61166275 new_plane_state,
@@ -6158,10 +6317,11 @@ static int dm_update_plane_state(struct dc *dc, · 41 unmodified lines
61586317 }
61596318
61606319 static int
6161−dm_determine_update_type_for_commit(struct dc *dc,
6320+dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
61626321 struct drm_atomic_state *state,
61636322 enum surface_update_type *out_type)
61646323 {
6324+ struct dc *dc = dm->dc;
61656325 struct dm_atomic_state *dm_state = NULL, *old_dm_state = NULL;
61666326 int i, j, num_plane, ret = 0;
61676327 struct drm_plane_state *old_plane_state, *new_plane_state;
@@ -6175,20 +6335,19 @@ dm_determine_update_type_for_commit(struct dc *dc, · 7 unmodified lines
61756335 struct dc_stream_status *status = NULL;
61766336
61776337 struct dc_surface_update *updates;
6178− struct dc_plane_state *surface;
61796338 enum surface_update_type update_type = UPDATE_TYPE_FAST;
61806339
61816340 updates = kcalloc(MAX_SURFACES, sizeof(*updates), GFP_KERNEL);
6182− surface = kcalloc(MAX_SURFACES, sizeof(*surface), GFP_KERNEL);
61836341
6184− if (!updates || !surface) {
6185− DRM_ERROR("Plane or surface update failed to allocate");
6342+ if (!updates) {
6343+ DRM_ERROR("Failed to allocate plane updates\n");
61866344 /* Set type to FULL to avoid crashing in DC*/
61876345 update_type = UPDATE_TYPE_FULL;
61886346 goto cleanup;
61896347 }
61906348
61916349 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
6350+ struct dc_scaling_info scaling_info;
61926351 struct dc_stream_update stream_update;
61936352
61946353 memset(&stream_update, 0, sizeof(stream_update));
@@ -6219,23 +6378,12 @@ dm_determine_update_type_for_commit(struct dc *dc, · 24 unmodified lines
62196378 goto cleanup;
62206379 }
62216380
6222− if (!state->allow_modeset)
6223− continue;
6224−
62256381 if (crtc != new_plane_crtc)
62266382 continue;
62276383
6228− updates[num_plane].surface = &surface[num_plane];
6384+ updates[num_plane].surface = new_dm_plane_state->dc_state;
62296385
62306386 if (new_crtc_state->mode_changed) {
6231− updates[num_plane].surface->src_rect =
6232− new_dm_plane_state->dc_state->src_rect;
6233− updates[num_plane].surface->dst_rect =
6234− new_dm_plane_state->dc_state->dst_rect;
6235− updates[num_plane].surface->rotation =
6236− new_dm_plane_state->dc_state->rotation;
6237− updates[num_plane].surface->in_transfer_func =
6238− new_dm_plane_state->dc_state->in_transfer_func;
62396387 stream_update.dst = new_dm_crtc_state->stream->dst;
62406388 stream_update.src = new_dm_crtc_state->stream->src;
62416389 }
@@ -6251,6 +6399,13 @@ dm_determine_update_type_for_commit(struct dc *dc, · 9 unmodified lines
62516399 new_dm_crtc_state->stream->out_transfer_func;
62526400 }
62536401
6402+ ret = fill_dc_scaling_info(new_plane_state,
6403+ &scaling_info);
6404+ if (ret)
6405+ goto cleanup;
6406+
6407+ updates[num_plane].scaling_info = &scaling_info;
6408+
62546409 num_plane++;
62556410 }
62566411
@@ -6270,8 +6425,14 @@ dm_determine_update_type_for_commit(struct dc *dc, · 13 unmodified lines
62706425 status = dc_stream_get_status_from_state(old_dm_state->context,
62716426 new_dm_crtc_state->stream);
62726427
6428+ /*
6429+ * TODO: DC modifies the surface during this call so we need
6430+ * to lock here - find a way to do this without locking.
6431+ */
6432+ mutex_lock(&dm->dc_lock);
62736433 update_type = dc_check_update_surfaces_for_stream(dc, updates, num_plane,
62746434 &stream_update, status);
6435+ mutex_unlock(&dm->dc_lock);
62756436
62766437 if (update_type > UPDATE_TYPE_MED) {
62776438 update_type = UPDATE_TYPE_FULL;
@@ -6281,7 +6442,6 @@ dm_determine_update_type_for_commit(struct dc *dc, · 3 unmodified lines
62816442
62826443 cleanup:
62836444 kfree(updates);
6284− kfree(surface);
62856445
62866446 *out_type = update_type;
62876447 return ret;
@@ -6465,7 +6625,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 177 unmodified lines
64656625 lock_and_validation_needed = true;
64666626 }
64676627
6468− ret = dm_determine_update_type_for_commit(dc, state, &update_type);
6628+ ret = dm_determine_update_type_for_commit(&adev->dm, state, &update_type);
64696629 if (ret)
64706630 goto fail;
64716631
@@ -6480,9 +6640,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 8 unmodified lines
64806640 */
64816641 if (lock_and_validation_needed && overall_update_type <= UPDATE_TYPE_FAST)
64826642 WARN(1, "Global lock should be Set, overall_update_type should be UPDATE_TYPE_MED or UPDATE_TYPE_FULL");
6483− else if (!lock_and_validation_needed && overall_update_type > UPDATE_TYPE_FAST)
6484− WARN(1, "Global lock should NOT be set, overall_update_type should be UPDATE_TYPE_FAST");
6485−
64866643
64876644 if (overall_update_type > UPDATE_TYPE_FAST) {
64886645 ret = dm_atomic_get_state(state, &dm_state);
@@ -6493,7 +6650,7 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, · 4 unmodified lines
64936650 if (ret)
64946651 goto fail;
64956652
6496− if (dc_validate_global_state(dc, dm_state->context) != DC_OK) {
6653+ if (dc_validate_global_state(dc, dm_state->context, false) != DC_OK) {
64976654 ret = -EINVAL;
64986655 goto fail;
64996656 }
drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c+22−2
@@ -701,8 +701,15 @@ static void hack_bounding_box(struct dcn_bw_internal_vars *v, · 700 unmodified lines
701701
702702 bool dcn_validate_bandwidth(
703703 struct dc *dc,
704− struct dc_state *context)
704+ struct dc_state *context,
705+ bool fast_validate)
705706 {
707+ /*
708+ * we want a breakdown of the various stages of validation, which the
709+ * perf_trace macro doesn't support
710+ */
711+ BW_VAL_TRACE_SETUP();
712+
706713 const struct resource_pool *pool = dc->res_pool;
707714 struct dcn_bw_internal_vars *v = &context->dcn_bw_vars;
708715 int i, input_idx;
@@ -711,6 +718,9 @@ bool dcn_validate_bandwidth( · 2 unmodified lines
711718 float bw_limit;
712719
713720 PERFORMANCE_TRACE_START();
721+
722+ BW_VAL_TRACE_COUNT();
723+
714724 if (dcn_bw_apply_registry_override(dc))
715725 dcn_bw_sync_calcs_and_dml(dc);
716726
@@ -1013,8 +1023,11 @@ bool dcn_validate_bandwidth( · 296 unmodified lines
10131023 mode_support_and_system_configuration(v);
10141024 }
10151025
1016− if (v->voltage_level != 5) {
1026+ BW_VAL_TRACE_END_VOLTAGE_LEVEL();
1027+
1028+ if (v->voltage_level != number_of_states_plus_one && !fast_validate) {
10171029 float bw_consumed = v->total_bandwidth_consumed_gbyte_per_second;
1030+
10181031 if (bw_consumed < v->fabric_and_dram_bandwidth_vmin0p65)
10191032 bw_consumed = v->fabric_and_dram_bandwidth_vmin0p65;
10201033 else if (bw_consumed < v->fabric_and_dram_bandwidth_vmid0p72)
@@ -1087,6 +1100,8 @@ bool dcn_validate_bandwidth( · 66 unmodified lines
10871100 break;
10881101 }
10891102
1103+ BW_VAL_TRACE_END_WATERMARKS();
1104+
10901105 for (i = 0, input_idx = 0; i < pool->pipe_count; i++) {
10911106 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
10921107
@@ -1177,6 +1192,10 @@ bool dcn_validate_bandwidth( · 84 unmodified lines
11771192
11781193 input_idx++;
11791194 }
1195+ } else if (v->voltage_level == number_of_states_plus_one) {
1196+ BW_VAL_TRACE_SKIP(fail);
1197+ } else if (fast_validate) {
1198+ BW_VAL_TRACE_SKIP(fast);
11801199 }
11811200
11821201 if (v->voltage_level == 0) {
@@ -1196,6 +1215,7 @@ bool dcn_validate_bandwidth( · 13 unmodified lines
11961215 kernel_fpu_end();
11971216
11981217 PERFORMANCE_TRACE_END();
1218+ BW_VAL_TRACE_FINISH();
11991219
12001220 if (bw_limit_pass && v->voltage_level != 5)
12011221 return true;
drivers/gpu/drm/amd/display/dc/core/dc.c+1−1
@@ -597,7 +597,7 @@ uint32_t dc_link_bandwidth_kbps( · 596 unmodified lines
597597
598598 }
599599
600−const struct dc_link_settings *dc_link_get_verified_link_cap(
600+const struct dc_link_settings *dc_link_get_link_cap(
601601 const struct dc_link *link)
602602 {
603603 if (link->preferred_link_setting.lane_count != LANE_COUNT_UNKNOWN &&
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c+31−2
@@ -1548,8 +1548,7 @@ bool dp_validate_mode_timing( · 1547 unmodified lines
15481548 timing->v_addressable == (uint32_t) 480)
15491549 return true;
15501550
1551− /* We always use verified link settings */
1552− link_setting = dc_link_get_verified_link_cap(link);
1551+ link_setting = dc_link_get_link_cap(link);
15531552
15541553 /* TODO: DYNAMIC_VALIDATION needs to be implemented */
15551554 /*if (flags.DYNAMIC_VALIDATION == 1 &&
@@ -2587,6 +2586,9 @@ void detect_edp_sink_caps(struct dc_link *link) · 1031 unmodified lines
25872586 uint32_t entry;
25882587 uint32_t link_rate_in_khz;
25892588 enum dc_link_rate link_rate = LINK_RATE_UNKNOWN;
2589+ union lane_count_set lane_count_set = { {0} };
2590+ uint8_t link_bw_set;
2591+ uint8_t link_rate_set;
25902592
25912593 retrieve_link_cap(link);
25922594 link->dpcd_caps.edp_supported_link_rates_count = 0;
@@ -2612,6 +2614,33 @@ void detect_edp_sink_caps(struct dc_link *link) · 19 unmodified lines
26122614 }
26132615 }
26142616 link->verified_link_cap = link->reported_link_cap;
2617+
2618+ // Read DPCD 00101h to find out the number of lanes currently set
2619+ core_link_read_dpcd(link, DP_LANE_COUNT_SET,
2620+ &lane_count_set.raw, sizeof(lane_count_set));
2621+ link->cur_link_settings.lane_count = lane_count_set.bits.LANE_COUNT_SET;
2622+
2623+ // Read DPCD 00100h to find if standard link rates are set
2624+ core_link_read_dpcd(link, DP_LINK_BW_SET,
2625+ &link_bw_set, sizeof(link_bw_set));
2626+
2627+ if (link_bw_set == 0) {
2628+ /* If standard link rates are not being used,
2629+ * Read DPCD 00115h to find the link rate set used
2630+ */
2631+ core_link_read_dpcd(link, DP_LINK_RATE_SET,
2632+ &link_rate_set, sizeof(link_rate_set));
2633+
2634+ if (link_rate_set < link->dpcd_caps.edp_supported_link_rates_count) {
2635+ link->cur_link_settings.link_rate =
2636+ link->dpcd_caps.edp_supported_link_rates[link_rate_set];
2637+ link->cur_link_settings.link_rate_set = link_rate_set;
2638+ link->cur_link_settings.use_link_rate_set = true;
2639+ }
2640+ } else {
2641+ link->cur_link_settings.link_rate = link_bw_set;
2642+ link->cur_link_settings.use_link_rate_set = false;
2643+ }
26152644 }
26162645
26172646 void dc_link_dp_enable_hpd(const struct dc_link *link)
drivers/gpu/drm/amd/display/dc/core/dc_resource.c+4−2
@@ -2067,12 +2067,14 @@ void dc_resource_state_construct( · 2066 unmodified lines
20672067 * Checks HW resource availability and bandwidth requirement.
20682068 * @dc: dc struct for this driver
20692069 * @new_ctx: state to be validated
2070+ * @fast_validate: set to true if only yes/no to support matters
20702071 *
20712072 * Return: DC_OK if the result can be programmed. Otherwise, an error code.
20722073 */
20732074 enum dc_status dc_validate_global_state(
20742075 struct dc *dc,
2075− struct dc_state *new_ctx)
2076+ struct dc_state *new_ctx,
2077+ bool fast_validate)
20762078 {
20772079 enum dc_status result = DC_ERROR_UNEXPECTED;
20782080 int i, j;
@@ -2127,7 +2129,7 @@ enum dc_status dc_validate_global_state( · 48 unmodified lines
21272129 result = resource_build_scaling_params_for_context(dc, new_ctx);
21282130
21292131 if (result == DC_OK)
2130− if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx))
2132+ if (!dc->res_pool->funcs->validate_bandwidth(dc, new_ctx, fast_validate))
21312133 result = DC_FAIL_BANDWIDTH_VALIDATE;
21322134
21332135 return result;
drivers/gpu/drm/amd/display/dc/core/dc_stream.c+2−1
@@ -211,7 +211,8 @@ static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc) · 210 unmodified lines
211211 ASIC_REV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) {
212212
213213 vupdate_line = get_vupdate_offset_from_vsync(pipe_ctx);
214− dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos);
214+ if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos))
215+ return;
215216
216217 if (vpos >= vupdate_line)
217218 return;
drivers/gpu/drm/amd/display/dc/dc.h+81−4
@@ -39,7 +39,7 @@ · 38 unmodified lines
3939 #include "inc/hw/dmcu.h"
4040 #include "dml/display_mode_lib.h"
4141
42−#define DC_VER "3.2.25"
42+#define DC_VER "3.2.26"
4343
4444 #define MAX_SURFACES 3
4545 #define MAX_PLANES 6
@@ -66,8 +66,27 @@ struct dc_plane_cap { · 20 unmodified lines
6666 uint32_t blends_with_above : 1;
6767 uint32_t blends_with_below : 1;
6868 uint32_t per_pixel_alpha : 1;
69− uint32_t supports_argb8888 : 1;
70− uint32_t supports_nv12 : 1;
69+ struct {
70+ uint32_t argb8888 : 1;
71+ uint32_t nv12 : 1;
72+ uint32_t fp16 : 1;
73+ } pixel_format_support;
74+ // max upscaling factor x1000
75+ // upscaling factors are always >= 1
76+ // for example, 1080p -> 8K is 4.0, or 4000 raw value
77+ struct {
78+ uint32_t argb8888;
79+ uint32_t nv12;
80+ uint32_t fp16;
81+ } max_upscale_factor;
82+ // max downscale factor x1000
83+ // downscale factors are always <= 1
84+ // for example, 8K -> 1080p is 0.25, or 250 raw value
85+ struct {
86+ uint32_t argb8888;
87+ uint32_t nv12;
88+ uint32_t fp16;
89+ } max_downscale_factor;
7190 };
7291
7392 struct dc_caps {
@@ -183,6 +202,7 @@ struct dc_config { · 109 unmodified lines
183202 bool disable_disp_pll_sharing;
184203 bool fbc_support;
185204 bool optimize_edp_link_rate;
205+ bool disable_fractional_pwm;
186206 bool allow_seamless_boot_optimization;
187207 };
188208
@@ -226,6 +246,57 @@ struct dc_clocks { · 37 unmodified lines
226246 bool p_state_change_support;
227247 };
228248
249+struct dc_bw_validation_profile {
250+ bool enable;
251+
252+ unsigned long long total_ticks;
253+ unsigned long long voltage_level_ticks;
254+ unsigned long long watermark_ticks;
255+ unsigned long long rq_dlg_ticks;
256+
257+ unsigned long long total_count;
258+ unsigned long long skip_fast_count;
259+ unsigned long long skip_pass_count;
260+ unsigned long long skip_fail_count;
261+};
262+
263+#define BW_VAL_TRACE_SETUP() \
264+ unsigned long long end_tick = 0; \
265+ unsigned long long voltage_level_tick = 0; \
266+ unsigned long long watermark_tick = 0; \
267+ unsigned long long start_tick = dc->debug.bw_val_profile.enable ? \
268+ dm_get_timestamp(dc->ctx) : 0
269+
270+#define BW_VAL_TRACE_COUNT() \
271+ if (dc->debug.bw_val_profile.enable) \
272+ dc->debug.bw_val_profile.total_count++
273+
274+#define BW_VAL_TRACE_SKIP(status) \
275+ if (dc->debug.bw_val_profile.enable) { \
276+ if (!voltage_level_tick) \
277+ voltage_level_tick = dm_get_timestamp(dc->ctx); \
278+ dc->debug.bw_val_profile.skip_ ## status ## _count++; \
279+ }
280+
281+#define BW_VAL_TRACE_END_VOLTAGE_LEVEL() \
282+ if (dc->debug.bw_val_profile.enable) \
283+ voltage_level_tick = dm_get_timestamp(dc->ctx)
284+
285+#define BW_VAL_TRACE_END_WATERMARKS() \
286+ if (dc->debug.bw_val_profile.enable) \
287+ watermark_tick = dm_get_timestamp(dc->ctx)
288+
289+#define BW_VAL_TRACE_FINISH() \
290+ if (dc->debug.bw_val_profile.enable) { \
291+ end_tick = dm_get_timestamp(dc->ctx); \
292+ dc->debug.bw_val_profile.total_ticks += end_tick - start_tick; \
293+ dc->debug.bw_val_profile.voltage_level_ticks += voltage_level_tick - start_tick; \
294+ if (watermark_tick) { \
295+ dc->debug.bw_val_profile.watermark_ticks += watermark_tick - voltage_level_tick; \
296+ dc->debug.bw_val_profile.rq_dlg_ticks += end_tick - watermark_tick; \
297+ } \
298+ }
299+
229300 struct dc_debug_options {
230301 enum visual_confirm visual_confirm;
231302 bool sanity_checks;
@@ -279,6 +350,7 @@ struct dc_debug_options { · 47 unmodified lines
279350 unsigned int force_odm_combine; //bit vector based on otg inst
280351 unsigned int force_fclk_khz;
281352 bool disable_tri_buf;
353+ struct dc_bw_validation_profile bw_val_profile;
282354 };
283355
284356 struct dc_debug_data {
@@ -638,9 +710,14 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla · 353 unmodified lines
638710
639711 void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info);
640712
713+/*
714+ * fast_validate: we return after determining if we can support the new state,
715+ * but before we populate the programming info
716+ */
641717 enum dc_status dc_validate_global_state(
642718 struct dc *dc,
643− struct dc_state *new_ctx);
719+ struct dc_state *new_ctx,
720+ bool fast_validate);
644721
645722
646723 void dc_resource_state_construct(
drivers/gpu/drm/amd/display/dc/dc_link.h+1−1
@@ -250,7 +250,7 @@ uint32_t dc_link_bandwidth_kbps( · 249 unmodified lines
250250 const struct dc_link *link,
251251 const struct dc_link_settings *link_setting);
252252
253−const struct dc_link_settings *dc_link_get_verified_link_cap(
253+const struct dc_link_settings *dc_link_get_link_cap(
254254 const struct dc_link *link);
255255
256256 bool dc_submit_i2c(
drivers/gpu/drm/amd/display/dc/dce/dce_abm.c+18−0
@@ -50,6 +50,7 @@ · 49 unmodified lines
5050 #define MCP_ABM_LEVEL_SET 0x65
5151 #define MCP_ABM_PIPE_SET 0x66
5252 #define MCP_BL_SET 0x67
53+#define MCP_BL_SET_PWM_FRAC 0x6A /* Enable or disable Fractional PWM */
5354
5455 #define MCP_DISABLE_ABM_IMMEDIATELY 255
5556
@@ -390,6 +391,23 @@ static bool dce_abm_init_backlight(struct abm *abm) · 334 unmodified lines
390391 REG_UPDATE(BL_PWM_GRP1_REG_LOCK,
391392 BL_PWM_GRP1_REG_LOCK, 0);
392393
394+ /* Wait until microcontroller is ready to process interrupt */
395+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
396+
397+ /* Set PWM fractional enable/disable */
398+ value = (abm->ctx->dc->config.disable_fractional_pwm == false) ? 1 : 0;
399+ REG_WRITE(MASTER_COMM_DATA_REG1, value);
400+
401+ /* Set command to enable or disable fractional PWM microcontroller */
402+ REG_UPDATE(MASTER_COMM_CMD_REG, MASTER_COMM_CMD_REG_BYTE0,
403+ MCP_BL_SET_PWM_FRAC);
404+
405+ /* Notify microcontroller of new command */
406+ REG_UPDATE(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 1);
407+
408+ /* Ensure command has been executed before continuing */
409+ REG_WAIT(MASTER_COMM_CNTL_REG, MASTER_COMM_INTERRUPT, 0, 100, 800);
410+
393411 return true;
394412 }
395413
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c+20−2
@@ -380,7 +380,24 @@ static const struct resource_caps res_cap = { · 379 unmodified lines
380380
381381 static const struct dc_plane_cap plane_cap = {
382382 .type = DC_PLANE_TYPE_DCE_RGB,
383− .supports_argb8888 = true,
383+
384+ .pixel_format_support = {
385+ .argb8888 = true,
386+ .nv12 = false,
387+ .fp16 = false
388+ },
389+
390+ .max_upscale_factor = {
391+ .argb8888 = 16000,
392+ .nv12 = 1,
393+ .fp16 = 1
394+ },
395+
396+ .max_downscale_factor = {
397+ .argb8888 = 250,
398+ .nv12 = 1,
399+ .fp16 = 1
400+ }
384401 };
385402
386403 #define CTX ctx
@@ -761,7 +778,8 @@ static enum dc_status build_mapped_resource( · 374 unmodified lines
761778
762779 bool dce100_validate_bandwidth(
763780 struct dc *dc,
764− struct dc_state *context)
781+ struct dc_state *context,
782+ bool fast_validate)
765783 {
766784 int i;
767785 bool at_least_one_pipe = false;
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c+38−3
@@ -397,14 +397,48 @@ static const struct dc_plane_cap plane_cap = { · 396 unmodified lines
397397 .blends_with_below = true,
398398 .blends_with_above = true,
399399 .per_pixel_alpha = 1,
400− .supports_argb8888 = true,
400+
401+ .pixel_format_support = {
402+ .argb8888 = true,
403+ .nv12 = false,
404+ .fp16 = false
405+ },
406+
407+ .max_upscale_factor = {
408+ .argb8888 = 16000,
409+ .nv12 = 1,
410+ .fp16 = 1
411+ },
412+
413+ .max_downscale_factor = {
414+ .argb8888 = 250,
415+ .nv12 = 1,
416+ .fp16 = 1
417+ }
401418 };
402419
403420 static const struct dc_plane_cap underlay_plane_cap = {
404421 .type = DC_PLANE_TYPE_DCE_UNDERLAY,
405422 .blends_with_above = true,
406423 .per_pixel_alpha = 1,
407− .supports_nv12 = true
424+
425+ .pixel_format_support = {
426+ .argb8888 = false,
427+ .nv12 = true,
428+ .fp16 = false
429+ },
430+
431+ .max_upscale_factor = {
432+ .argb8888 = 1,
433+ .nv12 = 16000,
434+ .fp16 = 1
435+ },
436+
437+ .max_downscale_factor = {
438+ .argb8888 = 1,
439+ .nv12 = 250,
440+ .fp16 = 1
441+ }
408442 };
409443
410444 #define CTX ctx
@@ -869,7 +903,8 @@ static enum dc_status build_mapped_resource( · 458 unmodified lines
869903
870904 static bool dce110_validate_bandwidth(
871905 struct dc *dc,
872− struct dc_state *context)
906+ struct dc_state *context,
907+ bool fast_validate)
873908 {
874909 bool result = false;
875910
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c+20−2
@@ -399,7 +399,24 @@ static const struct resource_caps polaris_11_resource_cap = { · 398 unmodified lines
399399
400400 static const struct dc_plane_cap plane_cap = {
401401 .type = DC_PLANE_TYPE_DCE_RGB,
402− .supports_argb8888 = true,
402+
403+ .pixel_format_support = {
404+ .argb8888 = true,
405+ .nv12 = false,
406+ .fp16 = false
407+ },
408+
409+ .max_upscale_factor = {
410+ .argb8888 = 16000,
411+ .nv12 = 1,
412+ .fp16 = 1
413+ },
414+
415+ .max_downscale_factor = {
416+ .argb8888 = 250,
417+ .nv12 = 1,
418+ .fp16 = 1
419+ }
403420 };
404421
405422 #define CTX ctx
@@ -809,7 +826,8 @@ static enum dc_status build_mapped_resource( · 403 unmodified lines
809826
810827 bool dce112_validate_bandwidth(
811828 struct dc *dc,
812− struct dc_state *context)
829+ struct dc_state *context,
830+ bool fast_validate)
813831 {
814832 bool result = false;
815833
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.h+2−1
@@ -44,7 +44,8 @@ enum dc_status dce112_validate_with_context( · 43 unmodified lines
4444
4545 bool dce112_validate_bandwidth(
4646 struct dc *dc,
47− struct dc_state *context);
47+ struct dc_state *context,
48+ bool fast_validate);
4849
4950 enum dc_status dce112_add_stream_to_ctx(
5051 struct dc *dc,
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c+18−1
@@ -456,7 +456,24 @@ static const struct resource_caps res_cap = { · 455 unmodified lines
456456
457457 static const struct dc_plane_cap plane_cap = {
458458 .type = DC_PLANE_TYPE_DCE_RGB,
459− .supports_argb8888 = true,
459+
460+ .pixel_format_support = {
461+ .argb8888 = true,
462+ .nv12 = false,
463+ .fp16 = false
464+ },
465+
466+ .max_upscale_factor = {
467+ .argb8888 = 16000,
468+ .nv12 = 1,
469+ .fp16 = 1
470+ },
471+
472+ .max_downscale_factor = {
473+ .argb8888 = 250,
474+ .nv12 = 1,
475+ .fp16 = 1
476+ }
460477 };
461478
462479 static const struct dc_debug_options debug_defaults = {
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c+20−2
@@ -389,7 +389,24 @@ static const struct resource_caps res_cap_83 = { · 388 unmodified lines
389389
390390 static const struct dc_plane_cap plane_cap = {
391391 .type = DC_PLANE_TYPE_DCE_RGB,
392− .supports_argb8888 = true,
392+
393+ .pixel_format_support = {
394+ .argb8888 = true,
395+ .nv12 = false,
396+ .fp16 = false
397+ },
398+
399+ .max_upscale_factor = {
400+ .argb8888 = 16000,
401+ .nv12 = 1,
402+ .fp16 = 1
403+ },
404+
405+ .max_downscale_factor = {
406+ .argb8888 = 250,
407+ .nv12 = 1,
408+ .fp16 = 1
409+ }
393410 };
394411
395412 static const struct dce_dmcu_registers dmcu_regs = {
@@ -795,7 +812,8 @@ static void destruct(struct dce110_resource_pool *pool) · 399 unmodified lines
795812
796813 bool dce80_validate_bandwidth(
797814 struct dc *dc,
798− struct dc_state *context)
815+ struct dc_state *context,
816+ bool fast_validate)
799817 {
800818 int i;
801819 bool at_least_one_pipe = false;
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hubp.h+6−3
@@ -247,7 +247,7 @@ · 246 unmodified lines
247247 .field_name = reg_name ## __ ## field_name ## post_fix
248248
249249 /* Mask/shift struct generation macro for all ASICs (including those with reduced functionality) */
250−#define HUBP_MASK_SH_LIST_DCN(mask_sh)\
250+#define HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh)\
251251 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_BLANK_EN, mask_sh),\
252252 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_TTU_DISABLE, mask_sh),\
253253 HUBP_SF(HUBP0_DCHUBP_CNTL, HUBP_UNDERFLOW_STATUS, mask_sh),\
@@ -331,7 +331,6 @@ · 77 unmodified lines
331331 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, META_CHUNK_SIZE, mask_sh),\
332332 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MIN_META_CHUNK_SIZE, mask_sh),\
333333 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, DPTE_GROUP_SIZE, mask_sh),\
334− HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\
335334 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, SWATH_HEIGHT, mask_sh),\
336335 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, PTE_ROW_HEIGHT_LINEAR, mask_sh),\
337336 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, CHUNK_SIZE_C, mask_sh),\
@@ -339,7 +338,6 @@ · 1 unmodified line
339338 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, META_CHUNK_SIZE_C, mask_sh),\
340339 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MIN_META_CHUNK_SIZE_C, mask_sh),\
341340 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, DPTE_GROUP_SIZE_C, mask_sh),\
342− HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh),\
343341 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, SWATH_HEIGHT_C, mask_sh),\
344342 HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, PTE_ROW_HEIGHT_LINEAR_C, mask_sh),\
345343 HUBP_SF(HUBPREQ0_BLANK_OFFSET_0, REFCYC_H_BLANK_END, mask_sh),\
@@ -373,6 +371,11 @@ · 27 unmodified lines
373371 HUBP_SF(HUBPREQ0_DCN_SURF0_TTU_CNTL1, REFCYC_PER_REQ_DELIVERY_PRE, mask_sh),\
374372 HUBP_SF(HUBP0_HUBP_CLK_CNTL, HUBP_CLOCK_ENABLE, mask_sh)
375373
374+#define HUBP_MASK_SH_LIST_DCN(mask_sh)\
375+ HUBP_MASK_SH_LIST_DCN_COMMON(mask_sh),\
376+ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG, MPTE_GROUP_SIZE, mask_sh),\
377+ HUBP_SF(HUBP0_DCHUBP_REQ_SIZE_CONFIG_C, MPTE_GROUP_SIZE_C, mask_sh)
378+
376379 /* Mask/shift struct generation macro for ASICs with VM */
377380 #define HUBP_MASK_SH_LIST_DCN_VM(mask_sh)\
378381 HUBP_SF(HUBPREQ0_NOM_PARAMETERS_0, DST_Y_PER_PTE_ROW_NOM_L, mask_sh),\
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c+18−2
@@ -521,8 +521,24 @@ static const struct dc_plane_cap plane_cap = { · 520 unmodified lines
521521 .blends_with_above = true,
522522 .blends_with_below = true,
523523 .per_pixel_alpha = true,
524− .supports_argb8888 = true,
525− .supports_nv12 = true
524+
525+ .pixel_format_support = {
526+ .argb8888 = true,
527+ .nv12 = true,
528+ .fp16 = true
529+ },
530+
531+ .max_upscale_factor = {
532+ .argb8888 = 16000,
533+ .nv12 = 16000,
534+ .fp16 = 1
535+ },
536+
537+ .max_downscale_factor = {
538+ .argb8888 = 250,
539+ .nv12 = 250,
540+ .fp16 = 1
541+ }
526542 };
527543
528544 static const struct dc_debug_options debug_defaults_drv = {
drivers/gpu/drm/amd/display/dc/inc/core_types.h+2−1
@@ -97,7 +97,8 @@ struct resource_funcs { · 96 unmodified lines
9797 const struct encoder_init_data *init);
9898 bool (*validate_bandwidth)(
9999 struct dc *dc,
100− struct dc_state *context);
100+ struct dc_state *context,
101+ bool fast_validate);
101102
102103 enum dc_status (*validate_global)(
103104 struct dc *dc,
drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h+2−1
@@ -621,7 +621,8 @@ extern const struct dcn_ip_params dcn10_ip_defaults; · 620 unmodified lines
621621
622622 bool dcn_validate_bandwidth(
623623 struct dc *dc,
624− struct dc_state *context);
624+ struct dc_state *context,
625+ bool fast_validate);
625626
626627 unsigned int dcn_find_dcfclk_suits_all(
627628 const struct dc *dc,
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h+4−0
@@ -540,6 +540,8 @@ struct smu_funcs · 539 unmodified lines
540540 int (*get_fan_speed_percent)(struct smu_context *smu, uint32_t *speed);
541541 int (*set_fan_speed_percent)(struct smu_context *smu, uint32_t speed);
542542 int (*set_fan_speed_rpm)(struct smu_context *smu, uint32_t speed);
543+ int (*set_xgmi_pstate)(struct smu_context *smu, uint32_t pstate);
544+
543545 };
544546
545547 #define smu_init_microcode(smu) \
@@ -723,6 +725,8 @@ struct smu_funcs · 177 unmodified lines
723725 ((smu)->funcs->get_sclk ? (smu)->funcs->get_sclk((smu), (low)) : 0)
724726 #define smu_get_mclk(smu, low) \
725727 ((smu)->funcs->get_mclk ? (smu)->funcs->get_mclk((smu), (low)) : 0)
728+#define smu_set_xgmi_pstate(smu, pstate) \
729+ ((smu)->funcs->set_xgmi_pstate ? (smu)->funcs->set_xgmi_pstate((smu), (pstate)) : 0)
726730
727731
728732 extern int smu_get_atom_data_table(struct smu_context *smu, uint32_t table,
drivers/gpu/drm/amd/powerplay/smu_v11_0.c+8−1
@@ -1893,6 +1893,13 @@ set_fan_speed_rpm_failed: · 1892 unmodified lines
18931893 return ret;
18941894 }
18951895
1896+static int smu_v11_0_set_xgmi_pstate(struct smu_context *smu,
1897+ uint32_t pstate)
1898+{
1899+ /* send msg to SMU to set pstate */
1900+ return 0;
1901+}
1902+
18961903 static const struct smu_funcs smu_v11_0_funcs = {
18971904 .init_microcode = smu_v11_0_init_microcode,
18981905 .load_microcode = smu_v11_0_load_microcode,
@@ -1947,6 +1954,7 @@ static const struct smu_funcs smu_v11_0_funcs = { · 48 unmodified lines
19471954 .get_fan_speed_percent = smu_v11_0_get_fan_speed_percent,
19481955 .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
19491956 .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
1957+ .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
19501958 };
19511959
19521960 void smu_v11_0_set_smu_funcs(struct smu_context *smu)
@@ -1954,7 +1962,6 @@ void smu_v11_0_set_smu_funcs(struct smu_context *smu) · 1 unmodified line
19541962 struct amdgpu_device *adev = smu->adev;
19551963
19561964 smu->funcs = &smu_v11_0_funcs;
1957−
19581965 switch (adev->asic_type) {
19591966 case CHIP_VEGA20:
19601967 vega20_set_ppt_funcs(smu);
include/uapi/drm/amdgpu_drm.h+8−0
@@ -528,6 +528,8 @@ struct drm_amdgpu_gem_va { · 527 unmodified lines
528528 #define AMDGPU_CHUNK_ID_SYNCOBJ_OUT 0x05
529529 #define AMDGPU_CHUNK_ID_BO_HANDLES 0x06
530530 #define AMDGPU_CHUNK_ID_SCHEDULED_DEPENDENCIES 0x07
531+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_WAIT 0x08
532+#define AMDGPU_CHUNK_ID_SYNCOBJ_TIMELINE_SIGNAL 0x09
531533
532534 struct drm_amdgpu_cs_chunk {
533535 __u32 chunk_id;
@@ -608,6 +610,12 @@ struct drm_amdgpu_cs_chunk_sem { · 74 unmodified lines
608610 __u32 handle;
609611 };
610612
613+struct drm_amdgpu_cs_chunk_syncobj {
614+ __u32 handle;
615+ __u32 flags;
616+ __u64 point;
617+};
618+
611619 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ 0
612620 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNCOBJ_FD 1
613621 #define AMDGPU_FENCE_TO_HANDLE_GET_SYNC_FILE_FD 2