diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 1208258ad3b2..63560eb2bffb 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -1130,7 +1130,7 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) struct drm_device *drm = dev_get_drvdata(master); struct vc4_crtc *vc4_crtc; struct drm_crtc *crtc; - struct drm_plane *primary_plane, *cursor_plane, *destroy_plane, *temp; + struct drm_plane *primary_plane, *destroy_plane, *temp; const struct of_device_id *match; int ret, i; @@ -1178,34 +1178,9 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) */ drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size); - /* 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 = drm_crtc_mask(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 = drm_crtc_mask(crtc); - crtc->cursor = cursor_plane; - } + ret = vc4_plane_create_additional_planes(drm, crtc); + if (ret) + goto err_destroy_planes; vc4_crtc_get_cob_allocation(vc4_crtc); diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index 6f50a91e3933..bb3416e7624a 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h @@ -846,6 +846,8 @@ int vc4_kms_load(struct drm_device *dev); /* vc4_plane.c */ struct drm_plane *vc4_plane_init(struct drm_device *dev, enum drm_plane_type type); +int vc4_plane_create_additional_planes(struct drm_device *dev, + struct drm_crtc *crtc); u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); u32 vc4_plane_dlist_size(const struct drm_plane_state *state); void vc4_plane_async_set_fb(struct drm_plane *plane, diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 91e408f7a56e..ea559b3288f5 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -1267,3 +1267,41 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, return plane; } + +int vc4_plane_create_additional_planes(struct drm_device *drm, + struct drm_crtc *crtc) +{ + struct drm_plane *cursor_plane; + unsigned int i; + + /* 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 = drm_crtc_mask(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 = drm_crtc_mask(crtc); + crtc->cursor = cursor_plane; + } + + return 0; +}