You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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: Ben Widawsky <ben@bwidawsk.net> Reviewed-by: Daniel Stone <daniels@collabora.com> (v2) Reviewed-by: Liviu Dudau <Liviu.Dudau@arm.com> Signed-off-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
committed by
Daniel Stone
parent
d7429669c8
commit
e6fc3b6855
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user