aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2017-11-10 11:10:00 -0500
committerPhilipp Zabel <p.zabel@pengutronix.de>2017-12-19 06:49:11 -0500
commit9222f768f7b09fea4f12914b376ec975ef758a60 (patch)
tree5de428de8b565c4281162e12c574ecab78d78ea6 /drivers
parenta2ceec52d9a48bd046e5496e266dda1c57872f4b (diff)
drm/imx: add FB modifier support
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@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c1
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c65
2 files changed, 60 insertions, 6 deletions
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 17d2f3a1c562..1887a668c55e 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -272,6 +272,7 @@ static int imx_drm_bind(struct device *dev)
272 drm->mode_config.max_height = 4096; 272 drm->mode_config.max_height = 4096;
273 drm->mode_config.funcs = &imx_drm_mode_config_funcs; 273 drm->mode_config.funcs = &imx_drm_mode_config_funcs;
274 drm->mode_config.helper_private = &imx_drm_mode_config_helpers; 274 drm->mode_config.helper_private = &imx_drm_mode_config_helpers;
275 drm->mode_config.allow_fb_modifiers = true;
275 276
276 drm_mode_config_init(drm); 277 drm_mode_config_init(drm);
277 278
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 091393cb9659..32a6debf7107 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -551,7 +551,7 @@ static void ipu_plane_atomic_update(struct drm_plane *plane,
551 drm_rect_width(&state->src) >> 16, 551 drm_rect_width(&state->src) >> 16,
552 drm_rect_height(&state->src) >> 16, 552 drm_rect_height(&state->src) >> 16,
553 fb->pitches[0], fb->format->format, 553 fb->pitches[0], fb->format->format,
554 0, &eba); 554 fb->modifier, &eba);
555 } 555 }
556 556
557 if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) { 557 if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) {
@@ -700,18 +700,71 @@ static const struct drm_plane_helper_funcs ipu_plane_helper_funcs = {
700int ipu_planes_assign_pre(struct drm_device *dev, 700int ipu_planes_assign_pre(struct drm_device *dev,
701 struct drm_atomic_state *state) 701 struct drm_atomic_state *state)
702{ 702{
703 struct drm_crtc_state *old_crtc_state, *crtc_state;
703 struct drm_plane_state *plane_state; 704 struct drm_plane_state *plane_state;
705 struct ipu_plane_state *ipu_state;
706 struct ipu_plane *ipu_plane;
704 struct drm_plane *plane; 707 struct drm_plane *plane;
708 struct drm_crtc *crtc;
705 int available_pres = ipu_prg_max_active_channels(); 709 int available_pres = ipu_prg_max_active_channels();
706 int i; 710 int ret, i;
711
712 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, crtc_state, i) {
713 ret = drm_atomic_add_affected_planes(state, crtc);
714 if (ret)
715 return ret;
716 }
717
718 /*
719 * We are going over the planes in 2 passes: first we assign PREs to
720 * planes with a tiling modifier, which need the PREs to resolve into
721 * linear. Any failure to assign a PRE there is fatal. In the second
722 * pass we try to assign PREs to linear FBs, to improve memory access
723 * patterns for them. Failure at this point is non-fatal, as we can
724 * scan out linear FBs without a PRE.
725 */
726 for_each_new_plane_in_state(state, plane, plane_state, i) {
727 ipu_state = to_ipu_plane_state(plane_state);
728 ipu_plane = to_ipu_plane(plane);
729
730 if (!plane_state->fb) {
731 ipu_state->use_pre = false;
732 continue;
733 }
734
735 if (!(plane_state->fb->flags & DRM_MODE_FB_MODIFIERS) ||
736 plane_state->fb->modifier == DRM_FORMAT_MOD_LINEAR)
737 continue;
738
739 if (!ipu_prg_present(ipu_plane->ipu) || !available_pres)
740 return -EINVAL;
741
742 if (!ipu_prg_format_supported(ipu_plane->ipu,
743 plane_state->fb->format->format,
744 plane_state->fb->modifier))
745 return -EINVAL;
746
747 ipu_state->use_pre = true;
748 available_pres--;
749 }
707 750
708 for_each_new_plane_in_state(state, plane, plane_state, i) { 751 for_each_new_plane_in_state(state, plane, plane_state, i) {
709 struct ipu_plane_state *ipu_state = 752 ipu_state = to_ipu_plane_state(plane_state);
710 to_ipu_plane_state(plane_state); 753 ipu_plane = to_ipu_plane(plane);
711 struct ipu_plane *ipu_plane = to_ipu_plane(plane); 754
755 if (!plane_state->fb) {
756 ipu_state->use_pre = false;
757 continue;
758 }
759
760 if ((plane_state->fb->flags & DRM_MODE_FB_MODIFIERS) &&
761 plane_state->fb->modifier != DRM_FORMAT_MOD_LINEAR)
762 continue;
763
764 /* make sure that modifier is initialized */
765 plane_state->fb->modifier = DRM_FORMAT_MOD_LINEAR;
712 766
713 if (ipu_prg_present(ipu_plane->ipu) && available_pres && 767 if (ipu_prg_present(ipu_plane->ipu) && available_pres &&
714 plane_state->fb &&
715 ipu_prg_format_supported(ipu_plane->ipu, 768 ipu_prg_format_supported(ipu_plane->ipu,
716 plane_state->fb->format->format, 769 plane_state->fb->format->format,
717 plane_state->fb->modifier)) { 770 plane_state->fb->modifier)) {