This adds FB modifier support for the Vivante single buffer tiled formats,
when the PRG/PRE engines are present.

Signed-off-by: Lucas Stach <l.st...@pengutronix.de>
---
 drivers/gpu/drm/imx/imx-drm-core.c |  1 +
 drivers/gpu/drm/imx/ipuv3-plane.c  | 55 ++++++++++++++++++++++++++++++++++----
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/imx/imx-drm-core.c 
b/drivers/gpu/drm/imx/imx-drm-core.c
index 50add2f9e250..d21e7db95979 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -266,6 +266,7 @@ static int imx_drm_bind(struct device *dev)
        drm->mode_config.max_height = 4096;
        drm->mode_config.funcs = &imx_drm_mode_config_funcs;
        drm->mode_config.helper_private = &imx_drm_mode_config_helpers;
+       drm->mode_config.allow_fb_modifiers = true;
 
        drm_mode_config_init(drm);
 
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c 
b/drivers/gpu/drm/imx/ipuv3-plane.c
index 705ca93847ff..44593dd6ba31 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -527,7 +527,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
                                          drm_rect_height(&state->src) >> 16,
                                          state->fb->pitches[0],
                                          state->fb->format->format,
-                                         0,
+                                         state->fb->modifier,
                                          &eba);
        }
 
@@ -673,17 +673,62 @@ int ipu_planes_assign_pre(struct drm_device *dev,
                          struct drm_atomic_state *state)
 {
        struct drm_plane_state *plane_state;
+       struct ipu_plane_state *ipu_state;
+       struct ipu_plane *ipu_plane;
        struct drm_plane *plane;
        int available_pres = ipu_prg_max_active_channels();
        int i;
 
+       /*
+        * We are going over the planes in 2 passes: first we assign PREs to
+        * planes with a tiling modifier, which need the PREs to resolve into
+        * linear. Any failure to assign a PRE there is fatal. In the second
+        * pass we try to assign PREs to linear FBs, to improve memory access
+        * patterns for them. Failure at this point is non-fatal, as we can
+        * scan out linear FBs without a PRE.
+        */
        for_each_plane_in_state(state, plane, plane_state, i) {
-               struct ipu_plane_state *ipu_state =
-                               to_ipu_plane_state(plane_state);
-               struct ipu_plane *ipu_plane = to_ipu_plane(plane);
+               ipu_state = to_ipu_plane_state(plane_state);
+               ipu_plane = to_ipu_plane(plane);
+
+               if (!plane_state->fb) {
+                       ipu_state->use_pre = false;
+                       continue;
+               }
+
+               if (!(plane_state->fb->flags & DRM_MODE_FB_MODIFIERS) ||
+                   plane_state->fb->modifier == DRM_FORMAT_MOD_LINEAR)
+                       continue;
+
+               if (!ipu_prg_present(ipu_plane->ipu) || !available_pres)
+                       return -EINVAL;
+
+               if (!ipu_prg_format_supported(ipu_plane->ipu,
+                                             plane_state->fb->format->format,
+                                             plane_state->fb->modifier))
+                       return -EINVAL;
+
+               ipu_state->use_pre = true;
+               available_pres--;
+       }
+
+       for_each_plane_in_state(state, plane, plane_state, i) {
+               ipu_state = to_ipu_plane_state(plane_state);
+               ipu_plane = to_ipu_plane(plane);
+
+               if (!plane_state->fb) {
+                       ipu_state->use_pre = false;
+                       continue;
+               }
+
+               if ((plane_state->fb->flags & DRM_MODE_FB_MODIFIERS) &&
+                   plane_state->fb->modifier != DRM_FORMAT_MOD_LINEAR)
+                       continue;
+
+               /* make sure that modifier is initialized */
+               plane_state->fb->modifier = DRM_FORMAT_MOD_LINEAR;
 
                if (ipu_prg_present(ipu_plane->ipu) && available_pres &&
-                   plane_state->fb &&
                    ipu_prg_format_supported(ipu_plane->ipu,
                                             plane_state->fb->format->format,
                                             plane_state->fb->modifier)) {
-- 
2.11.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to