Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Lucas Stach and committed by
Philipp Zabel
9222f768 a2ceec52

+60 -6
+1
drivers/gpu/drm/imx/imx-drm-core.c
··· 272 272 drm->mode_config.max_height = 4096; 273 273 drm->mode_config.funcs = &imx_drm_mode_config_funcs; 274 274 drm->mode_config.helper_private = &imx_drm_mode_config_helpers; 275 + drm->mode_config.allow_fb_modifiers = true; 275 276 276 277 drm_mode_config_init(drm); 277 278
+59 -6
drivers/gpu/drm/imx/ipuv3-plane.c
··· 551 551 drm_rect_width(&state->src) >> 16, 552 552 drm_rect_height(&state->src) >> 16, 553 553 fb->pitches[0], fb->format->format, 554 - 0, &eba); 554 + fb->modifier, &eba); 555 555 } 556 556 557 557 if (old_state->fb && !drm_atomic_crtc_needs_modeset(crtc_state)) { ··· 700 700 int ipu_planes_assign_pre(struct drm_device *dev, 701 701 struct drm_atomic_state *state) 702 702 { 703 + struct drm_crtc_state *old_crtc_state, *crtc_state; 703 704 struct drm_plane_state *plane_state; 705 + struct ipu_plane_state *ipu_state; 706 + struct ipu_plane *ipu_plane; 704 707 struct drm_plane *plane; 708 + struct drm_crtc *crtc; 705 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 751 for_each_new_plane_in_state(state, plane, plane_state, i) { 709 - struct ipu_plane_state *ipu_state = 710 - to_ipu_plane_state(plane_state); 711 - struct ipu_plane *ipu_plane = to_ipu_plane(plane); 752 + ipu_state = to_ipu_plane_state(plane_state); 753 + 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 767 if (ipu_prg_present(ipu_plane->ipu) && available_pres && 714 - plane_state->fb && 715 768 ipu_prg_format_supported(ipu_plane->ipu, 716 769 plane_state->fb->format->format, 717 770 plane_state->fb->modifier)) {