diff --git a/drivers/gpu/drm/arc/arcpgu_crtc.c b/drivers/gpu/drm/arc/arcpgu_crtc.c index 1859dd3ad622db044ea51de19a50ee00b39441ae..799416651f2f0e10c307483c48460bbe07ce9f99 100644 --- a/drivers/gpu/drm/arc/arcpgu_crtc.c +++ b/drivers/gpu/drm/arc/arcpgu_crtc.c @@ -217,6 +217,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, &arc_pgu_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index 16e1e20cf04cf45ba5921715511d1babc9173c4a..72b22b805412b2cb19d8d90e85904be737ecf335 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -315,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs, formats, ARRAY_SIZE(formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { return ERR_PTR(ret); diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 600fa7bd7f5201b451069dee8f21e9871cae70e3..60402e27882fafd1650b44735341052f99e2ee7b 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -398,7 +398,7 @@ int malidp_de_planes_init(struct drm_device *drm) DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(drm, &plane->base, crtcs, &malidp_de_plane_funcs, formats, - n, plane_type, NULL); + n, NULL, plane_type, NULL); if (ret < 0) goto cleanup; diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 1ffba91fbaae361ea9c813363d0a666c134373ce..1d01ad24fe520d6c149c28511a6c8e7ec7910b81 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -1269,6 +1269,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, &armada_primary_plane_funcs, armada_primary_formats, ARRAY_SIZE(armada_primary_formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { kfree(primary); diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 677b44f3534b9442c8aa31b131adf0b8dc4f1502..edc44910d79fc7c65bce893d31b2caf9ce1d34e4 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -460,6 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) &armada_ovl_plane_funcs, armada_ovl_formats, ARRAY_SIZE(armada_ovl_formats), + NULL, DRM_PLANE_TYPE_OVERLAY, NULL); if (ret) { kfree(dplane); diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index b5bd9b0052257c89ae640aacefc908515ab38c63..ba532bf101e0bc59b539cc0ce8834128c213c9b3 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -1087,7 +1087,8 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev, ret = drm_universal_plane_init(dev, &plane->base, 0, &layer_plane_funcs, desc->formats->formats, - desc->formats->nformats, type, NULL); + desc->formats->nformats, + NULL, type, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c index 2b33825f2f93138066b3593289bd076ad9f43409..9cb1eede0b4d9444a40e9b575b0e0184f4d2c9a5 100644 --- a/drivers/gpu/drm/drm_modeset_helper.c +++ b/drivers/gpu/drm/drm_modeset_helper.c @@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev) &drm_primary_helper_funcs, safe_modeset_formats, ARRAY_SIZE(safe_modeset_formats), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { kfree(primary); diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index 5dc8c4350602a561fe4cfd77fce77e26770696fb..d3fc561d7b481446169d2ebe5f060963730d0296 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -70,6 +70,8 @@ static unsigned int drm_num_planes(struct drm_device *dev) * @funcs: callbacks for the new plane * @formats: array of supported formats (DRM_FORMAT\_\*) * @format_count: number of elements in @formats + * @format_modifiers: array of struct drm_format modifiers terminated by + * DRM_FORMAT_MOD_INVALID * @type: type of plane (overlay, primary, cursor) * @name: printf style format string for the plane name, or NULL for default name * @@ -82,10 +84,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, uint32_t possible_crtcs, const struct drm_plane_funcs *funcs, const uint32_t *formats, unsigned int format_count, + const uint64_t *format_modifiers, enum drm_plane_type type, const char *name, ...) { struct drm_mode_config *config = &dev->mode_config; + unsigned int format_modifier_count = 0; int ret; ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); @@ -105,6 +109,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, return -ENOMEM; } + /* + * First driver to need more than 64 formats needs to fix this. Each + * format is encoded as a bit and the current code only supports a u64. + */ + if (WARN_ON(format_count > 64)) + return -EINVAL; + + if (format_modifiers) { + const uint64_t *temp_modifiers = format_modifiers; + while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID) + format_modifier_count++; + } + + plane->modifier_count = format_modifier_count; + plane->modifiers = kmalloc_array(format_modifier_count, + sizeof(format_modifiers[0]), + GFP_KERNEL); + + if (format_modifier_count && !plane->modifiers) { + DRM_DEBUG_KMS("out of memory when allocating plane\n"); + kfree(plane->format_types); + drm_mode_object_unregister(dev, &plane->base); + return -ENOMEM; + } + if (name) { va_list ap; @@ -117,12 +146,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, } if (!plane->name) { kfree(plane->format_types); + kfree(plane->modifiers); drm_mode_object_unregister(dev, &plane->base); return -ENOMEM; } memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); plane->format_count = format_count; + memcpy(plane->modifiers, format_modifiers, + format_modifier_count * sizeof(format_modifiers[0])); plane->possible_crtcs = possible_crtcs; plane->type = type; @@ -205,7 +237,8 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, - formats, format_count, type, NULL); + formats, format_count, + NULL, type, NULL); } EXPORT_SYMBOL(drm_plane_init); @@ -224,6 +257,7 @@ void drm_plane_cleanup(struct drm_plane *plane) drm_modeset_lock_fini(&plane->mutex); kfree(plane->format_types); + kfree(plane->modifiers); drm_mode_object_unregister(dev, &plane->base); BUG_ON(list_empty(&plane->head)); diff --git a/drivers/gpu/drm/drm_simple_kms_helper.c b/drivers/gpu/drm/drm_simple_kms_helper.c index 39c203ad59db81731b21064ecc571caf520d6e02..dc9fd109de14f00db553b4b02a6bd882f08a94aa 100644 --- a/drivers/gpu/drm/drm_simple_kms_helper.c +++ b/drivers/gpu/drm/drm_simple_kms_helper.c @@ -199,6 +199,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge); * @funcs: callbacks for the display pipe (optional) * @formats: array of supported formats (DRM_FORMAT\_\*) * @format_count: number of elements in @formats + * @format_modifiers: array of formats modifiers * @connector: connector to attach and register (optional) * * Sets up a display pipeline which consist of a really simple @@ -219,6 +220,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev, struct drm_simple_display_pipe *pipe, const struct drm_simple_display_pipe_funcs *funcs, const uint32_t *formats, unsigned int format_count, + const uint64_t *format_modifiers, struct drm_connector *connector) { struct drm_encoder *encoder = &pipe->encoder; @@ -233,6 +235,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev, ret = drm_universal_plane_init(dev, plane, 0, &drm_simple_kms_plane_funcs, formats, format_count, + format_modifiers, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) return ret; diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 611b6fd65433d0a29a77c8549dcca47c0e4979a9..e5099bc9f21a0fcf23b57ded2671bdc40ec3ad9b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -283,7 +283,7 @@ int exynos_plane_init(struct drm_device *dev, &exynos_plane_funcs, config->pixel_formats, config->num_pixel_formats, - config->type, NULL); + NULL, config->type, NULL); if (err) { DRM_ERROR("failed to initialize plane\n"); return err; diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c index 0a20723aa6e17194b08940beef9c211299a30455..9554b245746ebaef31d698c702903e7c40980289 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c @@ -224,7 +224,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev) &fsl_dcu_drm_plane_funcs, fsl_dcu_drm_plane_formats, ARRAY_SIZE(fsl_dcu_drm_plane_formats), - DRM_PLANE_TYPE_PRIMARY, NULL); + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { kfree(primary); primary = NULL; diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index 54a4542a40f111a5b4ae7bc2168e9482037309ed..bec0a8726c6baac4add6dfb11a9436f6fe5afa90 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -181,6 +181,7 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv) ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs, channel_formats1, ARRAY_SIZE(channel_formats1), + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index 706efd0c41902efcb071f0777c0c52c623fef09d..9882ebd8751c833704de75bb5d3ffdefde230453 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -910,7 +910,7 @@ static int ade_plane_init(struct drm_device *dev, struct ade_plane *aplane, return ret; ret = drm_universal_plane_init(dev, &aplane->base, 1, &ade_plane_funcs, - fmts, fmts_cnt, type, NULL); + fmts, fmts_cnt, NULL, type, NULL); if (ret) { DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch); return ret; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e92fd14c06c711dc3bf6ace69f95f5dd986bac10..8998d6a2728812e280b800ef58b9f0706c670a66 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13809,18 +13809,21 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, 0, &intel_plane_funcs, intel_primary_formats, num_formats, + NULL, DRM_PLANE_TYPE_PRIMARY, "plane 1%c", pipe_name(pipe)); else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, 0, &intel_plane_funcs, intel_primary_formats, num_formats, + NULL, DRM_PLANE_TYPE_PRIMARY, "primary %c", pipe_name(pipe)); else ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, 0, &intel_plane_funcs, intel_primary_formats, num_formats, + NULL, DRM_PLANE_TYPE_PRIMARY, "plane %c", plane_name(primary->plane)); if (ret) @@ -13906,7 +13909,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, 0, &intel_cursor_plane_funcs, intel_cursor_formats, ARRAY_SIZE(intel_cursor_formats), - DRM_PLANE_TYPE_CURSOR, + NULL, DRM_PLANE_TYPE_CURSOR, "cursor %c", pipe_name(pipe)); if (ret) goto fail; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 94f9a1332dbf6e636d268964787a6195a879fa5d..4c6b387fa9dc8e7e3b83e74548804ec6bc262b6a 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1171,13 +1171,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, possible_crtcs, &intel_plane_funcs, plane_formats, num_plane_formats, - DRM_PLANE_TYPE_OVERLAY, + NULL, DRM_PLANE_TYPE_OVERLAY, "plane %d%c", plane + 2, pipe_name(pipe)); else ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, possible_crtcs, &intel_plane_funcs, plane_formats, num_plane_formats, - DRM_PLANE_TYPE_OVERLAY, + NULL, DRM_PLANE_TYPE_OVERLAY, "sprite %c", sprite_name(pipe, plane)); if (ret) goto fail; diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 0847cc0d96a4b98c0885c0cd3b0873bc3fd9f872..debde2dae7bf920ed6c24a79e65bee58a727312b 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -718,8 +718,8 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs, &ipu_plane_funcs, ipu_plane_formats, - ARRAY_SIZE(ipu_plane_formats), type, - NULL); + ARRAY_SIZE(ipu_plane_formats), + NULL, type, NULL); if (ret) { DRM_ERROR("failed to initialize plane\n"); kfree(ipu_plane); diff --git a/drivers/gpu/drm/mediatek/mtk_drm_plane.c b/drivers/gpu/drm/mediatek/mtk_drm_plane.c index 1a59b9ab4aa817701938235dd9ac397d75206098..6f121891430fadad9ed1086e82e61cfa4dc92271 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_plane.c @@ -175,7 +175,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, err = drm_universal_plane_init(dev, plane, possible_crtcs, &mtk_plane_funcs, formats, - ARRAY_SIZE(formats), type, NULL); + ARRAY_SIZE(formats), NULL, type, NULL); if (err) { DRM_ERROR("failed to initialize plane\n"); return err; diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c index a32d3b6e2e12e482f16d4f23eedea11cb8f5da18..17e96fa4786854e2001a9c8553c0500127db403b 100644 --- a/drivers/gpu/drm/meson/meson_plane.c +++ b/drivers/gpu/drm/meson/meson_plane.c @@ -223,6 +223,7 @@ int meson_plane_create(struct meson_drm *priv) &meson_plane_funcs, supported_drm_formats, ARRAY_SIZE(supported_drm_formats), + NULL, DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); drm_plane_helper_add(plane, &meson_plane_helper_funcs); diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index a20e3d644523572193893a2f26d19c19d2308590..7a1ad3af08e330c08519f287b600fa425a9b1780 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c @@ -401,7 +401,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, mdp4_plane->formats, mdp4_plane->nformats, - type, NULL); + NULL, type, NULL); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index fe3a4de1a4331ff86f0b4f0cc85a48b208bca3b5..61dfea791f3f90ef7a1de1ebf3a5d852cb4a0855 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -1139,12 +1139,12 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_cursor_plane_funcs, mdp5_plane->formats, mdp5_plane->nformats, - type, NULL); + NULL, type, NULL); else ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, mdp5_plane->formats, mdp5_plane->nformats, - type, NULL); + NULL, type, NULL); if (ret) goto fail; diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index a34f41ce3599338b9df7739977b7f917e52a9d52..93c38eb6d1879e24cff07435a822ca29a8b6fa40 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -190,7 +190,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags) } ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs, - mxsfb_formats, ARRAY_SIZE(mxsfb_formats), + mxsfb_formats, ARRAY_SIZE(mxsfb_formats), NULL, &mxsfb->connector); if (ret < 0) { dev_err(drm->dev, "Cannot setup simple display pipe\n"); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 7abfb561b00cc06665c6618aff1da7938acead79..bd1199b67eb4d19cd88b6053aa2b9a970cfbeacf 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1083,8 +1083,9 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev, wndw->func = func; wndw->dmac = dmac; - ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, format, - nformat, type, "%s-%d", name, index); + ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, + format, nformat, NULL, + type, "%s-%d", name, index); if (ret) return ret; diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 2160f64548e03bc028c6f7d9dd36d1aee5ae5745..b92a8f1d01550a70099d822dad285d07a3c5b0e6 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -291,7 +291,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, ret = drm_universal_plane_init(dev, plane, possible_crtcs, &omap_plane_funcs, formats, - nformats, type, NULL); + nformats, NULL, type, NULL); if (ret < 0) goto error; diff --git a/drivers/gpu/drm/pl111/pl111_display.c b/drivers/gpu/drm/pl111/pl111_display.c index c6ca4f1bbd495bdcf34398d7cdae613ac58d4d81..f0139fa58d5593b770b7bcc4a886530e6d40d569 100644 --- a/drivers/gpu/drm/pl111/pl111_display.c +++ b/drivers/gpu/drm/pl111/pl111_display.c @@ -457,7 +457,7 @@ int pl111_display_init(struct drm_device *drm) ret = drm_simple_display_pipe_init(drm, &priv->pipe, &pl111_display_funcs, formats, ARRAY_SIZE(formats), - &priv->connector.connector); + NULL, &priv->connector.connector); if (ret) return ret; diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 5eeae89c138d9037be4214cf841177a04db59442..14c5613b4388a839461915fc448d4772422861a3 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -784,7 +784,7 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev, err = drm_universal_plane_init(&qdev->ddev, plane, possible_crtcs, funcs, formats, num_formats, - type, NULL); + NULL, type, NULL); if (err) goto free_plane; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c index dcde6288da6c9dabf4a340c9802c842b2e5f2d28..2b02eccbfb709f97f1a3b59c7ae10a445cc07d7e 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c @@ -743,8 +743,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp) ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, &rcar_du_plane_funcs, formats, - ARRAY_SIZE(formats), type, - NULL); + ARRAY_SIZE(formats), + NULL, type, NULL); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index f870445ebc8df025b0ff9b37696d95552b9e1353..7362d80d236b8af4892ad240a21984908af1a8ba 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c @@ -439,8 +439,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp) 1 << vsp->index, &rcar_du_vsp_plane_funcs, formats_kms, - ARRAY_SIZE(formats_kms), type, - NULL); + ARRAY_SIZE(formats_kms), + NULL, type, NULL); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index ee4a12da78ab4edad618f270c3b27acfb0fa41e8..ab18659e2a6fc4285208a79694ff92813406cbe2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1288,7 +1288,7 @@ static int vop_create_crtc(struct vop *vop) 0, &vop_plane_funcs, win_data->phy->data_formats, win_data->phy->nformats, - win_data->type, NULL); + NULL, win_data->type, NULL); if (ret) { DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n", ret); @@ -1327,7 +1327,7 @@ static int vop_create_crtc(struct vop *vop) &vop_plane_funcs, win_data->phy->data_formats, win_data->phy->nformats, - win_data->type, NULL); + NULL, win_data->type, NULL); if (ret) { DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n", ret); diff --git a/drivers/gpu/drm/sti/sti_cursor.c b/drivers/gpu/drm/sti/sti_cursor.c index 5b3a41f74f21b2da5d130ffba0d8d947d9b44de8..f31cbe898eb33884510566936c09503694aa7ec8 100644 --- a/drivers/gpu/drm/sti/sti_cursor.c +++ b/drivers/gpu/drm/sti/sti_cursor.c @@ -392,7 +392,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev, &sti_cursor_plane_helpers_funcs, cursor_supported_formats, ARRAY_SIZE(cursor_supported_formats), - DRM_PLANE_TYPE_CURSOR, NULL); + NULL, DRM_PLANE_TYPE_CURSOR, NULL); if (res) { DRM_ERROR("Failed to initialize universal plane\n"); goto err_plane; diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c index 5ee0503945c8bfb3a7224aa509e4fba4af2a2751..dceedbe702d77eb0884f821161f96cf9c8b30cf4 100644 --- a/drivers/gpu/drm/sti/sti_gdp.c +++ b/drivers/gpu/drm/sti/sti_gdp.c @@ -931,7 +931,7 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev, &sti_gdp_plane_helpers_funcs, gdp_supported_formats, ARRAY_SIZE(gdp_supported_formats), - type, NULL); + NULL, type, NULL); if (res) { DRM_ERROR("Failed to initialize universal plane\n"); goto err; diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index 53a46dda8bd5ed3722d512b820b2760fe8c9faa7..f112308531162c476b3cf7d384ba0bd13dadfe0e 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c @@ -1298,7 +1298,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev, &sti_hqvdp_plane_helpers_funcs, hqvdp_supported_formats, ARRAY_SIZE(hqvdp_supported_formats), - DRM_PLANE_TYPE_OVERLAY, NULL); + NULL, DRM_PLANE_TYPE_OVERLAY, NULL); if (res) { DRM_ERROR("Failed to initialize universal plane\n"); return NULL; diff --git a/drivers/gpu/drm/stm/ltdc.c b/drivers/gpu/drm/stm/ltdc.c index 04cc66d6b96f1e4d49d6dc229b8f7404b0801b02..ae9eb0fff06bc5a7603806456c5c9d90a8b70557 100644 --- a/drivers/gpu/drm/stm/ltdc.c +++ b/drivers/gpu/drm/stm/ltdc.c @@ -735,7 +735,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, ret = drm_universal_plane_init(ddev, plane, possible_crtcs, <dc_plane_funcs, formats, nb_fmt, - type, NULL); + NULL, type, NULL); if (ret < 0) return 0; diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index ead4f9d4c1eeddf580bde0beadcd0c7e7a480dc7..d45f3a1a0a29d6ddfcd9f497c0e50e9484236d24 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -115,7 +115,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, ret = drm_universal_plane_init(drm, &layer->plane, 0, &sun4i_backend_layer_funcs, plane->formats, plane->nformats, - plane->type, NULL); + NULL, plane->type, NULL); if (ret) { dev_err(drm->dev, "Couldn't initialize layer\n"); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/sun4i/sun8i_layer.c b/drivers/gpu/drm/sun4i/sun8i_layer.c index e627eeece65890176468dccfe0b390d7469cf878..23810ff7268412a87edb449a6ac6e559ce5f0cb3 100644 --- a/drivers/gpu/drm/sun4i/sun8i_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_layer.c @@ -90,7 +90,7 @@ static struct sun8i_layer *sun8i_layer_init_one(struct drm_device *drm, ret = drm_universal_plane_init(drm, &layer->plane, 0, &sun8i_mixer_layer_funcs, plane->formats, plane->nformats, - plane->type, NULL); + NULL, plane->type, NULL); if (ret) { dev_err(drm->dev, "Couldn't initialize layer\n"); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 0cb9b90e2e68dd4dd7a1aecbafe2f88c0ab404fd..4df39112e38ec6052beb2165e0550594922174f6 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -678,8 +678,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, possible_crtcs, &tegra_primary_plane_funcs, formats, - num_formats, DRM_PLANE_TYPE_PRIMARY, - NULL); + num_formats, NULL, + DRM_PLANE_TYPE_PRIMARY, NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); @@ -844,8 +844,8 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, &tegra_cursor_plane_funcs, formats, - num_formats, DRM_PLANE_TYPE_CURSOR, - NULL); + num_formats, NULL, + DRM_PLANE_TYPE_CURSOR, NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); @@ -906,8 +906,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe, &tegra_overlay_plane_funcs, formats, - num_formats, DRM_PLANE_TYPE_OVERLAY, - NULL); + num_formats, NULL, + DRM_PLANE_TYPE_OVERLAY, NULL); if (err < 0) { kfree(plane); return ERR_PTR(err); diff --git a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c index ec43fb7ad9e46889b129eb14fd3b1c0c9489317d..26823a4a07d89eaf7a08e5db889311b63a119fa4 100644 --- a/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c +++ b/drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c @@ -225,7 +225,7 @@ tinydrm_display_pipe_init(struct tinydrm_device *tdev, return PTR_ERR(connector); ret = drm_simple_display_pipe_init(drm, &tdev->pipe, funcs, formats, - format_count, connector); + format_count, NULL, connector); if (ret) return ret; diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 8853e9a4f00549ef116fffd618691d178cc16a0f..2968b3ebb895714cb8c8faeaf40dff1c996f2259 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -902,7 +902,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, ret = drm_universal_plane_init(dev, plane, 0, &vc4_plane_funcs, formats, num_formats, - type, NULL); + NULL, type, NULL); drm_plane_helper_add(plane, &vc4_plane_helper_funcs); diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index adcdbd0abef692d46bf574dcf1c5c130b3510e4d..71ba455af915b78298662ee5daf588bd554984b0 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -298,7 +298,7 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, ret = drm_universal_plane_init(dev, plane, 1 << index, &virtio_gpu_plane_funcs, formats, nformats, - type, NULL); + NULL, type, NULL); if (ret) goto err_plane_init; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index 6391069498d6da30409c1269ea77c89eb5767589..b8a09807c5de8ebd447af97a56465323672d33d2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -428,7 +428,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) 0, &vmw_ldu_plane_funcs, vmw_primary_plane_formats, ARRAY_SIZE(vmw_primary_plane_formats), - DRM_PLANE_TYPE_PRIMARY, NULL); + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { DRM_ERROR("Failed to initialize primary plane"); goto err_free; @@ -443,7 +443,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) 0, &vmw_ldu_cursor_funcs, vmw_cursor_plane_formats, ARRAY_SIZE(vmw_cursor_plane_formats), - DRM_PLANE_TYPE_CURSOR, NULL); + NULL, DRM_PLANE_TYPE_CURSOR, NULL); if (ret) { DRM_ERROR("Failed to initialize cursor plane"); drm_plane_cleanup(&ldu->base.primary); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 854403509216808a32a96d93eb381765e39a7abc..d1552d3e0652b61a3859ef65a59a12ec501ea1e9 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -624,7 +624,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) 0, &vmw_sou_plane_funcs, vmw_primary_plane_formats, ARRAY_SIZE(vmw_primary_plane_formats), - DRM_PLANE_TYPE_PRIMARY, NULL); + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { DRM_ERROR("Failed to initialize primary plane"); goto err_free; @@ -639,7 +639,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) 0, &vmw_sou_cursor_funcs, vmw_cursor_plane_formats, ARRAY_SIZE(vmw_cursor_plane_formats), - DRM_PLANE_TYPE_CURSOR, NULL); + NULL, DRM_PLANE_TYPE_CURSOR, NULL); if (ret) { DRM_ERROR("Failed to initialize cursor plane"); drm_plane_cleanup(&sou->base.primary); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index ed9404a7f457c671df4df287475566e029699df7..c4de4ad0543b729fc180adf660f0ddbc7490e4d0 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -1475,7 +1475,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) 0, &vmw_stdu_plane_funcs, vmw_primary_plane_formats, ARRAY_SIZE(vmw_primary_plane_formats), - DRM_PLANE_TYPE_PRIMARY, NULL); + NULL, DRM_PLANE_TYPE_PRIMARY, NULL); if (ret) { DRM_ERROR("Failed to initialize primary plane"); goto err_free; @@ -1490,7 +1490,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) 0, &vmw_stdu_cursor_funcs, vmw_cursor_plane_formats, ARRAY_SIZE(vmw_cursor_plane_formats), - DRM_PLANE_TYPE_CURSOR, NULL); + NULL, DRM_PLANE_TYPE_CURSOR, NULL); if (ret) { DRM_ERROR("Failed to initialize cursor plane"); drm_plane_cleanup(&stdu->base.primary); diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c index 4a6252720c10a16cbf686ff52fd5ca112d55063a..18e7634932649783695a0aba16d7fd494648b053 100644 --- a/drivers/gpu/drm/zte/zx_plane.c +++ b/drivers/gpu/drm/zte/zx_plane.c @@ -540,7 +540,7 @@ int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane, ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK, &zx_plane_funcs, formats, format_count, - type, NULL); + NULL, type, NULL); if (ret) { DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret); return ret; diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h index 9ab3e70448127902aad5414f7fe1e109ed298e21..9d2cc3b11ae71df50d6dc772ee38044fd446b3bf 100644 --- a/include/drm/drm_plane.h +++ b/include/drm/drm_plane.h @@ -392,6 +392,22 @@ struct drm_plane_funcs { */ void (*atomic_print_state)(struct drm_printer *p, const struct drm_plane_state *state); + + /** + * @format_mod_supported: + * + * This optional hook is used for the DRM to determine if the given + * format/modifier combination is valid for the plane. This allows the + * DRM to generate the correct format bitmask (which formats apply to + * which modifier). + * + * Returns: + * + * True if the given modifier is valid for that format on the plane. + * False otherwise. + */ + bool (*format_mod_supported)(struct drm_plane *plane, uint32_t format, + uint64_t modifier); }; /** @@ -487,6 +503,9 @@ struct drm_plane { unsigned int format_count; bool format_default; + uint64_t *modifiers; + unsigned int modifier_count; + struct drm_crtc *crtc; struct drm_framebuffer *fb; @@ -527,13 +546,14 @@ struct drm_plane { #define obj_to_plane(x) container_of(x, struct drm_plane, base) -__printf(8, 9) +__printf(9, 10) int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, uint32_t possible_crtcs, const struct drm_plane_funcs *funcs, const uint32_t *formats, unsigned int format_count, + const uint64_t *format_modifiers, enum drm_plane_type type, const char *name, ...); int drm_plane_init(struct drm_device *dev, diff --git a/include/drm/drm_simple_kms_helper.h b/include/drm/drm_simple_kms_helper.h index 2d36538e4a17ebdabe7fa9e20de25fb8cf952dbe..6d9adbb46293310cb09780ec509f048b94642a41 100644 --- a/include/drm/drm_simple_kms_helper.h +++ b/include/drm/drm_simple_kms_helper.h @@ -122,6 +122,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev, struct drm_simple_display_pipe *pipe, const struct drm_simple_display_pipe_funcs *funcs, const uint32_t *formats, unsigned int format_count, + const uint64_t *format_modifiers, struct drm_connector *connector); #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index 7586c46f68bf22f48a1536c0f27eed0d8d06eb92..76c9101a7fc60993ee7187c1a62a6f7c9248cf0d 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -185,6 +185,8 @@ extern "C" { #define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 /* add more to the end as needed */ +#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) + #define fourcc_mod_code(vendor, val) \ ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) @@ -196,6 +198,15 @@ extern "C" { * authoritative source for all of these. */ +/* + * Invalid Modifier + * + * This modifier can be used as a sentinel to terminate the format modifiers + * list, or to initialize a variable with an invalid modifier. It might also be + * used to report an error back to userspace for certain APIs. + */ +#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED) + /* * Linear Layout *