diff options
Diffstat (limited to 'target/linux/brcm2708/patches-4.4/0283-drm-vc4-Add-more-display-planes-to-each-CRTC.patch')
-rw-r--r-- | target/linux/brcm2708/patches-4.4/0283-drm-vc4-Add-more-display-planes-to-each-CRTC.patch | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/target/linux/brcm2708/patches-4.4/0283-drm-vc4-Add-more-display-planes-to-each-CRTC.patch b/target/linux/brcm2708/patches-4.4/0283-drm-vc4-Add-more-display-planes-to-each-CRTC.patch new file mode 100644 index 0000000000..89800e7ae1 --- /dev/null +++ b/target/linux/brcm2708/patches-4.4/0283-drm-vc4-Add-more-display-planes-to-each-CRTC.patch @@ -0,0 +1,106 @@ +From 340763d1863fe246b44405edeba01889c81e5cb7 Mon Sep 17 00:00:00 2001 +From: Eric Anholt <eric@anholt.net> +Date: Tue, 20 Oct 2015 14:18:56 +0100 +Subject: [PATCH 283/304] 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; + } |