summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2023-10-09 17:06:33 +0300
committerThomas Zimmermann <tzimmermann@suse.de>2023-11-14 12:17:22 +0300
commit58b184dcb3f4c52c15b6ff4fa2fa0d69d1e1313f (patch)
tree095b3f0e19401760e994ce607a2baaf9e1a19465
parent4cd24d4b1a9548f42cdb7f449edc6f869a8ae730 (diff)
downloadlinux-58b184dcb3f4c52c15b6ff4fa2fa0d69d1e1313f.tar.xz
drm/ofdrm: Preallocate format-conversion buffer in atomic_check
Preallocate the format-conversion state's storage in the plane's atomic_check function if a format conversion is necessary. Allows the update to fail if no memory is available. Avoids the same allocation within atomic_update, which may not fail. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231009141018.11291-5-tzimmermann@suse.de
-rw-r--r--drivers/gpu/drm/tiny/ofdrm.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
index 404c83032cec..05a72473cfc6 100644
--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -758,7 +758,11 @@ static const uint64_t ofdrm_primary_plane_format_modifiers[] = {
static int ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
struct drm_atomic_state *new_state)
{
+ struct drm_device *dev = plane->dev;
+ struct ofdrm_device *odev = ofdrm_device_of_dev(dev);
struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(new_state, plane);
+ struct drm_shadow_plane_state *new_shadow_plane_state =
+ to_drm_shadow_plane_state(new_plane_state);
struct drm_framebuffer *new_fb = new_plane_state->fb;
struct drm_crtc *new_crtc = new_plane_state->crtc;
struct drm_crtc_state *new_crtc_state = NULL;
@@ -777,6 +781,16 @@ static int ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
else if (!new_plane_state->visible)
return 0;
+ if (new_fb->format != odev->format) {
+ void *buf;
+
+ /* format conversion necessary; reserve buffer */
+ buf = drm_format_conv_state_reserve(&new_shadow_plane_state->fmtcnv_state,
+ odev->pitch, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+ }
+
new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_plane_state->crtc);
new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);