Skip to content

Commit 9b1cbf8

Browse files
chadmedjannau
authored andcommitted
drm: apple: respect drm_plane_state zpos
The for_each_oldnew_plane_in_state iterator is nondeterministic in terms of the order of planes. DCP expects surfaces to be fed to it in the correct order. Relying on the iterator to lazily increment the index into surf[] means we cannot meet this expectation. The constant reordering of planes in the surf[] array seems to cause DCP to crash under certain circumstances. Cursors will also often be drawn under the main plane, which is less than ideal. Populate surf[] in the order everyone expects us to. This fixes a whole host of odd behaviour when wiring up multiple DRM universal planes. Signed-off-by: James Calligeros <[email protected]>
1 parent 86eac5a commit 9b1cbf8

1 file changed

Lines changed: 11 additions & 4 deletions

File tree

drivers/gpu/drm/apple/iomfb_template.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1295,8 +1295,6 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru
12951295
dcp->surfaces_cleared = true;
12961296
}
12971297

1298-
// Surface 0 has limitations at least on t600x.
1299-
l = 1;
13001298
for_each_oldnew_plane_in_state(state, plane, old_state, new_state, plane_idx) {
13011299
struct drm_framebuffer *fb = new_state->fb;
13021300
struct drm_gem_dma_object *obj;
@@ -1307,6 +1305,17 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru
13071305
if (old_state->crtc != crtc && new_state->crtc != crtc)
13081306
continue;
13091307

1308+
/*
1309+
* Plane order is nondeterministic for this iterator. DCP will
1310+
* almost always crash at some point if the z order of planes
1311+
* flip-flops around. Make sure we are always blending them
1312+
* in the correct order.
1313+
*
1314+
* Despite having 4 surfaces, we can only blend two. Surface 0 is
1315+
* also unusable on some machines, so ignore it.
1316+
*/
1317+
l = 2 - new_state->zpos;
1318+
13101319
WARN_ON(l >= SWAP_SURFACES);
13111320

13121321
req->swap.swap_enabled |= BIT(l);
@@ -1333,7 +1342,6 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru
13331342
}
13341343

13351344
if (!new_state->fb) {
1336-
l += 1;
13371345
continue;
13381346
}
13391347
req->surf_null[l] = false;
@@ -1383,7 +1391,6 @@ void DCP_FW_NAME(iomfb_flush)(struct apple_dcp *dcp, struct drm_crtc *crtc, stru
13831391
.has_planes = 1,
13841392
};
13851393

1386-
l += 1;
13871394
}
13881395

13891396
if (!has_surface && !crtc_state->color_mgmt_changed) {

0 commit comments

Comments
 (0)