Skip to content

Commit fc2d6f1

Browse files
committed
drm/vc4: Add more display planes to each CRTC.
Previously we only did the primary and cursor plane, but overlay planes are useful and just require this setup to add, since all planes go into the HVS display list in the same way. Signed-off-by: Eric Anholt <[email protected]>
1 parent d8dbf44 commit fc2d6f1

File tree

1 file changed

+40
-16
lines changed

1 file changed

+40
-16
lines changed

drivers/gpu/drm/vc4/vc4_crtc.c

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -657,9 +657,9 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
657657
struct vc4_dev *vc4 = to_vc4_dev(drm);
658658
struct vc4_crtc *vc4_crtc;
659659
struct drm_crtc *crtc;
660-
struct drm_plane *primary_plane, *cursor_plane;
660+
struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp;
661661
const struct of_device_id *match;
662-
int ret;
662+
int ret, i;
663663

664664
vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
665665
if (!vc4_crtc)
@@ -688,38 +688,62 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data)
688688
goto err;
689689
}
690690

691-
cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
692-
if (IS_ERR(cursor_plane)) {
693-
dev_err(dev, "failed to construct cursor plane\n");
694-
ret = PTR_ERR(cursor_plane);
695-
goto err_primary;
696-
}
697-
698-
drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
691+
drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
699692
&vc4_crtc_funcs, NULL);
700693
drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
701694
primary_plane->crtc = crtc;
702-
cursor_plane->crtc = crtc;
703695
vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
704696
vc4_crtc->channel = vc4_crtc->data->hvs_channel;
705697

698+
/* Set up some arbitrary number of planes. We're not limited
699+
* by a set number of physical registers, just the space in
700+
* the HVS (16k) and how small an plane can be (28 bytes).
701+
* However, each plane we set up takes up some memory, and
702+
* increases the cost of looping over planes, which atomic
703+
* modesetting does quite a bit. As a result, we pick a
704+
* modest number of planes to expose, that should hopefully
705+
* still cover any sane usecase.
706+
*/
707+
for (i = 0; i < 8; i++) {
708+
struct drm_plane *plane =
709+
vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY);
710+
711+
if (IS_ERR(plane))
712+
continue;
713+
714+
plane->possible_crtcs = 1 << drm_crtc_index(crtc);
715+
}
716+
717+
/* Set up the legacy cursor after overlay initialization,
718+
* since we overlay planes on the CRTC in the order they were
719+
* initialized.
720+
*/
721+
cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
722+
if (!IS_ERR(cursor_plane)) {
723+
cursor_plane->possible_crtcs = 1 << drm_crtc_index(crtc);
724+
cursor_plane->crtc = crtc;
725+
crtc->cursor = cursor_plane;
726+
}
727+
706728
CRTC_WRITE(PV_INTEN, 0);
707729
CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
708730
ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
709731
vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
710732
if (ret)
711-
goto err_cursor;
733+
goto err_destroy_planes;
712734

713735
vc4_set_crtc_possible_masks(drm, crtc);
714736

715737
platform_set_drvdata(pdev, vc4_crtc);
716738

717739
return 0;
718740

719-
err_cursor:
720-
cursor_plane->funcs->destroy(cursor_plane);
721-
err_primary:
722-
primary_plane->funcs->destroy(primary_plane);
741+
err_destroy_planes:
742+
list_for_each_entry_safe(destroy_plane, temp,
743+
&drm->mode_config.plane_list, head) {
744+
if (destroy_plane->possible_crtcs == 1 << drm_crtc_index(crtc))
745+
destroy_plane->funcs->destroy(destroy_plane);
746+
}
723747
err:
724748
return ret;
725749
}

0 commit comments

Comments
 (0)