summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm2708/patches-4.4/0282-drm-vc4-Add-more-display-planes-to-each-CRTC.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0282-drm-vc4-Add-more-display-planes-to-each-CRTC.patch')
-rw-r--r--target/linux/brcm2708/patches-4.4/0282-drm-vc4-Add-more-display-planes-to-each-CRTC.patch106
1 files changed, 106 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0282-drm-vc4-Add-more-display-planes-to-each-CRTC.patch b/target/linux/brcm2708/patches-4.4/0282-drm-vc4-Add-more-display-planes-to-each-CRTC.patch
new file mode 100644
index 0000000000..34d6a18e40
--- /dev/null
+++ b/target/linux/brcm2708/patches-4.4/0282-drm-vc4-Add-more-display-planes-to-each-CRTC.patch
@@ -0,0 +1,106 @@
+From 5735ac96c821e3caf84de2d2358d0993130bc999 Mon Sep 17 00:00:00 2001
+From: Eric Anholt <eric@anholt.net>
+Date: Tue, 20 Oct 2015 14:18:56 +0100
+Subject: [PATCH 282/381] 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 <eric@anholt.net>
+(cherry picked from commit fc2d6f1eabee9d971453da2a27a72471c2a347dd)
+---
+ drivers/gpu/drm/vc4/vc4_crtc.c | 56 ++++++++++++++++++++++++++++++------------
+ 1 file changed, 40 insertions(+), 16 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c
+@@ -677,9 +677,9 @@ static int vc4_crtc_bind(struct device *
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+ struct vc4_crtc *vc4_crtc;
+ struct drm_crtc *crtc;
+- struct drm_plane *primary_plane, *cursor_plane;
++ struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp;
+ const struct of_device_id *match;
+- int ret;
++ int ret, i;
+
+ vc4_crtc = devm_kzalloc(dev, sizeof(*vc4_crtc), GFP_KERNEL);
+ if (!vc4_crtc)
+@@ -708,27 +708,49 @@ static int vc4_crtc_bind(struct device *
+ goto err;
+ }
+
+- cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
+- if (IS_ERR(cursor_plane)) {
+- dev_err(dev, "failed to construct cursor plane\n");
+- ret = PTR_ERR(cursor_plane);
+- goto err_primary;
+- }
+-
+- drm_crtc_init_with_planes(drm, crtc, primary_plane, cursor_plane,
++ drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
+ &vc4_crtc_funcs);
+ drm_crtc_helper_add(crtc, &vc4_crtc_helper_funcs);
+ primary_plane->crtc = crtc;
+- cursor_plane->crtc = crtc;
+ vc4->crtc[drm_crtc_index(crtc)] = vc4_crtc;
+ vc4_crtc->channel = vc4_crtc->data->hvs_channel;
+
++ /* Set up some arbitrary number of planes. We're not limited
++ * by a set number of physical registers, just the space in
++ * the HVS (16k) and how small an plane can be (28 bytes).
++ * However, each plane we set up takes up some memory, and
++ * increases the cost of looping over planes, which atomic
++ * modesetting does quite a bit. As a result, we pick a
++ * modest number of planes to expose, that should hopefully
++ * still cover any sane usecase.
++ */
++ for (i = 0; i < 8; i++) {
++ struct drm_plane *plane =
++ vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY);
++
++ if (IS_ERR(plane))
++ continue;
++
++ plane->possible_crtcs = 1 << drm_crtc_index(crtc);
++ }
++
++ /* Set up the legacy cursor after overlay initialization,
++ * since we overlay planes on the CRTC in the order they were
++ * initialized.
++ */
++ cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR);
++ if (!IS_ERR(cursor_plane)) {
++ cursor_plane->possible_crtcs = 1 << drm_crtc_index(crtc);
++ cursor_plane->crtc = crtc;
++ crtc->cursor = cursor_plane;
++ }
++
+ CRTC_WRITE(PV_INTEN, 0);
+ CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START);
+ ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
+ vc4_crtc_irq_handler, 0, "vc4 crtc", vc4_crtc);
+ if (ret)
+- goto err_cursor;
++ goto err_destroy_planes;
+
+ vc4_set_crtc_possible_masks(drm, crtc);
+
+@@ -736,10 +758,12 @@ static int vc4_crtc_bind(struct device *
+
+ return 0;
+
+-err_cursor:
+- cursor_plane->funcs->destroy(cursor_plane);
+-err_primary:
+- primary_plane->funcs->destroy(primary_plane);
++err_destroy_planes:
++ list_for_each_entry_safe(destroy_plane, temp,
++ &drm->mode_config.plane_list, head) {
++ if (destroy_plane->possible_crtcs == 1 << drm_crtc_index(crtc))
++ destroy_plane->funcs->destroy(destroy_plane);
++ }
+ err:
+ return ret;
+ }