Skip to content

Commit edc4330

Browse files
author
Jyri Sarha
committed
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>
1 parent db380c5 commit edc4330

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

drivers/gpu/drm/tilcdc/tilcdc_drv.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <linux/component.h>
2121
#include <linux/pinctrl/consumer.h>
2222
#include <linux/suspend.h>
23+
#include <drm/drm_atomic.h>
24+
#include <drm/drm_atomic_helper.h>
2325

2426
#include "tilcdc_drv.h"
2527
#include "tilcdc_regs.h"
@@ -59,9 +61,78 @@ static void tilcdc_fb_output_poll_changed(struct drm_device *dev)
5961
drm_fbdev_cma_hotplug_event(priv->fbdev);
6062
}
6163

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+
62131
static const struct drm_mode_config_funcs mode_config_funcs = {
63132
.fb_create = tilcdc_fb_create,
64133
.output_poll_changed = tilcdc_fb_output_poll_changed,
134+
.atomic_check = tilcdc_atomic_check,
135+
.atomic_commit = tilcdc_commit,
65136
};
66137

67138
static int modeset_init(struct drm_device *dev)

0 commit comments

Comments
 (0)