aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2016-11-04 13:51:42 -0400
committerRob Clark <robdclark@gmail.com>2016-11-27 11:32:27 -0500
commit870d738acb7ebb0d4f6192c9d328cae95479715b (patch)
tree9d8ad211c6b5d82cfb2cf4122a99ffc81c9c3f23
parentc056b55dc672cbc42e8814ef45726ca22e01ef9e (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.c31
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c3
-rw-r--r--drivers/gpu/drm/msm/msm_drv.h3
-rw-r--r--drivers/gpu/drm/msm/msm_kms.h14
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
279struct 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
291void 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
299void 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
51int msm_register_address_space(struct drm_device *dev, 54int 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);
180int msm_atomic_commit(struct drm_device *dev, 180int msm_atomic_commit(struct drm_device *dev,
181 struct drm_atomic_state *state, bool nonblock); 181 struct drm_atomic_state *state, bool nonblock);
182struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev);
183void msm_atomic_state_clear(struct drm_atomic_state *state);
184void msm_atomic_state_free(struct drm_atomic_state *state);
182 185
183int msm_register_address_space(struct drm_device *dev, 186int 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 */
76struct 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
68static inline void msm_kms_init(struct msm_kms *kms, 82static 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{