diff options
author | Jyri Sarha <jsarha@ti.com> | 2015-12-30 10:40:24 -0500 |
---|---|---|
committer | Jyri Sarha <jsarha@ti.com> | 2016-08-08 16:05:05 -0400 |
commit | edc43303888c13904a1c990592eb64f17e8e7eb1 (patch) | |
tree | 172d20b3b2ea8c688b124d4367bb8be610a38f39 /drivers/gpu/drm/tilcdc | |
parent | db380c58b76be09bc27be0f5d3480547db71e6d5 (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.c | 71 |
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 | ||
64 | int 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 | |||
88 | static 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 | |||
62 | static const struct drm_mode_config_funcs mode_config_funcs = { | 131 | static 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 | ||
67 | static int modeset_init(struct drm_device *dev) | 138 | static int modeset_init(struct drm_device *dev) |