提交 e6fc3b68 编写于 作者: B Ben Widawsky 提交者: Daniel Stone

drm: Plumb modifiers through plane init

This is the plumbing for supporting fb modifiers on planes. Modifiers
have already been introduced to some extent, but this series will extend
this to allow querying modifiers per plane. Based on this, the client to
enable optimal modifications for framebuffers.

This patch simply allows the DRM drivers to initialize their list of
supported modifiers upon initializing the plane.

v2: A minor addition from Daniel

v3:
* Updated commit message
* s/INVALID/DRM_FORMAT_MOD_INVALID (Liviu)
* Remove some excess newlines (Liviu)
* Update comment for > 64 modifiers (Liviu)

v4: Minor comment adjustments (Liviu)

v5: Some new platforms added due to rebase

v6: Add some missed plane inits (or maybe they're new - who knows at
this point) (Daniel)
Signed-off-by: NBen Widawsky <ben@bwidawsk.net>
Reviewed-by: Daniel Stone <daniels@collabora.com> (v2)
Reviewed-by: NLiviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: NDaniel Stone <daniels@collabora.com>
上级 d7429669
...@@ -217,6 +217,7 @@ static struct drm_plane *arc_pgu_plane_init(struct drm_device *drm) ...@@ -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, ret = drm_universal_plane_init(drm, plane, 0xff, &arc_pgu_plane_funcs,
formats, ARRAY_SIZE(formats), formats, ARRAY_SIZE(formats),
NULL,
DRM_PLANE_TYPE_PRIMARY, NULL); DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) if (ret)
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -315,6 +315,7 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ...@@ -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, ret = drm_universal_plane_init(drm, plane, 0xff, &hdlcd_plane_funcs,
formats, ARRAY_SIZE(formats), formats, ARRAY_SIZE(formats),
NULL,
DRM_PLANE_TYPE_PRIMARY, NULL); DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) { if (ret) {
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -398,7 +398,7 @@ int malidp_de_planes_init(struct drm_device *drm) ...@@ -398,7 +398,7 @@ int malidp_de_planes_init(struct drm_device *drm)
DRM_PLANE_TYPE_OVERLAY; DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(drm, &plane->base, crtcs, ret = drm_universal_plane_init(drm, &plane->base, crtcs,
&malidp_de_plane_funcs, formats, &malidp_de_plane_funcs, formats,
n, plane_type, NULL); n, NULL, plane_type, NULL);
if (ret < 0) if (ret < 0)
goto cleanup; goto cleanup;
......
...@@ -1269,6 +1269,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, ...@@ -1269,6 +1269,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev,
&armada_primary_plane_funcs, &armada_primary_plane_funcs,
armada_primary_formats, armada_primary_formats,
ARRAY_SIZE(armada_primary_formats), ARRAY_SIZE(armada_primary_formats),
NULL,
DRM_PLANE_TYPE_PRIMARY, NULL); DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) { if (ret) {
kfree(primary); kfree(primary);
......
...@@ -460,6 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) ...@@ -460,6 +460,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs)
&armada_ovl_plane_funcs, &armada_ovl_plane_funcs,
armada_ovl_formats, armada_ovl_formats,
ARRAY_SIZE(armada_ovl_formats), ARRAY_SIZE(armada_ovl_formats),
NULL,
DRM_PLANE_TYPE_OVERLAY, NULL); DRM_PLANE_TYPE_OVERLAY, NULL);
if (ret) { if (ret) {
kfree(dplane); kfree(dplane);
......
...@@ -1087,7 +1087,8 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev, ...@@ -1087,7 +1087,8 @@ static int atmel_hlcdc_plane_create(struct drm_device *dev,
ret = drm_universal_plane_init(dev, &plane->base, 0, ret = drm_universal_plane_init(dev, &plane->base, 0,
&layer_plane_funcs, &layer_plane_funcs,
desc->formats->formats, desc->formats->formats,
desc->formats->nformats, type, NULL); desc->formats->nformats,
NULL, type, NULL);
if (ret) if (ret)
return ret; return ret;
......
...@@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev) ...@@ -124,6 +124,7 @@ static struct drm_plane *create_primary_plane(struct drm_device *dev)
&drm_primary_helper_funcs, &drm_primary_helper_funcs,
safe_modeset_formats, safe_modeset_formats,
ARRAY_SIZE(safe_modeset_formats), ARRAY_SIZE(safe_modeset_formats),
NULL,
DRM_PLANE_TYPE_PRIMARY, NULL); DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) { if (ret) {
kfree(primary); kfree(primary);
......
...@@ -70,6 +70,8 @@ static unsigned int drm_num_planes(struct drm_device *dev) ...@@ -70,6 +70,8 @@ static unsigned int drm_num_planes(struct drm_device *dev)
* @funcs: callbacks for the new plane * @funcs: callbacks for the new plane
* @formats: array of supported formats (DRM_FORMAT\_\*) * @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats * @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) * @type: type of plane (overlay, primary, cursor)
* @name: printf style format string for the plane name, or NULL for default name * @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, ...@@ -82,10 +84,12 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
uint32_t possible_crtcs, uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs, const struct drm_plane_funcs *funcs,
const uint32_t *formats, unsigned int format_count, const uint32_t *formats, unsigned int format_count,
const uint64_t *format_modifiers,
enum drm_plane_type type, enum drm_plane_type type,
const char *name, ...) const char *name, ...)
{ {
struct drm_mode_config *config = &dev->mode_config; struct drm_mode_config *config = &dev->mode_config;
unsigned int format_modifier_count = 0;
int ret; int ret;
ret = drm_mode_object_add(dev, &plane->base, DRM_MODE_OBJECT_PLANE); 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, ...@@ -105,6 +109,31 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
return -ENOMEM; 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) { if (name) {
va_list ap; va_list ap;
...@@ -117,12 +146,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, ...@@ -117,12 +146,15 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
} }
if (!plane->name) { if (!plane->name) {
kfree(plane->format_types); kfree(plane->format_types);
kfree(plane->modifiers);
drm_mode_object_unregister(dev, &plane->base); drm_mode_object_unregister(dev, &plane->base);
return -ENOMEM; return -ENOMEM;
} }
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
plane->format_count = format_count; plane->format_count = format_count;
memcpy(plane->modifiers, format_modifiers,
format_modifier_count * sizeof(format_modifiers[0]));
plane->possible_crtcs = possible_crtcs; plane->possible_crtcs = possible_crtcs;
plane->type = type; plane->type = type;
...@@ -205,7 +237,8 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, ...@@ -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; type = is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
return drm_universal_plane_init(dev, plane, possible_crtcs, funcs, 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); EXPORT_SYMBOL(drm_plane_init);
...@@ -224,6 +257,7 @@ void drm_plane_cleanup(struct drm_plane *plane) ...@@ -224,6 +257,7 @@ void drm_plane_cleanup(struct drm_plane *plane)
drm_modeset_lock_fini(&plane->mutex); drm_modeset_lock_fini(&plane->mutex);
kfree(plane->format_types); kfree(plane->format_types);
kfree(plane->modifiers);
drm_mode_object_unregister(dev, &plane->base); drm_mode_object_unregister(dev, &plane->base);
BUG_ON(list_empty(&plane->head)); BUG_ON(list_empty(&plane->head));
......
...@@ -199,6 +199,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge); ...@@ -199,6 +199,7 @@ EXPORT_SYMBOL(drm_simple_display_pipe_attach_bridge);
* @funcs: callbacks for the display pipe (optional) * @funcs: callbacks for the display pipe (optional)
* @formats: array of supported formats (DRM_FORMAT\_\*) * @formats: array of supported formats (DRM_FORMAT\_\*)
* @format_count: number of elements in @formats * @format_count: number of elements in @formats
* @format_modifiers: array of formats modifiers
* @connector: connector to attach and register (optional) * @connector: connector to attach and register (optional)
* *
* Sets up a display pipeline which consist of a really simple * 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, ...@@ -219,6 +220,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
struct drm_simple_display_pipe *pipe, struct drm_simple_display_pipe *pipe,
const struct drm_simple_display_pipe_funcs *funcs, const struct drm_simple_display_pipe_funcs *funcs,
const uint32_t *formats, unsigned int format_count, const uint32_t *formats, unsigned int format_count,
const uint64_t *format_modifiers,
struct drm_connector *connector) struct drm_connector *connector)
{ {
struct drm_encoder *encoder = &pipe->encoder; struct drm_encoder *encoder = &pipe->encoder;
...@@ -233,6 +235,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev, ...@@ -233,6 +235,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0, ret = drm_universal_plane_init(dev, plane, 0,
&drm_simple_kms_plane_funcs, &drm_simple_kms_plane_funcs,
formats, format_count, formats, format_count,
format_modifiers,
DRM_PLANE_TYPE_PRIMARY, NULL); DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) if (ret)
return ret; return ret;
......
...@@ -283,7 +283,7 @@ int exynos_plane_init(struct drm_device *dev, ...@@ -283,7 +283,7 @@ int exynos_plane_init(struct drm_device *dev,
&exynos_plane_funcs, &exynos_plane_funcs,
config->pixel_formats, config->pixel_formats,
config->num_pixel_formats, config->num_pixel_formats,
config->type, NULL); NULL, config->type, NULL);
if (err) { if (err) {
DRM_ERROR("failed to initialize plane\n"); DRM_ERROR("failed to initialize plane\n");
return err; return err;
......
...@@ -224,7 +224,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev) ...@@ -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_funcs,
fsl_dcu_drm_plane_formats, fsl_dcu_drm_plane_formats,
ARRAY_SIZE(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) { if (ret) {
kfree(primary); kfree(primary);
primary = NULL; primary = NULL;
......
...@@ -181,6 +181,7 @@ static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv) ...@@ -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, ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
channel_formats1, channel_formats1,
ARRAY_SIZE(channel_formats1), ARRAY_SIZE(channel_formats1),
NULL,
DRM_PLANE_TYPE_PRIMARY, DRM_PLANE_TYPE_PRIMARY,
NULL); NULL);
if (ret) { if (ret) {
......
...@@ -910,7 +910,7 @@ static int ade_plane_init(struct drm_device *dev, struct ade_plane *aplane, ...@@ -910,7 +910,7 @@ static int ade_plane_init(struct drm_device *dev, struct ade_plane *aplane,
return ret; return ret;
ret = drm_universal_plane_init(dev, &aplane->base, 1, &ade_plane_funcs, 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) { if (ret) {
DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch); DRM_ERROR("fail to init plane, ch=%d\n", aplane->ch);
return ret; return ret;
......
...@@ -13809,18 +13809,21 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) ...@@ -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, ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs, 0, &intel_plane_funcs,
intel_primary_formats, num_formats, intel_primary_formats, num_formats,
NULL,
DRM_PLANE_TYPE_PRIMARY, DRM_PLANE_TYPE_PRIMARY,
"plane 1%c", pipe_name(pipe)); "plane 1%c", pipe_name(pipe));
else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv)) else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs, 0, &intel_plane_funcs,
intel_primary_formats, num_formats, intel_primary_formats, num_formats,
NULL,
DRM_PLANE_TYPE_PRIMARY, DRM_PLANE_TYPE_PRIMARY,
"primary %c", pipe_name(pipe)); "primary %c", pipe_name(pipe));
else else
ret = drm_universal_plane_init(&dev_priv->drm, &primary->base, ret = drm_universal_plane_init(&dev_priv->drm, &primary->base,
0, &intel_plane_funcs, 0, &intel_plane_funcs,
intel_primary_formats, num_formats, intel_primary_formats, num_formats,
NULL,
DRM_PLANE_TYPE_PRIMARY, DRM_PLANE_TYPE_PRIMARY,
"plane %c", plane_name(primary->plane)); "plane %c", plane_name(primary->plane));
if (ret) if (ret)
...@@ -13906,7 +13909,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv, ...@@ -13906,7 +13909,7 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
0, &intel_cursor_plane_funcs, 0, &intel_cursor_plane_funcs,
intel_cursor_formats, intel_cursor_formats,
ARRAY_SIZE(intel_cursor_formats), ARRAY_SIZE(intel_cursor_formats),
DRM_PLANE_TYPE_CURSOR, NULL, DRM_PLANE_TYPE_CURSOR,
"cursor %c", pipe_name(pipe)); "cursor %c", pipe_name(pipe));
if (ret) if (ret)
goto fail; goto fail;
......
...@@ -1171,13 +1171,13 @@ intel_sprite_plane_create(struct drm_i915_private *dev_priv, ...@@ -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, ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
possible_crtcs, &intel_plane_funcs, possible_crtcs, &intel_plane_funcs,
plane_formats, num_plane_formats, plane_formats, num_plane_formats,
DRM_PLANE_TYPE_OVERLAY, NULL, DRM_PLANE_TYPE_OVERLAY,
"plane %d%c", plane + 2, pipe_name(pipe)); "plane %d%c", plane + 2, pipe_name(pipe));
else else
ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base, ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
possible_crtcs, &intel_plane_funcs, possible_crtcs, &intel_plane_funcs,
plane_formats, num_plane_formats, plane_formats, num_plane_formats,
DRM_PLANE_TYPE_OVERLAY, NULL, DRM_PLANE_TYPE_OVERLAY,
"sprite %c", sprite_name(pipe, plane)); "sprite %c", sprite_name(pipe, plane));
if (ret) if (ret)
goto fail; goto fail;
......
...@@ -718,8 +718,8 @@ struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, ...@@ -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, ret = drm_universal_plane_init(dev, &ipu_plane->base, possible_crtcs,
&ipu_plane_funcs, ipu_plane_formats, &ipu_plane_funcs, ipu_plane_formats,
ARRAY_SIZE(ipu_plane_formats), type, ARRAY_SIZE(ipu_plane_formats),
NULL); NULL, type, NULL);
if (ret) { if (ret) {
DRM_ERROR("failed to initialize plane\n"); DRM_ERROR("failed to initialize plane\n");
kfree(ipu_plane); kfree(ipu_plane);
......
...@@ -175,7 +175,7 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, ...@@ -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, err = drm_universal_plane_init(dev, plane, possible_crtcs,
&mtk_plane_funcs, formats, &mtk_plane_funcs, formats,
ARRAY_SIZE(formats), type, NULL); ARRAY_SIZE(formats), NULL, type, NULL);
if (err) { if (err) {
DRM_ERROR("failed to initialize plane\n"); DRM_ERROR("failed to initialize plane\n");
return err; return err;
......
...@@ -223,6 +223,7 @@ int meson_plane_create(struct meson_drm *priv) ...@@ -223,6 +223,7 @@ int meson_plane_create(struct meson_drm *priv)
&meson_plane_funcs, &meson_plane_funcs,
supported_drm_formats, supported_drm_formats,
ARRAY_SIZE(supported_drm_formats), ARRAY_SIZE(supported_drm_formats),
NULL,
DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane"); DRM_PLANE_TYPE_PRIMARY, "meson_primary_plane");
drm_plane_helper_add(plane, &meson_plane_helper_funcs); drm_plane_helper_add(plane, &meson_plane_helper_funcs);
......
...@@ -401,7 +401,7 @@ struct drm_plane *mdp4_plane_init(struct drm_device *dev, ...@@ -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; type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs, ret = drm_universal_plane_init(dev, plane, 0xff, &mdp4_plane_funcs,
mdp4_plane->formats, mdp4_plane->nformats, mdp4_plane->formats, mdp4_plane->nformats,
type, NULL); NULL, type, NULL);
if (ret) if (ret)
goto fail; goto fail;
......
...@@ -1139,12 +1139,12 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev, ...@@ -1139,12 +1139,12 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0xff, ret = drm_universal_plane_init(dev, plane, 0xff,
&mdp5_cursor_plane_funcs, &mdp5_cursor_plane_funcs,
mdp5_plane->formats, mdp5_plane->nformats, mdp5_plane->formats, mdp5_plane->nformats,
type, NULL); NULL, type, NULL);
else else
ret = drm_universal_plane_init(dev, plane, 0xff, ret = drm_universal_plane_init(dev, plane, 0xff,
&mdp5_plane_funcs, &mdp5_plane_funcs,
mdp5_plane->formats, mdp5_plane->nformats, mdp5_plane->formats, mdp5_plane->nformats,
type, NULL); NULL, type, NULL);
if (ret) if (ret)
goto fail; goto fail;
......
...@@ -190,7 +190,7 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags) ...@@ -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, 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); &mxsfb->connector);
if (ret < 0) { if (ret < 0) {
dev_err(drm->dev, "Cannot setup simple display pipe\n"); dev_err(drm->dev, "Cannot setup simple display pipe\n");
......
...@@ -1083,8 +1083,9 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev, ...@@ -1083,8 +1083,9 @@ nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev,
wndw->func = func; wndw->func = func;
wndw->dmac = dmac; wndw->dmac = dmac;
ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, format, ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw,
nformat, type, "%s-%d", name, index); format, nformat, NULL,
type, "%s-%d", name, index);
if (ret) if (ret)
return ret; return ret;
......
...@@ -291,7 +291,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, ...@@ -291,7 +291,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, possible_crtcs, ret = drm_universal_plane_init(dev, plane, possible_crtcs,
&omap_plane_funcs, formats, &omap_plane_funcs, formats,
nformats, type, NULL); nformats, NULL, type, NULL);
if (ret < 0) if (ret < 0)
goto error; goto error;
......
...@@ -457,7 +457,7 @@ int pl111_display_init(struct drm_device *drm) ...@@ -457,7 +457,7 @@ int pl111_display_init(struct drm_device *drm)
ret = drm_simple_display_pipe_init(drm, &priv->pipe, ret = drm_simple_display_pipe_init(drm, &priv->pipe,
&pl111_display_funcs, &pl111_display_funcs,
formats, ARRAY_SIZE(formats), formats, ARRAY_SIZE(formats),
&priv->connector.connector); NULL, &priv->connector.connector);
if (ret) if (ret)
return ret; return ret;
......
...@@ -784,7 +784,7 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev, ...@@ -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, err = drm_universal_plane_init(&qdev->ddev, plane, possible_crtcs,
funcs, formats, num_formats, funcs, formats, num_formats,
type, NULL); NULL, type, NULL);
if (err) if (err)
goto free_plane; goto free_plane;
......
...@@ -743,8 +743,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp) ...@@ -743,8 +743,8 @@ int rcar_du_planes_init(struct rcar_du_group *rgrp)
ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs, ret = drm_universal_plane_init(rcdu->ddev, &plane->plane, crtcs,
&rcar_du_plane_funcs, formats, &rcar_du_plane_funcs, formats,
ARRAY_SIZE(formats), type, ARRAY_SIZE(formats),
NULL); NULL, type, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -439,8 +439,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp) ...@@ -439,8 +439,8 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp)
1 << vsp->index, 1 << vsp->index,
&rcar_du_vsp_plane_funcs, &rcar_du_vsp_plane_funcs,
formats_kms, formats_kms,
ARRAY_SIZE(formats_kms), type, ARRAY_SIZE(formats_kms),
NULL); NULL, type, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
...@@ -1288,7 +1288,7 @@ static int vop_create_crtc(struct vop *vop) ...@@ -1288,7 +1288,7 @@ static int vop_create_crtc(struct vop *vop)
0, &vop_plane_funcs, 0, &vop_plane_funcs,
win_data->phy->data_formats, win_data->phy->data_formats,
win_data->phy->nformats, win_data->phy->nformats,
win_data->type, NULL); NULL, win_data->type, NULL);
if (ret) { if (ret) {
DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n", DRM_DEV_ERROR(vop->dev, "failed to init plane %d\n",
ret); ret);
...@@ -1327,7 +1327,7 @@ static int vop_create_crtc(struct vop *vop) ...@@ -1327,7 +1327,7 @@ static int vop_create_crtc(struct vop *vop)
&vop_plane_funcs, &vop_plane_funcs,
win_data->phy->data_formats, win_data->phy->data_formats,
win_data->phy->nformats, win_data->phy->nformats,
win_data->type, NULL); NULL, win_data->type, NULL);
if (ret) { if (ret) {
DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n", DRM_DEV_ERROR(vop->dev, "failed to init overlay %d\n",
ret); ret);
......
...@@ -392,7 +392,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev, ...@@ -392,7 +392,7 @@ struct drm_plane *sti_cursor_create(struct drm_device *drm_dev,
&sti_cursor_plane_helpers_funcs, &sti_cursor_plane_helpers_funcs,
cursor_supported_formats, cursor_supported_formats,
ARRAY_SIZE(cursor_supported_formats), ARRAY_SIZE(cursor_supported_formats),
DRM_PLANE_TYPE_CURSOR, NULL); NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (res) { if (res) {
DRM_ERROR("Failed to initialize universal plane\n"); DRM_ERROR("Failed to initialize universal plane\n");
goto err_plane; goto err_plane;
......
...@@ -931,7 +931,7 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev, ...@@ -931,7 +931,7 @@ struct drm_plane *sti_gdp_create(struct drm_device *drm_dev,
&sti_gdp_plane_helpers_funcs, &sti_gdp_plane_helpers_funcs,
gdp_supported_formats, gdp_supported_formats,
ARRAY_SIZE(gdp_supported_formats), ARRAY_SIZE(gdp_supported_formats),
type, NULL); NULL, type, NULL);
if (res) { if (res) {
DRM_ERROR("Failed to initialize universal plane\n"); DRM_ERROR("Failed to initialize universal plane\n");
goto err; goto err;
......
...@@ -1298,7 +1298,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev, ...@@ -1298,7 +1298,7 @@ static struct drm_plane *sti_hqvdp_create(struct drm_device *drm_dev,
&sti_hqvdp_plane_helpers_funcs, &sti_hqvdp_plane_helpers_funcs,
hqvdp_supported_formats, hqvdp_supported_formats,
ARRAY_SIZE(hqvdp_supported_formats), ARRAY_SIZE(hqvdp_supported_formats),
DRM_PLANE_TYPE_OVERLAY, NULL); NULL, DRM_PLANE_TYPE_OVERLAY, NULL);
if (res) { if (res) {
DRM_ERROR("Failed to initialize universal plane\n"); DRM_ERROR("Failed to initialize universal plane\n");
return NULL; return NULL;
......
...@@ -735,7 +735,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, ...@@ -735,7 +735,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
ret = drm_universal_plane_init(ddev, plane, possible_crtcs, ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
&ltdc_plane_funcs, formats, nb_fmt, &ltdc_plane_funcs, formats, nb_fmt,
type, NULL); NULL, type, NULL);
if (ret < 0) if (ret < 0)
return 0; return 0;
......
...@@ -115,7 +115,7 @@ static struct sun4i_layer *sun4i_layer_init_one(struct drm_device *drm, ...@@ -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, ret = drm_universal_plane_init(drm, &layer->plane, 0,
&sun4i_backend_layer_funcs, &sun4i_backend_layer_funcs,
plane->formats, plane->nformats, plane->formats, plane->nformats,
plane->type, NULL); NULL, plane->type, NULL);
if (ret) { if (ret) {
dev_err(drm->dev, "Couldn't initialize layer\n"); dev_err(drm->dev, "Couldn't initialize layer\n");
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -90,7 +90,7 @@ static struct sun8i_layer *sun8i_layer_init_one(struct drm_device *drm, ...@@ -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, ret = drm_universal_plane_init(drm, &layer->plane, 0,
&sun8i_mixer_layer_funcs, &sun8i_mixer_layer_funcs,
plane->formats, plane->nformats, plane->formats, plane->nformats,
plane->type, NULL); NULL, plane->type, NULL);
if (ret) { if (ret) {
dev_err(drm->dev, "Couldn't initialize layer\n"); dev_err(drm->dev, "Couldn't initialize layer\n");
return ERR_PTR(ret); return ERR_PTR(ret);
......
...@@ -678,8 +678,8 @@ static struct drm_plane *tegra_dc_primary_plane_create(struct drm_device *drm, ...@@ -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, err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
&tegra_primary_plane_funcs, formats, &tegra_primary_plane_funcs, formats,
num_formats, DRM_PLANE_TYPE_PRIMARY, num_formats, NULL,
NULL); DRM_PLANE_TYPE_PRIMARY, NULL);
if (err < 0) { if (err < 0) {
kfree(plane); kfree(plane);
return ERR_PTR(err); return ERR_PTR(err);
...@@ -844,8 +844,8 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, ...@@ -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, err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
&tegra_cursor_plane_funcs, formats, &tegra_cursor_plane_funcs, formats,
num_formats, DRM_PLANE_TYPE_CURSOR, num_formats, NULL,
NULL); DRM_PLANE_TYPE_CURSOR, NULL);
if (err < 0) { if (err < 0) {
kfree(plane); kfree(plane);
return ERR_PTR(err); return ERR_PTR(err);
...@@ -906,8 +906,8 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, ...@@ -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, err = drm_universal_plane_init(drm, &plane->base, 1 << dc->pipe,
&tegra_overlay_plane_funcs, formats, &tegra_overlay_plane_funcs, formats,
num_formats, DRM_PLANE_TYPE_OVERLAY, num_formats, NULL,
NULL); DRM_PLANE_TYPE_OVERLAY, NULL);
if (err < 0) { if (err < 0) {
kfree(plane); kfree(plane);
return ERR_PTR(err); return ERR_PTR(err);
......
...@@ -225,7 +225,7 @@ tinydrm_display_pipe_init(struct tinydrm_device *tdev, ...@@ -225,7 +225,7 @@ tinydrm_display_pipe_init(struct tinydrm_device *tdev,
return PTR_ERR(connector); return PTR_ERR(connector);
ret = drm_simple_display_pipe_init(drm, &tdev->pipe, funcs, formats, ret = drm_simple_display_pipe_init(drm, &tdev->pipe, funcs, formats,
format_count, connector); format_count, NULL, connector);
if (ret) if (ret)
return ret; return ret;
......
...@@ -902,7 +902,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev, ...@@ -902,7 +902,7 @@ struct drm_plane *vc4_plane_init(struct drm_device *dev,
ret = drm_universal_plane_init(dev, plane, 0, ret = drm_universal_plane_init(dev, plane, 0,
&vc4_plane_funcs, &vc4_plane_funcs,
formats, num_formats, formats, num_formats,
type, NULL); NULL, type, NULL);
drm_plane_helper_add(plane, &vc4_plane_helper_funcs); drm_plane_helper_add(plane, &vc4_plane_helper_funcs);
......
...@@ -298,7 +298,7 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev, ...@@ -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, ret = drm_universal_plane_init(dev, plane, 1 << index,
&virtio_gpu_plane_funcs, &virtio_gpu_plane_funcs,
formats, nformats, formats, nformats,
type, NULL); NULL, type, NULL);
if (ret) if (ret)
goto err_plane_init; goto err_plane_init;
......
...@@ -428,7 +428,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -428,7 +428,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_ldu_plane_funcs, 0, &vmw_ldu_plane_funcs,
vmw_primary_plane_formats, vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats), ARRAY_SIZE(vmw_primary_plane_formats),
DRM_PLANE_TYPE_PRIMARY, NULL); NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) { if (ret) {
DRM_ERROR("Failed to initialize primary plane"); DRM_ERROR("Failed to initialize primary plane");
goto err_free; goto err_free;
...@@ -443,7 +443,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -443,7 +443,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_ldu_cursor_funcs, 0, &vmw_ldu_cursor_funcs,
vmw_cursor_plane_formats, vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats), ARRAY_SIZE(vmw_cursor_plane_formats),
DRM_PLANE_TYPE_CURSOR, NULL); NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) { if (ret) {
DRM_ERROR("Failed to initialize cursor plane"); DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&ldu->base.primary); drm_plane_cleanup(&ldu->base.primary);
......
...@@ -624,7 +624,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -624,7 +624,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_sou_plane_funcs, 0, &vmw_sou_plane_funcs,
vmw_primary_plane_formats, vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats), ARRAY_SIZE(vmw_primary_plane_formats),
DRM_PLANE_TYPE_PRIMARY, NULL); NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) { if (ret) {
DRM_ERROR("Failed to initialize primary plane"); DRM_ERROR("Failed to initialize primary plane");
goto err_free; goto err_free;
...@@ -639,7 +639,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -639,7 +639,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_sou_cursor_funcs, 0, &vmw_sou_cursor_funcs,
vmw_cursor_plane_formats, vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats), ARRAY_SIZE(vmw_cursor_plane_formats),
DRM_PLANE_TYPE_CURSOR, NULL); NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) { if (ret) {
DRM_ERROR("Failed to initialize cursor plane"); DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&sou->base.primary); drm_plane_cleanup(&sou->base.primary);
......
...@@ -1475,7 +1475,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -1475,7 +1475,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_stdu_plane_funcs, 0, &vmw_stdu_plane_funcs,
vmw_primary_plane_formats, vmw_primary_plane_formats,
ARRAY_SIZE(vmw_primary_plane_formats), ARRAY_SIZE(vmw_primary_plane_formats),
DRM_PLANE_TYPE_PRIMARY, NULL); NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
if (ret) { if (ret) {
DRM_ERROR("Failed to initialize primary plane"); DRM_ERROR("Failed to initialize primary plane");
goto err_free; goto err_free;
...@@ -1490,7 +1490,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -1490,7 +1490,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit)
0, &vmw_stdu_cursor_funcs, 0, &vmw_stdu_cursor_funcs,
vmw_cursor_plane_formats, vmw_cursor_plane_formats,
ARRAY_SIZE(vmw_cursor_plane_formats), ARRAY_SIZE(vmw_cursor_plane_formats),
DRM_PLANE_TYPE_CURSOR, NULL); NULL, DRM_PLANE_TYPE_CURSOR, NULL);
if (ret) { if (ret) {
DRM_ERROR("Failed to initialize cursor plane"); DRM_ERROR("Failed to initialize cursor plane");
drm_plane_cleanup(&stdu->base.primary); drm_plane_cleanup(&stdu->base.primary);
......
...@@ -540,7 +540,7 @@ int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane, ...@@ -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, ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK,
&zx_plane_funcs, formats, format_count, &zx_plane_funcs, formats, format_count,
type, NULL); NULL, type, NULL);
if (ret) { if (ret) {
DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret); DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret);
return ret; return ret;
......
...@@ -392,6 +392,22 @@ struct drm_plane_funcs { ...@@ -392,6 +392,22 @@ struct drm_plane_funcs {
*/ */
void (*atomic_print_state)(struct drm_printer *p, void (*atomic_print_state)(struct drm_printer *p,
const struct drm_plane_state *state); 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 { ...@@ -487,6 +503,9 @@ struct drm_plane {
unsigned int format_count; unsigned int format_count;
bool format_default; bool format_default;
uint64_t *modifiers;
unsigned int modifier_count;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_framebuffer *fb; struct drm_framebuffer *fb;
...@@ -527,13 +546,14 @@ struct drm_plane { ...@@ -527,13 +546,14 @@ struct drm_plane {
#define obj_to_plane(x) container_of(x, struct drm_plane, base) #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, int drm_universal_plane_init(struct drm_device *dev,
struct drm_plane *plane, struct drm_plane *plane,
uint32_t possible_crtcs, uint32_t possible_crtcs,
const struct drm_plane_funcs *funcs, const struct drm_plane_funcs *funcs,
const uint32_t *formats, const uint32_t *formats,
unsigned int format_count, unsigned int format_count,
const uint64_t *format_modifiers,
enum drm_plane_type type, enum drm_plane_type type,
const char *name, ...); const char *name, ...);
int drm_plane_init(struct drm_device *dev, int drm_plane_init(struct drm_device *dev,
......
...@@ -122,6 +122,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev, ...@@ -122,6 +122,7 @@ int drm_simple_display_pipe_init(struct drm_device *dev,
struct drm_simple_display_pipe *pipe, struct drm_simple_display_pipe *pipe,
const struct drm_simple_display_pipe_funcs *funcs, const struct drm_simple_display_pipe_funcs *funcs,
const uint32_t *formats, unsigned int format_count, const uint32_t *formats, unsigned int format_count,
const uint64_t *format_modifiers,
struct drm_connector *connector); struct drm_connector *connector);
#endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */ #endif /* __LINUX_DRM_SIMPLE_KMS_HELPER_H */
...@@ -185,6 +185,8 @@ extern "C" { ...@@ -185,6 +185,8 @@ extern "C" {
#define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07 #define DRM_FORMAT_MOD_VENDOR_BROADCOM 0x07
/* add more to the end as needed */ /* add more to the end as needed */
#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
#define fourcc_mod_code(vendor, val) \ #define fourcc_mod_code(vendor, val) \
((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
...@@ -196,6 +198,15 @@ extern "C" { ...@@ -196,6 +198,15 @@ extern "C" {
* authoritative source for all of these. * 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 * Linear Layout
* *
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册