All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/3] drm/msm: Avoid subclassing of drm_atomic_state
@ 2017-12-21  6:14 Archit Taneja
  2017-12-21  6:14 ` [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object Archit Taneja
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Archit Taneja @ 2017-12-21  6:14 UTC (permalink / raw)
  To: robdclark; +Cc: linux-arm-msm, dri-devel, dhinakaran.pandiyan

It's been recommended that we use drm_private_objs embedded in
drm_atomic_state to hold shared resources instead of subclassing
drm_atomic_state.

This will also help us in getting one step closer to using the
atomic commit helpers instead of the msm_atomic_commit() funcs
in msm_atomic.c

I've taken the drm_private_obj usage in drm_dp_mst_topology as
reference. I've put this as RFC because I want others to see if
the private_obj stuff is used correctly.

Archit Taneja (3):
  drm/msm/mdp5: Add global state as a private atomic object
  drm/msm/mdp5: Use the new private_obj state
  drm/msm: Don't subclass drm_atomic_state anymore

 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c   | 104 +++++++++++++++++++++---------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h   |  29 +++++----
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_mixer.c |  12 ++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c  |  20 +++---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c   |  17 +++--
 drivers/gpu/drm/msm/msm_atomic.c          |  31 ---------
 drivers/gpu/drm/msm/msm_drv.c             |   3 -
 drivers/gpu/drm/msm/msm_kms.h             |  14 ----
 8 files changed, 121 insertions(+), 109 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object
  2017-12-21  6:14 [RFC 0/3] drm/msm: Avoid subclassing of drm_atomic_state Archit Taneja
@ 2017-12-21  6:14 ` Archit Taneja
  2017-12-21  9:56   ` Daniel Vetter
  2017-12-21  6:14 ` [RFC 2/3] drm/msm/mdp5: Use the new private_obj state Archit Taneja
  2017-12-21  6:14 ` [RFC 3/3] drm/msm: Don't subclass drm_atomic_state anymore Archit Taneja
  2 siblings, 1 reply; 8+ messages in thread
From: Archit Taneja @ 2017-12-21  6:14 UTC (permalink / raw)
  To: robdclark
  Cc: dri-devel, linux-arm-msm, daniel, dhinakaran.pandiyan,
	Archit Taneja

Global shared resources (hwpipes, hwmixers and SMP) for MDP5 are
implemented as a part of atomic state by subclassing drm_atomic_state.

The preferred approach is to use the drm_private_obj infrastructure
available in the atomic core.

mdp5_global_state is introduced as a drm atomic private object. The two
funcs mdp5_get_global_state() and mdp5_get_existing_global_state() are
the two variants that will be used to access mdp5_global_state.

This will replace the existing mdp5_state struct (which subclasses
drm_atomic_state) and the funcs around it. These will be removed later
once we mdp5_global_state is put to use everywhere.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 86 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 27 +++++++++++
 2 files changed, 113 insertions(+)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index f7c0698fec40..dfc4d81124d5 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -106,6 +106,86 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
 	swap(to_kms_state(state)->state, mdp5_kms->state);
 }
 
+/* Global/shared object state funcs */
+
+/*
+ * This is a helper that returns the private state currently in operation.
+ * Note that this would return the "old_state" if called in the atomic check
+ * path, and the "new_state" after the atomic swap has been done.
+ */
+struct mdp5_global_state *
+mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms)
+{
+	return to_mdp5_global_state(mdp5_kms->glob_base.state);
+}
+
+/*
+ * This acquires the modeset lock set aside for global state, creates
+ * a new duplicated private object state.
+ */
+struct mdp5_global_state *mdp5_get_global_state(struct drm_atomic_state *s)
+{
+	struct msm_drm_private *priv = s->dev->dev_private;
+	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
+	struct drm_private_state *priv_state;
+	int ret;
+
+	ret = drm_modeset_lock(&mdp5_kms->glob_state_lock, s->acquire_ctx);
+	if (ret)
+		return ERR_PTR(ret);
+
+	priv_state = drm_atomic_get_private_obj_state(s, &mdp5_kms->glob_base);
+	if (IS_ERR(priv_state))
+		return ERR_CAST(priv_state);
+
+	return to_mdp5_global_state(priv_state);
+}
+
+static struct drm_private_state *
+mdp5_global_duplicate_state(struct drm_private_obj *obj)
+{
+	struct mdp5_global_state *state;
+
+	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
+
+	return &state->base;
+}
+
+static void mdp5_global_destroy_state(struct drm_private_obj *obj,
+				      struct drm_private_state *state)
+{
+	struct mdp5_global_state *mdp5_state = to_mdp5_global_state(state);
+
+	kfree(mdp5_state);
+}
+
+static const struct drm_private_state_funcs mdp5_global_state_funcs = {
+	.atomic_duplicate_state = mdp5_global_duplicate_state,
+	.atomic_destroy_state = mdp5_global_destroy_state,
+};
+
+static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
+{
+	struct mdp5_global_state *state;
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	drm_modeset_lock_init(&mdp5_kms->glob_state_lock);
+
+	state->mdp5_kms = mdp5_kms;
+
+	drm_atomic_private_obj_init(&mdp5_kms->glob_base,
+				    &state->base,
+				    &mdp5_global_state_funcs);
+	return 0;
+}
+
 static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
@@ -727,6 +807,8 @@ static void mdp5_destroy(struct platform_device *pdev)
 	if (mdp5_kms->rpm_enabled)
 		pm_runtime_disable(&pdev->dev);
 
+	drm_atomic_private_obj_fini(&mdp5_kms->glob_base);
+
 	kfree(mdp5_kms->state);
 }
 
@@ -887,6 +969,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 		goto fail;
 	}
 
+	ret = mdp5_global_obj_init(mdp5_kms);
+	if (ret)
+		goto fail;
+
 	mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
 	if (IS_ERR(mdp5_kms->mmio)) {
 		ret = PTR_ERR(mdp5_kms->mmio);
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 9b3fe01089d1..522ddb835593 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -55,6 +55,13 @@ struct mdp5_kms {
 	struct mdp5_state *state;
 	struct drm_modeset_lock state_lock;
 
+	/*
+	 * Global private object state, Do not access directly, use
+	 * mdp5_global_get_state()
+	 */
+	struct drm_private_obj glob_base;
+	struct drm_modeset_lock glob_state_lock;
+
 	struct mdp5_smp *smp;
 	struct mdp5_ctl_manager *ctlm;
 
@@ -95,6 +102,26 @@ struct mdp5_state {
 struct mdp5_state *__must_check
 mdp5_get_state(struct drm_atomic_state *s);
 
+/* Global private object state for tracking resources that are shared across
+ * multiple kms objects (planes/crtcs/etc).
+ */
+#define to_mdp5_global_state(x) container_of(x, struct mdp5_global_state, base)
+struct mdp5_global_state {
+	struct drm_private_state base;
+
+	struct drm_atomic_state *state;
+	struct mdp5_kms *mdp5_kms;
+
+	struct mdp5_hw_pipe_state hwpipe;
+	struct mdp5_hw_mixer_state hwmixer;
+	struct mdp5_smp_state smp;
+};
+
+struct mdp5_global_state *
+mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms);
+struct mdp5_global_state *__must_check
+mdp5_get_global_state(struct drm_atomic_state *s);
+
 /* Atomic plane state.  Subclasses the base drm_plane_state in order to
  * track assigned hwpipe and hw specific state.
  */
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC 2/3] drm/msm/mdp5: Use the new private_obj state
  2017-12-21  6:14 [RFC 0/3] drm/msm: Avoid subclassing of drm_atomic_state Archit Taneja
  2017-12-21  6:14 ` [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object Archit Taneja
@ 2017-12-21  6:14 ` Archit Taneja
  2017-12-21  6:14 ` [RFC 3/3] drm/msm: Don't subclass drm_atomic_state anymore Archit Taneja
  2 siblings, 0 replies; 8+ messages in thread
From: Archit Taneja @ 2017-12-21  6:14 UTC (permalink / raw)
  To: robdclark
  Cc: dri-devel, linux-arm-msm, daniel, dhinakaran.pandiyan,
	Archit Taneja

This replaces the usage of the subclassed atomic state (mdp5_state)
with a private_obj state embedded within drm_atomic_state. The latter
method is the preferred approach, since it's simpler to implement
and less prone to errors.

The new API replaces the older and equivalent mdp5_state usage in the
following pattern:
- References to "mdp5_kms->state" (i.e, the old/existing state) is
  replaced with mdp5_get_existing_global_state(). In the atomic_check
  path, this should be called with the glob_state_lock drm_modeset_lock
  alredy taken.
- References to "mdp5_get_state()" are replaced with
  mdp5_get_global_state(). This acquires glob_state_lock and uses
  drm_atomic_get_private_obj_state() to create a new duplicated state.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c   | 10 ++++++++--
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_mixer.c | 12 ++++++------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c  | 20 +++++++++++---------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c   | 17 ++++++++++++-----
 4 files changed, 37 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index dfc4d81124d5..dabb58ad068c 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -190,20 +190,26 @@ static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *st
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 	struct device *dev = &mdp5_kms->pdev->dev;
+	struct mdp5_global_state *global_state;
+
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
 
 	pm_runtime_get_sync(dev);
 
 	if (mdp5_kms->smp)
-		mdp5_smp_prepare_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
+		mdp5_smp_prepare_commit(mdp5_kms->smp, &global_state->smp);
 }
 
 static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
 {
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
 	struct device *dev = &mdp5_kms->pdev->dev;
+	struct mdp5_global_state *global_state;
+
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
 
 	if (mdp5_kms->smp)
-		mdp5_smp_complete_commit(mdp5_kms->smp, &mdp5_kms->state->smp);
+		mdp5_smp_complete_commit(mdp5_kms->smp, &global_state->smp);
 
 	pm_runtime_put_autosuspend(dev);
 }
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mixer.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mixer.c
index 8a00991f03c7..113e6b569562 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mixer.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_mixer.c
@@ -52,14 +52,14 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
 {
 	struct msm_drm_private *priv = s->dev->dev_private;
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
-	struct mdp5_state *state = mdp5_get_state(s);
+	struct mdp5_global_state *global_state = mdp5_get_global_state(s);
 	struct mdp5_hw_mixer_state *new_state;
 	int i;
 
-	if (IS_ERR(state))
-		return PTR_ERR(state);
+	if (IS_ERR(global_state))
+		return PTR_ERR(global_state);
 
-	new_state = &state->hwmixer;
+	new_state = &global_state->hwmixer;
 
 	for (i = 0; i < mdp5_kms->num_hwmixers; i++) {
 		struct mdp5_hw_mixer *cur = mdp5_kms->hwmixers[i];
@@ -129,8 +129,8 @@ int mdp5_mixer_assign(struct drm_atomic_state *s, struct drm_crtc *crtc,
 
 void mdp5_mixer_release(struct drm_atomic_state *s, struct mdp5_hw_mixer *mixer)
 {
-	struct mdp5_state *state = mdp5_get_state(s);
-	struct mdp5_hw_mixer_state *new_state = &state->hwmixer;
+	struct mdp5_global_state *global_state = mdp5_get_global_state(s);
+	struct mdp5_hw_mixer_state *new_state = &global_state->hwmixer;
 
 	if (!mixer)
 		return;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c
index 2bfac3712685..88a8a86c95c7 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_pipe.c
@@ -22,18 +22,20 @@ struct mdp5_hw_pipe *mdp5_pipe_assign(struct drm_atomic_state *s,
 {
 	struct msm_drm_private *priv = s->dev->dev_private;
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
-	struct mdp5_state *state;
+	struct mdp5_global_state *new_global_state, *old_global_state;
 	struct mdp5_hw_pipe_state *old_state, *new_state;
 	struct mdp5_hw_pipe *hwpipe = NULL;
 	int i;
 
-	state = mdp5_get_state(s);
-	if (IS_ERR(state))
-		return ERR_CAST(state);
+	new_global_state = mdp5_get_global_state(s);
+	if (IS_ERR(new_global_state))
+		return ERR_CAST(new_global_state);
 
-	/* grab old_state after mdp5_get_state(), since now we hold lock: */
-	old_state = &mdp5_kms->state->hwpipe;
-	new_state = &state->hwpipe;
+	/* grab old_state after mdp5_get_global_state(), since now we hold lock: */
+	old_global_state = mdp5_get_existing_global_state(mdp5_kms);
+
+	old_state = &old_global_state->hwpipe;
+	new_state = &new_global_state->hwpipe;
 
 	for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
 		struct mdp5_hw_pipe *cur = mdp5_kms->hwpipes[i];
@@ -76,7 +78,7 @@ struct mdp5_hw_pipe *mdp5_pipe_assign(struct drm_atomic_state *s,
 		int ret;
 
 		DBG("%s: alloc SMP blocks", hwpipe->name);
-		ret = mdp5_smp_assign(mdp5_kms->smp, &state->smp,
+		ret = mdp5_smp_assign(mdp5_kms->smp, &new_global_state->smp,
 				hwpipe->pipe, blkcfg);
 		if (ret)
 			return ERR_PTR(-ENOMEM);
@@ -95,7 +97,7 @@ void mdp5_pipe_release(struct drm_atomic_state *s, struct mdp5_hw_pipe *hwpipe)
 {
 	struct msm_drm_private *priv = s->dev->dev_private;
 	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
-	struct mdp5_state *state = mdp5_get_state(s);
+	struct mdp5_global_state *state = mdp5_get_global_state(s);
 	struct mdp5_hw_pipe_state *new_state = &state->hwpipe;
 
 	if (!hwpipe)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
index ae4983d9d0a5..96c2b828dba4 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c
@@ -340,17 +340,20 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p)
 	struct mdp5_kms *mdp5_kms = get_kms(smp);
 	struct mdp5_hw_pipe_state *hwpstate;
 	struct mdp5_smp_state *state;
+	struct mdp5_global_state *global_state;
 	int total = 0, i, j;
 
 	drm_printf(p, "name\tinuse\tplane\n");
 	drm_printf(p, "----\t-----\t-----\n");
 
 	if (drm_can_sleep())
-		drm_modeset_lock(&mdp5_kms->state_lock, NULL);
+		drm_modeset_lock(&mdp5_kms->glob_state_lock, NULL);
+
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
 
 	/* grab these *after* we hold the state_lock */
-	hwpstate = &mdp5_kms->state->hwpipe;
-	state = &mdp5_kms->state->smp;
+	hwpstate = &global_state->hwpipe;
+	state = &global_state->smp;
 
 	for (i = 0; i < mdp5_kms->num_hwpipes; i++) {
 		struct mdp5_hw_pipe *hwpipe = mdp5_kms->hwpipes[i];
@@ -374,7 +377,7 @@ void mdp5_smp_dump(struct mdp5_smp *smp, struct drm_printer *p)
 			bitmap_weight(state->state, smp->blk_cnt));
 
 	if (drm_can_sleep())
-		drm_modeset_unlock(&mdp5_kms->state_lock);
+		drm_modeset_unlock(&mdp5_kms->glob_state_lock);
 }
 
 void mdp5_smp_destroy(struct mdp5_smp *smp)
@@ -384,7 +387,8 @@ void mdp5_smp_destroy(struct mdp5_smp *smp)
 
 struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, const struct mdp5_smp_block *cfg)
 {
-	struct mdp5_smp_state *state = &mdp5_kms->state->smp;
+	struct mdp5_smp_state *state;
+	struct mdp5_global_state *global_state;
 	struct mdp5_smp *smp = NULL;
 	int ret;
 
@@ -398,6 +402,9 @@ struct mdp5_smp *mdp5_smp_init(struct mdp5_kms *mdp5_kms, const struct mdp5_smp_
 	smp->blk_cnt = cfg->mmb_count;
 	smp->blk_size = cfg->mmb_size;
 
+	global_state = mdp5_get_existing_global_state(mdp5_kms);
+	state = &global_state->smp;
+
 	/* statically tied MMBs cannot be re-allocated: */
 	bitmap_copy(state->state, cfg->reserved_state, smp->blk_cnt);
 	memcpy(smp->reserved, cfg->reserved, sizeof(smp->reserved));
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC 3/3] drm/msm: Don't subclass drm_atomic_state anymore
  2017-12-21  6:14 [RFC 0/3] drm/msm: Avoid subclassing of drm_atomic_state Archit Taneja
  2017-12-21  6:14 ` [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object Archit Taneja
  2017-12-21  6:14 ` [RFC 2/3] drm/msm/mdp5: Use the new private_obj state Archit Taneja
@ 2017-12-21  6:14 ` Archit Taneja
  2 siblings, 0 replies; 8+ messages in thread
From: Archit Taneja @ 2017-12-21  6:14 UTC (permalink / raw)
  To: robdclark
  Cc: dri-devel, linux-arm-msm, daniel, dhinakaran.pandiyan,
	Archit Taneja

With the addition of "private_objs" in drm_atomic_state, we no longer
need to subclass drm_atomic_state to store state of share resources
that don't perfectly fit within planes/crtc/connector state information.
We can now save this state within drm_atomic_state itself using
the private objects.

Remove the infrastructure that allowed subclassing of drm_atomic_state
in the driver.

Signed-off-by: Archit Taneja <architt@codeaurora.org>
---
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 46 ---------------------------------
 drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 22 ----------------
 drivers/gpu/drm/msm/msm_atomic.c        | 31 ----------------------
 drivers/gpu/drm/msm/msm_drv.c           |  3 ---
 drivers/gpu/drm/msm/msm_kms.h           | 14 ----------
 5 files changed, 116 deletions(-)

diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index dabb58ad068c..c42a77713d74 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -70,42 +70,6 @@ static int mdp5_hw_init(struct msm_kms *kms)
 	return 0;
 }
 
-struct mdp5_state *mdp5_get_state(struct drm_atomic_state *s)
-{
-	struct msm_drm_private *priv = s->dev->dev_private;
-	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
-	struct msm_kms_state *state = to_kms_state(s);
-	struct mdp5_state *new_state;
-	int ret;
-
-	if (state->state)
-		return state->state;
-
-	ret = drm_modeset_lock(&mdp5_kms->state_lock, s->acquire_ctx);
-	if (ret)
-		return ERR_PTR(ret);
-
-	new_state = kmalloc(sizeof(*mdp5_kms->state), GFP_KERNEL);
-	if (!new_state)
-		return ERR_PTR(-ENOMEM);
-
-	/* Copy state: */
-	new_state->hwpipe = mdp5_kms->state->hwpipe;
-	new_state->hwmixer = mdp5_kms->state->hwmixer;
-	if (mdp5_kms->smp)
-		new_state->smp = mdp5_kms->state->smp;
-
-	state->state = new_state;
-
-	return new_state;
-}
-
-static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
-{
-	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
-	swap(to_kms_state(state)->state, mdp5_kms->state);
-}
-
 /* Global/shared object state funcs */
 
 /*
@@ -315,7 +279,6 @@ static const struct mdp_kms_funcs kms_funcs = {
 		.irq             = mdp5_irq,
 		.enable_vblank   = mdp5_enable_vblank,
 		.disable_vblank  = mdp5_disable_vblank,
-		.swap_state      = mdp5_swap_state,
 		.prepare_commit  = mdp5_prepare_commit,
 		.complete_commit = mdp5_complete_commit,
 		.wait_for_crtc_commit_done = mdp5_wait_for_crtc_commit_done,
@@ -814,8 +777,6 @@ static void mdp5_destroy(struct platform_device *pdev)
 		pm_runtime_disable(&pdev->dev);
 
 	drm_atomic_private_obj_fini(&mdp5_kms->glob_base);
-
-	kfree(mdp5_kms->state);
 }
 
 static int construct_pipes(struct mdp5_kms *mdp5_kms, int cnt,
@@ -968,13 +929,6 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
 	mdp5_kms->dev = dev;
 	mdp5_kms->pdev = pdev;
 
-	drm_modeset_lock_init(&mdp5_kms->state_lock);
-	mdp5_kms->state = kzalloc(sizeof(*mdp5_kms->state), GFP_KERNEL);
-	if (!mdp5_kms->state) {
-		ret = -ENOMEM;
-		goto fail;
-	}
-
 	ret = mdp5_global_obj_init(mdp5_kms);
 	if (ret)
 		goto fail;
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 522ddb835593..6b9a7d091606 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -28,8 +28,6 @@
 #include "mdp5_ctl.h"
 #include "mdp5_smp.h"
 
-struct mdp5_state;
-
 struct mdp5_kms {
 	struct mdp_kms base;
 
@@ -49,12 +47,6 @@ struct mdp5_kms {
 	struct mdp5_cfg_handler *cfg;
 	uint32_t caps;	/* MDP capabilities (MDP_CAP_XXX bits) */
 
-	/**
-	 * Global atomic state.  Do not access directly, use mdp5_get_state()
-	 */
-	struct mdp5_state *state;
-	struct drm_modeset_lock state_lock;
-
 	/*
 	 * Global private object state, Do not access directly, use
 	 * mdp5_global_get_state()
@@ -88,20 +80,6 @@ struct mdp5_kms {
 };
 #define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base)
 
-/* Global atomic state for tracking resources that are shared across
- * multiple kms objects (planes/crtcs/etc).
- *
- * For atomic updates which require modifying global state,
- */
-struct mdp5_state {
-	struct mdp5_hw_pipe_state hwpipe;
-	struct mdp5_hw_mixer_state hwmixer;
-	struct mdp5_smp_state smp;
-};
-
-struct mdp5_state *__must_check
-mdp5_get_state(struct drm_atomic_state *s);
-
 /* Global private object state for tracking resources that are shared across
  * multiple kms objects (planes/crtcs/etc).
  */
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 025d454163b0..96a8f6a4c8eb 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -241,11 +241,7 @@ int msm_atomic_commit(struct drm_device *dev,
 	 * This is the point of no return - everything below never fails except
 	 * when the hw goes bonghits. Which means we can commit the new state on
 	 * the software side now.
-	 *
-	 * 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
@@ -279,30 +275,3 @@ int msm_atomic_commit(struct drm_device *dev,
 	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 606df7bea97b..5c5f7dd7e64d 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -46,9 +46,6 @@ 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,
 };
 
 #ifdef CONFIG_DRM_MSM_REGISTER_LOGGING
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h
index 17d5824417ad..f0842b963df1 100644
--- a/drivers/gpu/drm/msm/msm_kms.h
+++ b/drivers/gpu/drm/msm/msm_kms.h
@@ -40,8 +40,6 @@ 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);
@@ -77,18 +75,6 @@ struct msm_kms {
 	struct msm_gem_address_space *aspace;
 };
 
-/**
- * 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)
 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object
  2017-12-21  6:14 ` [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object Archit Taneja
@ 2017-12-21  9:56   ` Daniel Vetter
  2018-01-03 11:32     ` Archit Taneja
  2018-02-20 20:05     ` Rob Clark
  0 siblings, 2 replies; 8+ messages in thread
From: Daniel Vetter @ 2017-12-21  9:56 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-arm-msm, dri-devel, dhinakaran.pandiyan

On Thu, Dec 21, 2017 at 11:44:23AM +0530, Archit Taneja wrote:
> Global shared resources (hwpipes, hwmixers and SMP) for MDP5 are
> implemented as a part of atomic state by subclassing drm_atomic_state.
> 
> The preferred approach is to use the drm_private_obj infrastructure
> available in the atomic core.
> 
> mdp5_global_state is introduced as a drm atomic private object. The two
> funcs mdp5_get_global_state() and mdp5_get_existing_global_state() are
> the two variants that will be used to access mdp5_global_state.
> 
> This will replace the existing mdp5_state struct (which subclasses
> drm_atomic_state) and the funcs around it. These will be removed later
> once we mdp5_global_state is put to use everywhere.
> 
> Signed-off-by: Archit Taneja <architt@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 86 +++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 27 +++++++++++
>  2 files changed, 113 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> index f7c0698fec40..dfc4d81124d5 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
> @@ -106,6 +106,86 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
>  	swap(to_kms_state(state)->state, mdp5_kms->state);
>  }
>  
> +/* Global/shared object state funcs */
> +
> +/*
> + * This is a helper that returns the private state currently in operation.
> + * Note that this would return the "old_state" if called in the atomic check
> + * path, and the "new_state" after the atomic swap has been done.
> + */
> +struct mdp5_global_state *
> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms)
> +{
> +	return to_mdp5_global_state(mdp5_kms->glob_base.state);

This doesn't match the existing state stuff for everything else. Here you
look at the global state, but not at the one hanging off drm_atomic_state.

Maybe we should add a drm_atomic_get_existing_private_obj_state function
to make this easier?

I'm also not 100% sure on what semantics you want precisely.


> +}
> +
> +/*
> + * This acquires the modeset lock set aside for global state, creates
> + * a new duplicated private object state.
> + */
> +struct mdp5_global_state *mdp5_get_global_state(struct drm_atomic_state *s)
> +{
> +	struct msm_drm_private *priv = s->dev->dev_private;
> +	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
> +	struct drm_private_state *priv_state;
> +	int ret;
> +
> +	ret = drm_modeset_lock(&mdp5_kms->glob_state_lock, s->acquire_ctx);
> +	if (ret)
> +		return ERR_PTR(ret);
> +
> +	priv_state = drm_atomic_get_private_obj_state(s, &mdp5_kms->glob_base);
> +	if (IS_ERR(priv_state))
> +		return ERR_CAST(priv_state);
> +
> +	return to_mdp5_global_state(priv_state);
> +}
> +
> +static struct drm_private_state *
> +mdp5_global_duplicate_state(struct drm_private_obj *obj)
> +{
> +	struct mdp5_global_state *state;
> +
> +	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
> +	if (!state)
> +		return NULL;
> +
> +	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
> +
> +	return &state->base;
> +}
> +
> +static void mdp5_global_destroy_state(struct drm_private_obj *obj,
> +				      struct drm_private_state *state)
> +{
> +	struct mdp5_global_state *mdp5_state = to_mdp5_global_state(state);
> +
> +	kfree(mdp5_state);
> +}
> +
> +static const struct drm_private_state_funcs mdp5_global_state_funcs = {
> +	.atomic_duplicate_state = mdp5_global_duplicate_state,
> +	.atomic_destroy_state = mdp5_global_destroy_state,
> +};
> +
> +static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
> +{
> +	struct mdp5_global_state *state;
> +
> +	state = kzalloc(sizeof(*state), GFP_KERNEL);
> +	if (!state)
> +		return -ENOMEM;
> +
> +	drm_modeset_lock_init(&mdp5_kms->glob_state_lock);

I thought a bit the last few days about how to integrate modeset locking
into driver private state objects. I think the simplest solution would be
if we just add a drm_modeset_lock to drm_private_obj, and push the locking
(both here and in the mst helper) into the core private obj code.

Per-object locking might be a bit overkill (it's definitely overkill for
mst), but it's also easier to avoid special cases.

That would reduce the boilerplate here a bit more, essentially converting
the wrappers into type casting functions.
-Daniel

> +
> +	state->mdp5_kms = mdp5_kms;
> +
> +	drm_atomic_private_obj_init(&mdp5_kms->glob_base,
> +				    &state->base,
> +				    &mdp5_global_state_funcs);
> +	return 0;
> +}
> +
>  static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
>  {
>  	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
> @@ -727,6 +807,8 @@ static void mdp5_destroy(struct platform_device *pdev)
>  	if (mdp5_kms->rpm_enabled)
>  		pm_runtime_disable(&pdev->dev);
>  
> +	drm_atomic_private_obj_fini(&mdp5_kms->glob_base);
> +
>  	kfree(mdp5_kms->state);
>  }
>  
> @@ -887,6 +969,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
>  		goto fail;
>  	}
>  
> +	ret = mdp5_global_obj_init(mdp5_kms);
> +	if (ret)
> +		goto fail;
> +
>  	mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
>  	if (IS_ERR(mdp5_kms->mmio)) {
>  		ret = PTR_ERR(mdp5_kms->mmio);
> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
> index 9b3fe01089d1..522ddb835593 100644
> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
> @@ -55,6 +55,13 @@ struct mdp5_kms {
>  	struct mdp5_state *state;
>  	struct drm_modeset_lock state_lock;
>  
> +	/*
> +	 * Global private object state, Do not access directly, use
> +	 * mdp5_global_get_state()
> +	 */
> +	struct drm_private_obj glob_base;
> +	struct drm_modeset_lock glob_state_lock;
> +
>  	struct mdp5_smp *smp;
>  	struct mdp5_ctl_manager *ctlm;
>  
> @@ -95,6 +102,26 @@ struct mdp5_state {
>  struct mdp5_state *__must_check
>  mdp5_get_state(struct drm_atomic_state *s);
>  
> +/* Global private object state for tracking resources that are shared across
> + * multiple kms objects (planes/crtcs/etc).
> + */
> +#define to_mdp5_global_state(x) container_of(x, struct mdp5_global_state, base)
> +struct mdp5_global_state {
> +	struct drm_private_state base;
> +
> +	struct drm_atomic_state *state;
> +	struct mdp5_kms *mdp5_kms;
> +
> +	struct mdp5_hw_pipe_state hwpipe;
> +	struct mdp5_hw_mixer_state hwmixer;
> +	struct mdp5_smp_state smp;
> +};
> +
> +struct mdp5_global_state *
> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms);
> +struct mdp5_global_state *__must_check
> +mdp5_get_global_state(struct drm_atomic_state *s);
> +
>  /* Atomic plane state.  Subclasses the base drm_plane_state in order to
>   * track assigned hwpipe and hw specific state.
>   */
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object
  2017-12-21  9:56   ` Daniel Vetter
@ 2018-01-03 11:32     ` Archit Taneja
  2018-01-03 21:34       ` Rob Clark
  2018-02-20 20:05     ` Rob Clark
  1 sibling, 1 reply; 8+ messages in thread
From: Archit Taneja @ 2018-01-03 11:32 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: linux-arm-msm, dhinakaran.pandiyan, dri-devel



On 12/21/2017 03:26 PM, Daniel Vetter wrote:
> On Thu, Dec 21, 2017 at 11:44:23AM +0530, Archit Taneja wrote:
>> Global shared resources (hwpipes, hwmixers and SMP) for MDP5 are
>> implemented as a part of atomic state by subclassing drm_atomic_state.
>>
>> The preferred approach is to use the drm_private_obj infrastructure
>> available in the atomic core.
>>
>> mdp5_global_state is introduced as a drm atomic private object. The two
>> funcs mdp5_get_global_state() and mdp5_get_existing_global_state() are
>> the two variants that will be used to access mdp5_global_state.
>>
>> This will replace the existing mdp5_state struct (which subclasses
>> drm_atomic_state) and the funcs around it. These will be removed later
>> once we mdp5_global_state is put to use everywhere.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>   drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 86 +++++++++++++++++++++++++++++++++
>>   drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 27 +++++++++++
>>   2 files changed, 113 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>> index f7c0698fec40..dfc4d81124d5 100644
>> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>> @@ -106,6 +106,86 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
>>   	swap(to_kms_state(state)->state, mdp5_kms->state);
>>   }
>>   
>> +/* Global/shared object state funcs */
>> +
>> +/*
>> + * This is a helper that returns the private state currently in operation.
>> + * Note that this would return the "old_state" if called in the atomic check
>> + * path, and the "new_state" after the atomic swap has been done.
>> + */
>> +struct mdp5_global_state *
>> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms)
>> +{
>> +	return to_mdp5_global_state(mdp5_kms->glob_base.state);
> 
> This doesn't match the existing state stuff for everything else. Here you
> look at the global state, but not at the one hanging off drm_atomic_state.
> 
> Maybe we should add a drm_atomic_get_existing_private_obj_state function
> to make this easier?
> 
> I'm also not 100% sure on what semantics you want precisely.

I just wanted a func that returns me the private obj's state that is currently
"in use". I.e, the old state pre-swap, and the new state post-swap. If I use
drm_atomic_get_private_obj_state() after the swap has occurred, I get the old
state back. In other words, there aren't funcs for private objs like
drm_atomic_get_new_crtc_state() and drm_atomic_get_old_crtc_state() that we
can use. I'll go through the code again carefully to see if my understanding
isn't screwed up.

> 
> 
>> +}
>> +
>> +/*
>> + * This acquires the modeset lock set aside for global state, creates
>> + * a new duplicated private object state.
>> + */
>> +struct mdp5_global_state *mdp5_get_global_state(struct drm_atomic_state *s)
>> +{
>> +	struct msm_drm_private *priv = s->dev->dev_private;
>> +	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
>> +	struct drm_private_state *priv_state;
>> +	int ret;
>> +
>> +	ret = drm_modeset_lock(&mdp5_kms->glob_state_lock, s->acquire_ctx);
>> +	if (ret)
>> +		return ERR_PTR(ret);
>> +
>> +	priv_state = drm_atomic_get_private_obj_state(s, &mdp5_kms->glob_base);
>> +	if (IS_ERR(priv_state))
>> +		return ERR_CAST(priv_state);
>> +
>> +	return to_mdp5_global_state(priv_state);
>> +}
>> +
>> +static struct drm_private_state *
>> +mdp5_global_duplicate_state(struct drm_private_obj *obj)
>> +{
>> +	struct mdp5_global_state *state;
>> +
>> +	state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
>> +	if (!state)
>> +		return NULL;
>> +
>> +	__drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
>> +
>> +	return &state->base;
>> +}
>> +
>> +static void mdp5_global_destroy_state(struct drm_private_obj *obj,
>> +				      struct drm_private_state *state)
>> +{
>> +	struct mdp5_global_state *mdp5_state = to_mdp5_global_state(state);
>> +
>> +	kfree(mdp5_state);
>> +}
>> +
>> +static const struct drm_private_state_funcs mdp5_global_state_funcs = {
>> +	.atomic_duplicate_state = mdp5_global_duplicate_state,
>> +	.atomic_destroy_state = mdp5_global_destroy_state,
>> +};
>> +
>> +static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
>> +{
>> +	struct mdp5_global_state *state;
>> +
>> +	state = kzalloc(sizeof(*state), GFP_KERNEL);
>> +	if (!state)
>> +		return -ENOMEM;
>> +
>> +	drm_modeset_lock_init(&mdp5_kms->glob_state_lock);
> 
> I thought a bit the last few days about how to integrate modeset locking
> into driver private state objects. I think the simplest solution would be
> if we just add a drm_modeset_lock to drm_private_obj, and push the locking
> (both here and in the mst helper) into the core private obj code.

I'm also a bit unclear on how many private objs one should create. In this patchset,
I just create one private obj instance, and stuff all of our shared resources into
it (see mdp5_global_state below). I didn't see the point in creating one priv object
per shared resource, since a single lock for all of them seemed okay here.

Thanks,
Archit

> 
> Per-object locking might be a bit overkill (it's definitely overkill for
> mst), but it's also easier to avoid special cases.
> 
> That would reduce the boilerplate here a bit more, essentially converting
> the wrappers into type casting functions.
> -Daniel
> 
>> +
>> +	state->mdp5_kms = mdp5_kms;
>> +
>> +	drm_atomic_private_obj_init(&mdp5_kms->glob_base,
>> +				    &state->base,
>> +				    &mdp5_global_state_funcs);
>> +	return 0;
>> +}
>> +
>>   static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
>>   {
>>   	struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
>> @@ -727,6 +807,8 @@ static void mdp5_destroy(struct platform_device *pdev)
>>   	if (mdp5_kms->rpm_enabled)
>>   		pm_runtime_disable(&pdev->dev);
>>   
>> +	drm_atomic_private_obj_fini(&mdp5_kms->glob_base);
>> +
>>   	kfree(mdp5_kms->state);
>>   }
>>   
>> @@ -887,6 +969,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
>>   		goto fail;
>>   	}
>>   
>> +	ret = mdp5_global_obj_init(mdp5_kms);
>> +	if (ret)
>> +		goto fail;
>> +
>>   	mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
>>   	if (IS_ERR(mdp5_kms->mmio)) {
>>   		ret = PTR_ERR(mdp5_kms->mmio);
>> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>> index 9b3fe01089d1..522ddb835593 100644
>> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>> @@ -55,6 +55,13 @@ struct mdp5_kms {
>>   	struct mdp5_state *state;
>>   	struct drm_modeset_lock state_lock;
>>   
>> +	/*
>> +	 * Global private object state, Do not access directly, use
>> +	 * mdp5_global_get_state()
>> +	 */
>> +	struct drm_private_obj glob_base;
>> +	struct drm_modeset_lock glob_state_lock;
>> +
>>   	struct mdp5_smp *smp;
>>   	struct mdp5_ctl_manager *ctlm;
>>   
>> @@ -95,6 +102,26 @@ struct mdp5_state {
>>   struct mdp5_state *__must_check
>>   mdp5_get_state(struct drm_atomic_state *s);
>>   
>> +/* Global private object state for tracking resources that are shared across
>> + * multiple kms objects (planes/crtcs/etc).
>> + */
>> +#define to_mdp5_global_state(x) container_of(x, struct mdp5_global_state, base)
>> +struct mdp5_global_state {
>> +	struct drm_private_state base;
>> +
>> +	struct drm_atomic_state *state;
>> +	struct mdp5_kms *mdp5_kms;
>> +
>> +	struct mdp5_hw_pipe_state hwpipe;
>> +	struct mdp5_hw_mixer_state hwmixer;
>> +	struct mdp5_smp_state smp;
>> +};
>> +
>> +struct mdp5_global_state *
>> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms);
>> +struct mdp5_global_state *__must_check
>> +mdp5_get_global_state(struct drm_atomic_state *s);
>> +
>>   /* Atomic plane state.  Subclasses the base drm_plane_state in order to
>>    * track assigned hwpipe and hw specific state.
>>    */
>> -- 
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>> hosted by The Linux Foundation
>>
> 

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object
  2018-01-03 11:32     ` Archit Taneja
@ 2018-01-03 21:34       ` Rob Clark
  0 siblings, 0 replies; 8+ messages in thread
From: Rob Clark @ 2018-01-03 21:34 UTC (permalink / raw)
  To: Archit Taneja; +Cc: linux-arm-msm, dri-devel, dhinakaran.pandiyan

On Wed, Jan 3, 2018 at 6:32 AM, Archit Taneja <architt@codeaurora.org> wrote:
>
>
> On 12/21/2017 03:26 PM, Daniel Vetter wrote:
>>
>> On Thu, Dec 21, 2017 at 11:44:23AM +0530, Archit Taneja wrote:
>>>
>>> Global shared resources (hwpipes, hwmixers and SMP) for MDP5 are
>>> implemented as a part of atomic state by subclassing drm_atomic_state.
>>>
>>> The preferred approach is to use the drm_private_obj infrastructure
>>> available in the atomic core.
>>>
>>> mdp5_global_state is introduced as a drm atomic private object. The two
>>> funcs mdp5_get_global_state() and mdp5_get_existing_global_state() are
>>> the two variants that will be used to access mdp5_global_state.
>>>
>>> This will replace the existing mdp5_state struct (which subclasses
>>> drm_atomic_state) and the funcs around it. These will be removed later
>>> once we mdp5_global_state is put to use everywhere.
>>>
>>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>>> ---
>>>   drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 86
>>> +++++++++++++++++++++++++++++++++
>>>   drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 27 +++++++++++
>>>   2 files changed, 113 insertions(+)
>>>
>>> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>>> b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>>> index f7c0698fec40..dfc4d81124d5 100644
>>> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>>> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>>> @@ -106,6 +106,86 @@ static void mdp5_swap_state(struct msm_kms *kms,
>>> struct drm_atomic_state *state)
>>>         swap(to_kms_state(state)->state, mdp5_kms->state);
>>>   }
>>>   +/* Global/shared object state funcs */
>>> +
>>> +/*
>>> + * This is a helper that returns the private state currently in
>>> operation.
>>> + * Note that this would return the "old_state" if called in the atomic
>>> check
>>> + * path, and the "new_state" after the atomic swap has been done.
>>> + */
>>> +struct mdp5_global_state *
>>> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms)
>>> +{
>>> +       return to_mdp5_global_state(mdp5_kms->glob_base.state);
>>
>>
>> This doesn't match the existing state stuff for everything else. Here you
>> look at the global state, but not at the one hanging off drm_atomic_state.
>>
>> Maybe we should add a drm_atomic_get_existing_private_obj_state function
>> to make this easier?
>>
>> I'm also not 100% sure on what semantics you want precisely.
>
>
> I just wanted a func that returns me the private obj's state that is
> currently
> "in use". I.e, the old state pre-swap, and the new state post-swap. If I use
> drm_atomic_get_private_obj_state() after the swap has occurred, I get the
> old
> state back. In other words, there aren't funcs for private objs like
> drm_atomic_get_new_crtc_state() and drm_atomic_get_old_crtc_state() that we
> can use. I'll go through the code again carefully to see if my understanding
> isn't screwed up.
>
>
>>
>>
>>> +}
>>> +
>>> +/*
>>> + * This acquires the modeset lock set aside for global state, creates
>>> + * a new duplicated private object state.
>>> + */
>>> +struct mdp5_global_state *mdp5_get_global_state(struct drm_atomic_state
>>> *s)
>>> +{
>>> +       struct msm_drm_private *priv = s->dev->dev_private;
>>> +       struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
>>> +       struct drm_private_state *priv_state;
>>> +       int ret;
>>> +
>>> +       ret = drm_modeset_lock(&mdp5_kms->glob_state_lock,
>>> s->acquire_ctx);
>>> +       if (ret)
>>> +               return ERR_PTR(ret);
>>> +
>>> +       priv_state = drm_atomic_get_private_obj_state(s,
>>> &mdp5_kms->glob_base);
>>> +       if (IS_ERR(priv_state))
>>> +               return ERR_CAST(priv_state);
>>> +
>>> +       return to_mdp5_global_state(priv_state);
>>> +}
>>> +
>>> +static struct drm_private_state *
>>> +mdp5_global_duplicate_state(struct drm_private_obj *obj)
>>> +{
>>> +       struct mdp5_global_state *state;
>>> +
>>> +       state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
>>> +       if (!state)
>>> +               return NULL;
>>> +
>>> +       __drm_atomic_helper_private_obj_duplicate_state(obj,
>>> &state->base);
>>> +
>>> +       return &state->base;
>>> +}
>>> +
>>> +static void mdp5_global_destroy_state(struct drm_private_obj *obj,
>>> +                                     struct drm_private_state *state)
>>> +{
>>> +       struct mdp5_global_state *mdp5_state =
>>> to_mdp5_global_state(state);
>>> +
>>> +       kfree(mdp5_state);
>>> +}
>>> +
>>> +static const struct drm_private_state_funcs mdp5_global_state_funcs = {
>>> +       .atomic_duplicate_state = mdp5_global_duplicate_state,
>>> +       .atomic_destroy_state = mdp5_global_destroy_state,
>>> +};
>>> +
>>> +static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
>>> +{
>>> +       struct mdp5_global_state *state;
>>> +
>>> +       state = kzalloc(sizeof(*state), GFP_KERNEL);
>>> +       if (!state)
>>> +               return -ENOMEM;
>>> +
>>> +       drm_modeset_lock_init(&mdp5_kms->glob_state_lock);
>>
>>
>> I thought a bit the last few days about how to integrate modeset locking
>> into driver private state objects. I think the simplest solution would be
>> if we just add a drm_modeset_lock to drm_private_obj, and push the locking
>> (both here and in the mst helper) into the core private obj code.
>
>
> I'm also a bit unclear on how many private objs one should create. In this
> patchset,
> I just create one private obj instance, and stuff all of our shared
> resources into
> it (see mdp5_global_state below). I didn't see the point in creating one
> priv object
> per shared resource, since a single lock for all of them seemed okay here.
>

fwiw, with the current code, I stuck with just a single modeset lock,
since if you are re-assigning hwpipe's you are also re-assigning SMP
blocks.  Perhaps we should already split that into two now that we
added dynamic assignment of mixers.  (Ie. so a modeset on one output
wouldn't block pagefile on another.)

Maybe just separate private objects + locks for each thing would make
more sense than trying to micro-optimize the locking ;-)

BR,
-R

> Thanks,
> Archit
>
>
>>
>> Per-object locking might be a bit overkill (it's definitely overkill for
>> mst), but it's also easier to avoid special cases.
>>
>> That would reduce the boilerplate here a bit more, essentially converting
>> the wrappers into type casting functions.
>> -Daniel
>>
>>> +
>>> +       state->mdp5_kms = mdp5_kms;
>>> +
>>> +       drm_atomic_private_obj_init(&mdp5_kms->glob_base,
>>> +                                   &state->base,
>>> +                                   &mdp5_global_state_funcs);
>>> +       return 0;
>>> +}
>>> +
>>>   static void mdp5_prepare_commit(struct msm_kms *kms, struct
>>> drm_atomic_state *state)
>>>   {
>>>         struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
>>> @@ -727,6 +807,8 @@ static void mdp5_destroy(struct platform_device
>>> *pdev)
>>>         if (mdp5_kms->rpm_enabled)
>>>                 pm_runtime_disable(&pdev->dev);
>>>   +     drm_atomic_private_obj_fini(&mdp5_kms->glob_base);
>>> +
>>>         kfree(mdp5_kms->state);
>>>   }
>>>   @@ -887,6 +969,10 @@ static int mdp5_init(struct platform_device *pdev,
>>> struct drm_device *dev)
>>>                 goto fail;
>>>         }
>>>   +     ret = mdp5_global_obj_init(mdp5_kms);
>>> +       if (ret)
>>> +               goto fail;
>>> +
>>>         mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
>>>         if (IS_ERR(mdp5_kms->mmio)) {
>>>                 ret = PTR_ERR(mdp5_kms->mmio);
>>> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>>> b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>>> index 9b3fe01089d1..522ddb835593 100644
>>> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>>> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>>> @@ -55,6 +55,13 @@ struct mdp5_kms {
>>>         struct mdp5_state *state;
>>>         struct drm_modeset_lock state_lock;
>>>   +     /*
>>> +        * Global private object state, Do not access directly, use
>>> +        * mdp5_global_get_state()
>>> +        */
>>> +       struct drm_private_obj glob_base;
>>> +       struct drm_modeset_lock glob_state_lock;
>>> +
>>>         struct mdp5_smp *smp;
>>>         struct mdp5_ctl_manager *ctlm;
>>>   @@ -95,6 +102,26 @@ struct mdp5_state {
>>>   struct mdp5_state *__must_check
>>>   mdp5_get_state(struct drm_atomic_state *s);
>>>   +/* Global private object state for tracking resources that are shared
>>> across
>>> + * multiple kms objects (planes/crtcs/etc).
>>> + */
>>> +#define to_mdp5_global_state(x) container_of(x, struct
>>> mdp5_global_state, base)
>>> +struct mdp5_global_state {
>>> +       struct drm_private_state base;
>>> +
>>> +       struct drm_atomic_state *state;
>>> +       struct mdp5_kms *mdp5_kms;
>>> +
>>> +       struct mdp5_hw_pipe_state hwpipe;
>>> +       struct mdp5_hw_mixer_state hwmixer;
>>> +       struct mdp5_smp_state smp;
>>> +};
>>> +
>>> +struct mdp5_global_state *
>>> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms);
>>> +struct mdp5_global_state *__must_check
>>> +mdp5_get_global_state(struct drm_atomic_state *s);
>>> +
>>>   /* Atomic plane state.  Subclasses the base drm_plane_state in order to
>>>    * track assigned hwpipe and hw specific state.
>>>    */
>>> --
>>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora
>>> Forum,
>>> hosted by The Linux Foundation
>>>
>>
>
> --
> Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
> a Linux Foundation Collaborative Project
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object
  2017-12-21  9:56   ` Daniel Vetter
  2018-01-03 11:32     ` Archit Taneja
@ 2018-02-20 20:05     ` Rob Clark
  1 sibling, 0 replies; 8+ messages in thread
From: Rob Clark @ 2018-02-20 20:05 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: linux-arm-msm, dhinakaran.pandiyan, dri-devel

On Thu, Dec 21, 2017 at 4:56 AM, Daniel Vetter <daniel@ffwll.ch> wrote:
> On Thu, Dec 21, 2017 at 11:44:23AM +0530, Archit Taneja wrote:
>> Global shared resources (hwpipes, hwmixers and SMP) for MDP5 are
>> implemented as a part of atomic state by subclassing drm_atomic_state.
>>
>> The preferred approach is to use the drm_private_obj infrastructure
>> available in the atomic core.
>>
>> mdp5_global_state is introduced as a drm atomic private object. The two
>> funcs mdp5_get_global_state() and mdp5_get_existing_global_state() are
>> the two variants that will be used to access mdp5_global_state.
>>
>> This will replace the existing mdp5_state struct (which subclasses
>> drm_atomic_state) and the funcs around it. These will be removed later
>> once we mdp5_global_state is put to use everywhere.
>>
>> Signed-off-by: Archit Taneja <architt@codeaurora.org>
>> ---
>>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | 86 +++++++++++++++++++++++++++++++++
>>  drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | 27 +++++++++++
>>  2 files changed, 113 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>> index f7c0698fec40..dfc4d81124d5 100644
>> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
>> @@ -106,6 +106,86 @@ static void mdp5_swap_state(struct msm_kms *kms, struct drm_atomic_state *state)
>>       swap(to_kms_state(state)->state, mdp5_kms->state);
>>  }
>>
>> +/* Global/shared object state funcs */
>> +
>> +/*
>> + * This is a helper that returns the private state currently in operation.
>> + * Note that this would return the "old_state" if called in the atomic check
>> + * path, and the "new_state" after the atomic swap has been done.
>> + */
>> +struct mdp5_global_state *
>> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms)
>> +{
>> +     return to_mdp5_global_state(mdp5_kms->glob_base.state);
>
> This doesn't match the existing state stuff for everything else. Here you
> look at the global state, but not at the one hanging off drm_atomic_state.
>
> Maybe we should add a drm_atomic_get_existing_private_obj_state function
> to make this easier?
>
> I'm also not 100% sure on what semantics you want precisely.
>

This is used for read-only access to current state, a couple places in
atomic update post-swap (where
drm_atomic_get_existing_private_obj_state() would work, but also for
things like debugfs, where it wouldn't)..

Probably should const'ify the return value to make it clear that this
is read-only.

>
>> +}
>> +
>> +/*
>> + * This acquires the modeset lock set aside for global state, creates
>> + * a new duplicated private object state.
>> + */
>> +struct mdp5_global_state *mdp5_get_global_state(struct drm_atomic_state *s)
>> +{
>> +     struct msm_drm_private *priv = s->dev->dev_private;
>> +     struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(priv->kms));
>> +     struct drm_private_state *priv_state;
>> +     int ret;
>> +
>> +     ret = drm_modeset_lock(&mdp5_kms->glob_state_lock, s->acquire_ctx);
>> +     if (ret)
>> +             return ERR_PTR(ret);
>> +
>> +     priv_state = drm_atomic_get_private_obj_state(s, &mdp5_kms->glob_base);
>> +     if (IS_ERR(priv_state))
>> +             return ERR_CAST(priv_state);
>> +
>> +     return to_mdp5_global_state(priv_state);
>> +}
>> +
>> +static struct drm_private_state *
>> +mdp5_global_duplicate_state(struct drm_private_obj *obj)
>> +{
>> +     struct mdp5_global_state *state;
>> +
>> +     state = kmemdup(obj->state, sizeof(*state), GFP_KERNEL);
>> +     if (!state)
>> +             return NULL;
>> +
>> +     __drm_atomic_helper_private_obj_duplicate_state(obj, &state->base);
>> +
>> +     return &state->base;
>> +}
>> +
>> +static void mdp5_global_destroy_state(struct drm_private_obj *obj,
>> +                                   struct drm_private_state *state)
>> +{
>> +     struct mdp5_global_state *mdp5_state = to_mdp5_global_state(state);
>> +
>> +     kfree(mdp5_state);
>> +}
>> +
>> +static const struct drm_private_state_funcs mdp5_global_state_funcs = {
>> +     .atomic_duplicate_state = mdp5_global_duplicate_state,
>> +     .atomic_destroy_state = mdp5_global_destroy_state,
>> +};
>> +
>> +static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms)
>> +{
>> +     struct mdp5_global_state *state;
>> +
>> +     state = kzalloc(sizeof(*state), GFP_KERNEL);
>> +     if (!state)
>> +             return -ENOMEM;
>> +
>> +     drm_modeset_lock_init(&mdp5_kms->glob_state_lock);
>
> I thought a bit the last few days about how to integrate modeset locking
> into driver private state objects. I think the simplest solution would be
> if we just add a drm_modeset_lock to drm_private_obj, and push the locking
> (both here and in the mst helper) into the core private obj code.

I like the idea of adding a modeset lock to private objs.. I've got a
WIP patch to do this.

BR,
-R

> Per-object locking might be a bit overkill (it's definitely overkill for
> mst), but it's also easier to avoid special cases.
>
> That would reduce the boilerplate here a bit more, essentially converting
> the wrappers into type casting functions.
> -Daniel
>
>> +
>> +     state->mdp5_kms = mdp5_kms;
>> +
>> +     drm_atomic_private_obj_init(&mdp5_kms->glob_base,
>> +                                 &state->base,
>> +                                 &mdp5_global_state_funcs);
>> +     return 0;
>> +}
>> +
>>  static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
>>  {
>>       struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
>> @@ -727,6 +807,8 @@ static void mdp5_destroy(struct platform_device *pdev)
>>       if (mdp5_kms->rpm_enabled)
>>               pm_runtime_disable(&pdev->dev);
>>
>> +     drm_atomic_private_obj_fini(&mdp5_kms->glob_base);
>> +
>>       kfree(mdp5_kms->state);
>>  }
>>
>> @@ -887,6 +969,10 @@ static int mdp5_init(struct platform_device *pdev, struct drm_device *dev)
>>               goto fail;
>>       }
>>
>> +     ret = mdp5_global_obj_init(mdp5_kms);
>> +     if (ret)
>> +             goto fail;
>> +
>>       mdp5_kms->mmio = msm_ioremap(pdev, "mdp_phys", "MDP5");
>>       if (IS_ERR(mdp5_kms->mmio)) {
>>               ret = PTR_ERR(mdp5_kms->mmio);
>> diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>> index 9b3fe01089d1..522ddb835593 100644
>> --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>> +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
>> @@ -55,6 +55,13 @@ struct mdp5_kms {
>>       struct mdp5_state *state;
>>       struct drm_modeset_lock state_lock;
>>
>> +     /*
>> +      * Global private object state, Do not access directly, use
>> +      * mdp5_global_get_state()
>> +      */
>> +     struct drm_private_obj glob_base;
>> +     struct drm_modeset_lock glob_state_lock;
>> +
>>       struct mdp5_smp *smp;
>>       struct mdp5_ctl_manager *ctlm;
>>
>> @@ -95,6 +102,26 @@ struct mdp5_state {
>>  struct mdp5_state *__must_check
>>  mdp5_get_state(struct drm_atomic_state *s);
>>
>> +/* Global private object state for tracking resources that are shared across
>> + * multiple kms objects (planes/crtcs/etc).
>> + */
>> +#define to_mdp5_global_state(x) container_of(x, struct mdp5_global_state, base)
>> +struct mdp5_global_state {
>> +     struct drm_private_state base;
>> +
>> +     struct drm_atomic_state *state;
>> +     struct mdp5_kms *mdp5_kms;
>> +
>> +     struct mdp5_hw_pipe_state hwpipe;
>> +     struct mdp5_hw_mixer_state hwmixer;
>> +     struct mdp5_smp_state smp;
>> +};
>> +
>> +struct mdp5_global_state *
>> +mdp5_get_existing_global_state(struct mdp5_kms *mdp5_kms);
>> +struct mdp5_global_state *__must_check
>> +mdp5_get_global_state(struct drm_atomic_state *s);
>> +
>>  /* Atomic plane state.  Subclasses the base drm_plane_state in order to
>>   * track assigned hwpipe and hw specific state.
>>   */
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>> hosted by The Linux Foundation
>>
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-02-20 20:05 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-12-21  6:14 [RFC 0/3] drm/msm: Avoid subclassing of drm_atomic_state Archit Taneja
2017-12-21  6:14 ` [RFC 1/3] drm/msm/mdp5: Add global state as a private atomic object Archit Taneja
2017-12-21  9:56   ` Daniel Vetter
2018-01-03 11:32     ` Archit Taneja
2018-01-03 21:34       ` Rob Clark
2018-02-20 20:05     ` Rob Clark
2017-12-21  6:14 ` [RFC 2/3] drm/msm/mdp5: Use the new private_obj state Archit Taneja
2017-12-21  6:14 ` [RFC 3/3] drm/msm: Don't subclass drm_atomic_state anymore Archit Taneja

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.