[PATCH 3/4] drm/imx: add FB modifier support
Lucas Stach
l.stach at pengutronix.de
Wed May 3 16:28:36 UTC 2017
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.stach at 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
More information about the dri-devel
mailing list