From mboxrd@z Thu Jan 1 00:00:00 1970 From: Rob Clark Subject: [PATCH 2/5] drm/msm: subclass drm_atomic_state Date: Sat, 5 Nov 2016 12:25:58 -0400 Message-ID: <1478363161-29293-3-git-send-email-robdclark@gmail.com> References: <1478363161-29293-1-git-send-email-robdclark@gmail.com> Return-path: Received: from mail-qk0-f194.google.com ([209.85.220.194]:33290 "EHLO mail-qk0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755914AbcKEQ0Q (ORCPT ); Sat, 5 Nov 2016 12:26:16 -0400 Received: by mail-qk0-f194.google.com with SMTP id x190so8154671qkb.0 for ; Sat, 05 Nov 2016 09:26:15 -0700 (PDT) In-Reply-To: <1478363161-29293-1-git-send-email-robdclark@gmail.com> Sender: linux-arm-msm-owner@vger.kernel.org List-Id: linux-arm-msm@vger.kernel.org To: dri-devel@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, Archit Taneja , Daniel Vetter , Sean Paul , Rob Clark This will give the kms backends a slot to stash their own hw specific global state. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_atomic.c | 31 +++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/msm_drv.c | 3 +++ drivers/gpu/drm/msm/msm_drv.h | 3 +++ drivers/gpu/drm/msm/msm_kms.h | 14 ++++++++++++++ 4 files changed, 51 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 4e21e1d..30b5d23 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, drm_atomic_helper_swap_state(state, true); + /* swap driver private state while still holding state_lock */ + if (to_kms_state(state)->state) + priv->kms->funcs->swap_state(priv->kms, state); + /* * Everything below can be run asynchronously without the need to grab * any modeset locks at all under one conditions: It must be guaranteed @@ -271,3 +275,30 @@ error: drm_atomic_helper_cleanup_planes(dev, state); return ret; } + +struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev) +{ + struct msm_kms_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + + if (!state || drm_atomic_state_init(dev, &state->base) < 0) { + kfree(state); + return NULL; + } + + return &state->base; +} + +void msm_atomic_state_clear(struct drm_atomic_state *s) +{ + struct msm_kms_state *state = to_kms_state(s); + drm_atomic_state_default_clear(&state->base); + kfree(state->state); + state->state = NULL; +} + +void msm_atomic_state_free(struct drm_atomic_state *state) +{ + kfree(to_kms_state(state)->state); + drm_atomic_state_default_release(state); + kfree(state); +} diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 0f4409d..57cba3f 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 = { .output_poll_changed = msm_fb_output_poll_changed, .atomic_check = msm_atomic_check, .atomic_commit = msm_atomic_commit, + .atomic_state_alloc = msm_atomic_state_alloc, + .atomic_state_clear = msm_atomic_state_clear, + .atomic_state_free = msm_atomic_state_free, }; 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 03ce6a18..175b2bf 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, struct drm_atomic_state *state); int msm_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock); +struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev); +void msm_atomic_state_clear(struct drm_atomic_state *state); +void msm_atomic_state_free(struct drm_atomic_state *state); int msm_register_address_space(struct drm_device *dev, 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 40e41e5..cb9758b 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 { irqreturn_t (*irq)(struct msm_kms *kms); int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); + /* swap global atomic state: */ + void (*swap_state)(struct msm_kms *kms, struct drm_atomic_state *state); /* modeset, bracketing atomic_commit(): */ void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state); void (*complete_commit)(struct msm_kms *kms, struct drm_atomic_state *state); @@ -65,6 +67,18 @@ struct msm_kms { int irq; }; +/** + * Subclass of drm_atomic_state, to allow kms backend to have driver + * private global state. The kms backend can do whatever it wants + * with the ->state ptr. On ->atomic_state_clear() the ->state ptr + * is kfree'd and set back to NULL. + */ +struct msm_kms_state { + struct drm_atomic_state base; + void *state; +}; +#define to_kms_state(x) container_of(x, struct msm_kms_state, base) + static inline void msm_kms_init(struct msm_kms *kms, const struct msm_kms_funcs *funcs) { -- 2.7.4