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

drm/atomic-helper: Disable appropriate planes in disable_planes_on_crtc()

Currently, the helper drm_atomic_helper_disable_planes_on_crtc() calls
->atomic_disable for all planes _to be_ enabled on a particular CRTC.
This is obviously wrong for those planes which are not scanning out frames
when the helper is called. Instead, it's sane to disable active planes
of old_crtc_state in the helper.

Suggested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Peter Senna Tschudin <peter.senna@gmail.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Liu Ying <gnuiyl@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/1472196644-30563-3-git-send-email-gnuiyl@gmail.com

authored by

Liu Ying and committed by
Daniel Vetter
28500291 c9ac8b4c

+12 -9
+9 -7
drivers/gpu/drm/drm_atomic_helper.c
··· 1842 1842 1843 1843 /** 1844 1844 * drm_atomic_helper_disable_planes_on_crtc - helper to disable CRTC's planes 1845 - * @crtc: CRTC 1845 + * @old_crtc_state: atomic state object with the old CRTC state 1846 1846 * @atomic: if set, synchronize with CRTC's atomic_begin/flush hooks 1847 1847 * 1848 1848 * Disables all planes associated with the given CRTC. This can be 1849 - * used for instance in the CRTC helper disable callback to disable 1850 - * all planes before shutting down the display pipeline. 1849 + * used for instance in the CRTC helper atomic_disable callback to disable 1850 + * all planes. 1851 1851 * 1852 1852 * If the atomic-parameter is set the function calls the CRTC's 1853 1853 * atomic_begin hook before and atomic_flush hook after disabling the ··· 1856 1856 * It is a bug to call this function without having implemented the 1857 1857 * ->atomic_disable() plane hook. 1858 1858 */ 1859 - void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc, 1860 - bool atomic) 1859 + void 1860 + drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state, 1861 + bool atomic) 1861 1862 { 1863 + struct drm_crtc *crtc = old_crtc_state->crtc; 1862 1864 const struct drm_crtc_helper_funcs *crtc_funcs = 1863 1865 crtc->helper_private; 1864 1866 struct drm_plane *plane; ··· 1868 1866 if (atomic && crtc_funcs && crtc_funcs->atomic_begin) 1869 1867 crtc_funcs->atomic_begin(crtc, NULL); 1870 1868 1871 - drm_for_each_plane(plane, crtc->dev) { 1869 + drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) { 1872 1870 const struct drm_plane_helper_funcs *plane_funcs = 1873 1871 plane->helper_private; 1874 1872 1875 - if (plane->state->crtc != crtc || !plane_funcs) 1873 + if (!plane_funcs) 1876 1874 continue; 1877 1875 1878 1876 WARN_ON(!plane_funcs->atomic_disable);
+3 -2
include/drm/drm_atomic_helper.h
··· 71 71 void drm_atomic_helper_cleanup_planes(struct drm_device *dev, 72 72 struct drm_atomic_state *old_state); 73 73 void drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state); 74 - void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc, 75 - bool atomic); 74 + void 75 + drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state, 76 + bool atomic); 76 77 77 78 void drm_atomic_helper_swap_state(struct drm_atomic_state *state, 78 79 bool stall);