aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tilcdc
diff options
context:
space:
mode:
authorJyri Sarha <jsarha@ti.com>2015-12-30 10:40:24 -0500
committerJyri Sarha <jsarha@ti.com>2016-08-08 16:05:05 -0400
commitedc43303888c13904a1c990592eb64f17e8e7eb1 (patch)
tree172d20b3b2ea8c688b124d4367bb8be610a38f39 /drivers/gpu/drm/tilcdc
parentdb380c58b76be09bc27be0f5d3480547db71e6d5 (diff)
drm/tilcdc: Add atomic mode config funcs
Add atomic mode config funcs. The atomic_commit implementation is a copy-paste from drm_atomic_helper_commit(), leaving out the async test. The similar copy-paste implementation appears to be used in many other drivers too. The standard drm_atomic_helper_check() is used for checking. The drm_atomic_helper_check() can not be used in drm_mode_config_funcs atomic_check() callback because the plane's check implementation may update crtc state's ->mode_changed flag. Because of this the drm_atomic_helper_check_modeset() has to be called once more after drm_atomic_helper_check_planes() (see drm_atomic_helper_check_modeset() documentation). Signed-off-by: Jyri Sarha <jsarha@ti.com>
Diffstat (limited to 'drivers/gpu/drm/tilcdc')
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 16163a7e9ed1..a8c47794a3f1 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -20,6 +20,8 @@
20#include <linux/component.h> 20#include <linux/component.h>
21#include <linux/pinctrl/consumer.h> 21#include <linux/pinctrl/consumer.h>
22#include <linux/suspend.h> 22#include <linux/suspend.h>
23#include <drm/drm_atomic.h>
24#include <drm/drm_atomic_helper.h>
23 25
24#include "tilcdc_drv.h" 26#include "tilcdc_drv.h"
25#include "tilcdc_regs.h" 27#include "tilcdc_regs.h"
@@ -59,9 +61,78 @@ static void tilcdc_fb_output_poll_changed(struct drm_device *dev)
59 drm_fbdev_cma_hotplug_event(priv->fbdev); 61 drm_fbdev_cma_hotplug_event(priv->fbdev);
60} 62}
61 63
64int tilcdc_atomic_check(struct drm_device *dev,
65 struct drm_atomic_state *state)
66{
67 int ret;
68
69 ret = drm_atomic_helper_check_modeset(dev, state);
70 if (ret)
71 return ret;
72
73 ret = drm_atomic_helper_check_planes(dev, state);
74 if (ret)
75 return ret;
76
77 /*
78 * tilcdc ->atomic_check can update ->mode_changed if pixel format
79 * changes, hence will we check modeset changes again.
80 */
81 ret = drm_atomic_helper_check_modeset(dev, state);
82 if (ret)
83 return ret;
84
85 return ret;
86}
87
88static int tilcdc_commit(struct drm_device *dev,
89 struct drm_atomic_state *state,
90 bool async)
91{
92 int ret;
93
94 ret = drm_atomic_helper_prepare_planes(dev, state);
95 if (ret)
96 return ret;
97
98 drm_atomic_helper_swap_state(state, true);
99
100 /*
101 * Everything below can be run asynchronously without the need to grab
102 * any modeset locks at all under one condition: It must be guaranteed
103 * that the asynchronous work has either been cancelled (if the driver
104 * supports it, which at least requires that the framebuffers get
105 * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
106 * before the new state gets committed on the software side with
107 * drm_atomic_helper_swap_state().
108 *
109 * This scheme allows new atomic state updates to be prepared and
110 * checked in parallel to the asynchronous completion of the previous
111 * update. Which is important since compositors need to figure out the
112 * composition of the next frame right after having submitted the
113 * current layout.
114 */
115
116 drm_atomic_helper_commit_modeset_disables(dev, state);
117
118 drm_atomic_helper_commit_planes(dev, state, false);
119
120 drm_atomic_helper_commit_modeset_enables(dev, state);
121
122 drm_atomic_helper_wait_for_vblanks(dev, state);
123
124 drm_atomic_helper_cleanup_planes(dev, state);
125
126 drm_atomic_state_free(state);
127
128 return 0;
129}
130
62static const struct drm_mode_config_funcs mode_config_funcs = { 131static const struct drm_mode_config_funcs mode_config_funcs = {
63 .fb_create = tilcdc_fb_create, 132 .fb_create = tilcdc_fb_create,
64 .output_poll_changed = tilcdc_fb_output_poll_changed, 133 .output_poll_changed = tilcdc_fb_output_poll_changed,
134 .atomic_check = tilcdc_atomic_check,
135 .atomic_commit = tilcdc_commit,
65}; 136};
66 137
67static int modeset_init(struct drm_device *dev) 138static int modeset_init(struct drm_device *dev)