diff options
author | Rob Clark <robdclark@gmail.com> | 2016-11-04 13:51:42 -0400 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2016-11-27 11:32:27 -0500 |
commit | 870d738acb7ebb0d4f6192c9d328cae95479715b (patch) | |
tree | 9d8ad211c6b5d82cfb2cf4122a99ffc81c9c3f23 | |
parent | c056b55dc672cbc42e8814ef45726ca22e01ef9e (diff) |
drm/msm: subclass drm_atomic_state
This will give the kms backends a slot to stash their own hw specific
global state.
Signed-off-by: Rob Clark <robdclark@gmail.com>
-rw-r--r-- | drivers/gpu/drm/msm/msm_atomic.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/msm/msm_kms.h | 14 |
4 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 4e21e1d72378..30b5d23e53b4 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c | |||
@@ -241,6 +241,10 @@ int msm_atomic_commit(struct drm_device *dev, | |||
241 | 241 | ||
242 | drm_atomic_helper_swap_state(state, true); | 242 | drm_atomic_helper_swap_state(state, true); |
243 | 243 | ||
244 | /* swap driver private state while still holding state_lock */ | ||
245 | if (to_kms_state(state)->state) | ||
246 | priv->kms->funcs->swap_state(priv->kms, state); | ||
247 | |||
244 | /* | 248 | /* |
245 | * Everything below can be run asynchronously without the need to grab | 249 | * Everything below can be run asynchronously without the need to grab |
246 | * any modeset locks at all under one conditions: It must be guaranteed | 250 | * any modeset locks at all under one conditions: It must be guaranteed |
@@ -271,3 +275,30 @@ error: | |||
271 | drm_atomic_helper_cleanup_planes(dev, state); | 275 | drm_atomic_helper_cleanup_planes(dev, state); |
272 | return ret; | 276 | return ret; |
273 | } | 277 | } |
278 | |||
279 | struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev) | ||
280 | { | ||
281 | struct msm_kms_state *state = kzalloc(sizeof(*state), GFP_KERNEL); | ||
282 | |||
283 | if (!state || drm_atomic_state_init(dev, &state->base) < 0) { | ||
284 | kfree(state); | ||
285 | return NULL; | ||
286 | } | ||
287 | |||
288 | return &state->base; | ||
289 | } | ||
290 | |||
291 | void msm_atomic_state_clear(struct drm_atomic_state *s) | ||
292 | { | ||
293 | struct msm_kms_state *state = to_kms_state(s); | ||
294 | drm_atomic_state_default_clear(&state->base); | ||
295 | kfree(state->state); | ||
296 | state->state = NULL; | ||
297 | } | ||
298 | |||
299 | void msm_atomic_state_free(struct drm_atomic_state *state) | ||
300 | { | ||
301 | kfree(to_kms_state(state)->state); | ||
302 | drm_atomic_state_default_release(state); | ||
303 | kfree(state); | ||
304 | } | ||
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index c740eaf9272b..aa41d8dd623b 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
@@ -46,6 +46,9 @@ static const struct drm_mode_config_funcs mode_config_funcs = { | |||
46 | .output_poll_changed = msm_fb_output_poll_changed, | 46 | .output_poll_changed = msm_fb_output_poll_changed, |
47 | .atomic_check = msm_atomic_check, | 47 | .atomic_check = msm_atomic_check, |
48 | .atomic_commit = msm_atomic_commit, | 48 | .atomic_commit = msm_atomic_commit, |
49 | .atomic_state_alloc = msm_atomic_state_alloc, | ||
50 | .atomic_state_clear = msm_atomic_state_clear, | ||
51 | .atomic_state_free = msm_atomic_state_free, | ||
49 | }; | 52 | }; |
50 | 53 | ||
51 | int msm_register_address_space(struct drm_device *dev, | 54 | int msm_register_address_space(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 03ce6a18ac40..175b2bfae5e1 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h | |||
@@ -179,6 +179,9 @@ int msm_atomic_check(struct drm_device *dev, | |||
179 | struct drm_atomic_state *state); | 179 | struct drm_atomic_state *state); |
180 | int msm_atomic_commit(struct drm_device *dev, | 180 | int msm_atomic_commit(struct drm_device *dev, |
181 | struct drm_atomic_state *state, bool nonblock); | 181 | struct drm_atomic_state *state, bool nonblock); |
182 | struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev); | ||
183 | void msm_atomic_state_clear(struct drm_atomic_state *state); | ||
184 | void msm_atomic_state_free(struct drm_atomic_state *state); | ||
182 | 185 | ||
183 | int msm_register_address_space(struct drm_device *dev, | 186 | int msm_register_address_space(struct drm_device *dev, |
184 | struct msm_gem_address_space *aspace); | 187 | struct msm_gem_address_space *aspace); |
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 40e41e5cdbc6..cb9758bcadfd 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h | |||
@@ -40,6 +40,8 @@ struct msm_kms_funcs { | |||
40 | irqreturn_t (*irq)(struct msm_kms *kms); | 40 | irqreturn_t (*irq)(struct msm_kms *kms); |
41 | int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); | 41 | int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); |
42 | void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); | 42 | void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); |
43 | /* swap global atomic state: */ | ||
44 | void (*swap_state)(struct msm_kms *kms, struct drm_atomic_state *state); | ||
43 | /* modeset, bracketing atomic_commit(): */ | 45 | /* modeset, bracketing atomic_commit(): */ |
44 | void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state); | 46 | void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state); |
45 | void (*complete_commit)(struct msm_kms *kms, struct drm_atomic_state *state); | 47 | void (*complete_commit)(struct msm_kms *kms, struct drm_atomic_state *state); |
@@ -65,6 +67,18 @@ struct msm_kms { | |||
65 | int irq; | 67 | int irq; |
66 | }; | 68 | }; |
67 | 69 | ||
70 | /** | ||
71 | * Subclass of drm_atomic_state, to allow kms backend to have driver | ||
72 | * private global state. The kms backend can do whatever it wants | ||
73 | * with the ->state ptr. On ->atomic_state_clear() the ->state ptr | ||
74 | * is kfree'd and set back to NULL. | ||
75 | */ | ||
76 | struct msm_kms_state { | ||
77 | struct drm_atomic_state base; | ||
78 | void *state; | ||
79 | }; | ||
80 | #define to_kms_state(x) container_of(x, struct msm_kms_state, base) | ||
81 | |||
68 | static inline void msm_kms_init(struct msm_kms *kms, | 82 | static inline void msm_kms_init(struct msm_kms *kms, |
69 | const struct msm_kms_funcs *funcs) | 83 | const struct msm_kms_funcs *funcs) |
70 | { | 84 | { |