linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/11] Implement komeda DRM-Crtc
@ 2019-01-22 11:10 james qian wang (Arm Technology China)
  2019-01-22 11:10 ` [PATCH v2 01/11] drm/komeda: Add komeda_build_display_data_flow james qian wang (Arm Technology China)
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:10 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

This is the 4th patchset for komeda-driver, with this patchset the driver
can bring up and enable the D71 support with basic features.

This patchset implemented komeda_crtc/crtc_helper functions for
DRM-crtc.

v2: Rebase

james qian wang (Arm Technology China) (11):
  drm/komeda: Add komeda_build_display_data_flow
  drm/komeda: Add komeda_release_unclaimed_resources
  drm/komeda: Add komeda_crtc_atomic_flush
  drm/komeda: Add komeda_crtc_mode_valid/fixup
  drm/komeda: Add komeda_crtc_prepare/unprepare
  drm/komeda: Add komeda_crtc_atomic_enable/disable
  drm/komeda: Add komeda_crtc_vblank_enable/disable
  drm/komeda: Add komeda_crtc_funcs
  drm/komeda: Add komeda_kms_check
  drm/komeda: Add sysfs attribute: core_id and config_id
  drm/komeda: Expose bus_width to Komeda-CORE

 .../drm/arm/display/include/malidp_product.h  |  12 +
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  |  54 +++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 385 +++++++++++++++++-
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |  50 +++
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  34 ++
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |   7 +
 .../gpu/drm/arm/display/komeda/komeda_kms.c   |  36 +-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |   3 +
 .../drm/arm/display/komeda/komeda_pipeline.h  |  14 +
 .../display/komeda/komeda_pipeline_state.c    | 203 ++++++++-
 10 files changed, 790 insertions(+), 8 deletions(-)

-- 
2.17.1


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

* [PATCH v2 01/11] drm/komeda: Add komeda_build_display_data_flow
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
@ 2019-01-22 11:10 ` james qian wang (Arm Technology China)
  2019-01-22 11:10 ` [PATCH v2 02/11] drm/komeda: Add komeda_release_unclaimed_resources james qian wang (Arm Technology China)
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:10 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

This function builds a display output pipeline according to crtc_state.
And this change only added single pipeline support, the dual pipeline with
slave enabled data flow support will be added in the following change.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +
 .../display/komeda/komeda_pipeline_state.c    | 76 ++++++++++++++++++-
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 16d7ae891e81..22ad4dfc3e8d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -400,10 +400,13 @@ void komeda_component_destroy(struct komeda_dev *mdev,
 
 struct komeda_plane_state;
 struct komeda_crtc_state;
+struct komeda_crtc;
 
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
 				 struct komeda_plane_state *kplane_st,
 				 struct komeda_crtc_state *kcrtc_st,
 				 struct komeda_data_flow_cfg *dflow);
+int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
+				   struct komeda_crtc_state *kcrtc_st);
 
 #endif /* _KOMEDA_PIPELINE_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 74d25e542103..6a481508624f 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -344,7 +344,7 @@ komeda_compiz_set_input(struct komeda_compiz *compiz,
 	return 0;
 }
 
-int
+static int
 komeda_compiz_validate(struct komeda_compiz *compiz,
 		       struct komeda_crtc_state *state,
 		       struct komeda_data_flow_cfg *dflow)
@@ -382,6 +382,53 @@ komeda_compiz_validate(struct komeda_compiz *compiz,
 	return 0;
 }
 
+static int
+komeda_improc_validate(struct komeda_improc *improc,
+		       struct komeda_crtc_state *kcrtc_st,
+		       struct komeda_data_flow_cfg *dflow)
+{
+	struct drm_crtc *crtc = kcrtc_st->base.crtc;
+	struct komeda_component_state *c_st;
+	struct komeda_improc_state *st;
+
+	c_st = komeda_component_get_state_and_set_user(&improc->base,
+			kcrtc_st->base.state, crtc, crtc);
+	if (IS_ERR(c_st))
+		return PTR_ERR(c_st);
+
+	st = to_improc_st(c_st);
+
+	st->hsize = dflow->in_w;
+	st->vsize = dflow->in_h;
+
+	komeda_component_add_input(&st->base, &dflow->input, 0);
+	komeda_component_set_output(&dflow->input, &improc->base, 0);
+
+	return 0;
+}
+
+static int
+komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr *ctrlr,
+			     struct komeda_crtc_state *kcrtc_st,
+			     struct komeda_data_flow_cfg *dflow)
+{
+	struct drm_crtc *crtc = kcrtc_st->base.crtc;
+	struct komeda_timing_ctrlr_state *st;
+	struct komeda_component_state *c_st;
+
+	c_st = komeda_component_get_state_and_set_user(&ctrlr->base,
+			kcrtc_st->base.state, crtc, crtc);
+	if (IS_ERR(c_st))
+		return PTR_ERR(c_st);
+
+	st = to_ctrlr_st(c_st);
+
+	komeda_component_add_input(&st->base, &dflow->input, 0);
+	komeda_component_set_output(&dflow->input, &ctrlr->base, 0);
+
+	return 0;
+}
+
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
 				 struct komeda_plane_state *kplane_st,
 				 struct komeda_crtc_state *kcrtc_st,
@@ -404,3 +451,30 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer,
 
 	return err;
 }
+
+/* build display output data flow, the data path is:
+ * compiz -> improc -> timing_ctrlr
+ */
+int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
+				   struct komeda_crtc_state *kcrtc_st)
+{
+	struct komeda_pipeline *master = kcrtc->master;
+	struct komeda_data_flow_cfg m_dflow; /* master data flow */
+	int err;
+
+	memset(&m_dflow, 0, sizeof(m_dflow));
+
+	err = komeda_compiz_validate(master->compiz, kcrtc_st, &m_dflow);
+	if (err)
+		return err;
+
+	err = komeda_improc_validate(master->improc, kcrtc_st, &m_dflow);
+	if (err)
+		return err;
+
+	err = komeda_timing_ctrlr_validate(master->ctrlr, kcrtc_st, &m_dflow);
+	if (err)
+		return err;
+
+	return 0;
+}
-- 
2.17.1


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

* [PATCH v2 02/11] drm/komeda: Add komeda_release_unclaimed_resources
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
  2019-01-22 11:10 ` [PATCH v2 01/11] drm/komeda: Add komeda_build_display_data_flow james qian wang (Arm Technology China)
@ 2019-01-22 11:10 ` james qian wang (Arm Technology China)
  2019-01-22 11:10 ` [PATCH v2 03/11] drm/komeda: Add komeda_crtc_atomic_flush james qian wang (Arm Technology China)
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:10 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

Komeda driver treats KMS-CRTC/PLANE as user which will acquire pipeline
resources, but we still need to release the unclaimed resources.
crtc_atomic_check is the final check stage, so beside build a display data
pipeline according the crtc_state, but still needs to release/disable the
unclaimed pipeline resources.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 27 +++++++++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +
 .../display/komeda/komeda_pipeline_state.c    | 58 +++++++++++++++++++
 3 files changed, 88 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 7ca9bc8ef725..a250ab824155 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -14,6 +14,32 @@
 #include "komeda_dev.h"
 #include "komeda_kms.h"
 
+/* crtc_atomic_check is the final check stage, so beside build a display data
+ * pipeline according the crtc_state, but still needs to release/disable the
+ * unclaimed pipeline resources.
+ */
+static int
+komeda_crtc_atomic_check(struct drm_crtc *crtc,
+			 struct drm_crtc_state *state)
+{
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(state);
+	int err;
+
+	if (state->active) {
+		err = komeda_build_display_data_flow(kcrtc, kcrtc_st);
+		if (err)
+			return err;
+	}
+
+	/* release unclaimed pipeline resources */
+	err = komeda_release_unclaimed_resources(kcrtc->master, kcrtc_st);
+	if (err)
+		return err;
+
+	return 0;
+}
+
 void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 			      struct komeda_events *evts)
 {
@@ -33,6 +59,7 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 }
 
 struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
+	.atomic_check	= komeda_crtc_atomic_check,
 };
 
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 22ad4dfc3e8d..54b646128760 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -409,4 +409,7 @@ int komeda_build_layer_data_flow(struct komeda_layer *layer,
 int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
 				   struct komeda_crtc_state *kcrtc_st);
 
+int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
+				       struct komeda_crtc_state *kcrtc_st);
+
 #endif /* _KOMEDA_PIPELINE_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 6a481508624f..6797be630529 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -31,6 +31,18 @@ komeda_pipeline_get_state(struct komeda_pipeline *pipe,
 	return priv_to_pipe_st(priv_st);
 }
 
+struct komeda_pipeline_state *
+komeda_pipeline_get_new_state(struct komeda_pipeline *pipe,
+			      struct drm_atomic_state *state)
+{
+	struct drm_private_state *priv_st;
+
+	priv_st = drm_atomic_get_new_private_obj_state(state, &pipe->obj);
+	if (priv_st)
+		return priv_to_pipe_st(priv_st);
+	return NULL;
+}
+
 /* Assign pipeline for crtc */
 struct komeda_pipeline_state *
 komeda_pipeline_get_state_and_set_crtc(struct komeda_pipeline *pipe,
@@ -478,3 +490,49 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
 
 	return 0;
 }
+
+void komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
+					struct komeda_pipeline_state *new)
+{
+	struct drm_atomic_state *drm_st = new->obj.state;
+	struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state);
+	struct komeda_component_state *c_st;
+	struct komeda_component *c;
+	u32 disabling_comps, id;
+
+	WARN_ON(!old);
+
+	disabling_comps = (~new->active_comps) & old->active_comps;
+
+	/* unbound all disabling component */
+	dp_for_each_set_bit(id, disabling_comps) {
+		c = komeda_pipeline_get_component(pipe, id);
+		c_st = komeda_component_get_state_and_set_user(c,
+				drm_st, NULL, new->crtc);
+		WARN_ON(IS_ERR(c_st));
+	}
+}
+
+/* release unclaimed pipeline resource */
+int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
+				       struct komeda_crtc_state *kcrtc_st)
+{
+	struct drm_atomic_state *drm_st = kcrtc_st->base.state;
+	struct komeda_pipeline_state *st;
+
+	/* ignore the pipeline which is not affected */
+	if (!pipe || !has_bit(pipe->id, kcrtc_st->affected_pipes))
+		return 0;
+
+	if (has_bit(pipe->id, kcrtc_st->active_pipes))
+		st = komeda_pipeline_get_new_state(pipe, drm_st);
+	else
+		st = komeda_pipeline_get_state_and_set_crtc(pipe, drm_st, NULL);
+
+	if (WARN_ON(IS_ERR_OR_NULL(st)))
+		return -EINVAL;
+
+	komeda_pipeline_unbound_components(pipe, st);
+
+	return 0;
+}
-- 
2.17.1


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

* [PATCH v2 03/11] drm/komeda: Add komeda_crtc_atomic_flush
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
  2019-01-22 11:10 ` [PATCH v2 01/11] drm/komeda: Add komeda_build_display_data_flow james qian wang (Arm Technology China)
  2019-01-22 11:10 ` [PATCH v2 02/11] drm/komeda: Add komeda_release_unclaimed_resources james qian wang (Arm Technology China)
@ 2019-01-22 11:10 ` james qian wang (Arm Technology China)
  2019-01-22 11:10 ` [PATCH v2 04/11] drm/komeda: Add komeda_crtc_mode_valid/fixup james qian wang (Arm Technology China)
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:10 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

A komeda flush is comprised two steps:
1. update pipeline/component state to HW.
2. call dev_func->flush to notify HW to kickoff the update.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 11 ++++++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 33 +++++++++++++++++
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  3 ++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  5 +++
 .../display/komeda/komeda_pipeline_state.c    | 37 +++++++++++++++++++
 5 files changed, 89 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index afc13d3b3afc..74aab4f23ea0 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -241,6 +241,16 @@ static int d71_disable_irq(struct komeda_dev *mdev)
 	return 0;
 }
 
+static void d71_flush(struct komeda_dev *mdev,
+		      int master_pipe, u32 active_pipes)
+{
+	struct d71_dev *d71 = mdev->chip_data;
+	u32 reg_offset = (master_pipe == 0) ?
+			 GCU_CONFIG_VALID0 : GCU_CONFIG_VALID1;
+
+	malidp_write32(d71->gcu_addr, reg_offset, GCU_CONFIG_CVAL);
+}
+
 static int d71_reset(struct d71_dev *d71)
 {
 	u32 __iomem *gcu = d71->gcu_addr;
@@ -457,6 +467,7 @@ static struct komeda_dev_funcs d71_chip_funcs = {
 	.irq_handler	= d71_irq_handler,
 	.enable_irq	= d71_enable_irq,
 	.disable_irq	= d71_disable_irq,
+	.flush		= d71_flush,
 };
 
 struct komeda_dev_funcs *
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index a250ab824155..95d8f2bcd523 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -58,8 +58,41 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 		DRM_DEBUG("FLIP Done.\n");
 }
 
+static void
+komeda_crtc_do_flush(struct drm_crtc *crtc,
+		     struct drm_crtc_state *old)
+{
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc->state);
+	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
+	struct komeda_pipeline *master = kcrtc->master;
+
+	DRM_DEBUG_ATOMIC("CRTC%d_FLUSH: active_pipes: 0x%x, affected: 0x%x.\n",
+			 drm_crtc_index(crtc),
+			 kcrtc_st->active_pipes, kcrtc_st->affected_pipes);
+
+	/* step 1: update the pipeline/component state to HW */
+	if (has_bit(master->id, kcrtc_st->affected_pipes))
+		komeda_pipeline_update(master, old->state);
+
+	/* step 2: notify the HW to kickoff the update */
+	mdev->funcs->flush(mdev, master->id, kcrtc_st->active_pipes);
+}
+
+static void
+komeda_crtc_atomic_flush(struct drm_crtc *crtc,
+			 struct drm_crtc_state *old)
+{
+	/* commit with modeset will be handled in enable/disable */
+	if (drm_atomic_crtc_needs_modeset(crtc->state))
+		return;
+
+	komeda_crtc_do_flush(crtc, old);
+}
+
 struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
 	.atomic_check	= komeda_crtc_atomic_check,
+	.atomic_flush	= komeda_crtc_atomic_flush,
 };
 
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 8eae2620ce77..0bd38bdf0518 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -106,6 +106,9 @@ struct komeda_dev_funcs {
 
 	/** @dump_register: Optional, dump registers to seq_file */
 	void (*dump_register)(struct komeda_dev *mdev, struct seq_file *seq);
+	/** @flush: Notify the HW to flush or kickoff the update */
+	void (*flush)(struct komeda_dev *mdev,
+		      int master_pipe, u32 active_pipes);
 };
 
 /**
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 54b646128760..3d7a9ee550b2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -412,4 +412,9 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
 				       struct komeda_crtc_state *kcrtc_st);
 
+void komeda_pipeline_disable(struct komeda_pipeline *pipe,
+			     struct drm_atomic_state *old_state);
+void komeda_pipeline_update(struct komeda_pipeline *pipe,
+			    struct drm_atomic_state *old_state);
+
 #endif /* _KOMEDA_PIPELINE_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 6797be630529..87fd6493d202 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -31,6 +31,18 @@ komeda_pipeline_get_state(struct komeda_pipeline *pipe,
 	return priv_to_pipe_st(priv_st);
 }
 
+struct komeda_pipeline_state *
+komeda_pipeline_get_old_state(struct komeda_pipeline *pipe,
+			      struct drm_atomic_state *state)
+{
+	struct drm_private_state *priv_st;
+
+	priv_st = drm_atomic_get_old_private_obj_state(state, &pipe->obj);
+	if (priv_st)
+		return priv_to_pipe_st(priv_st);
+	return NULL;
+}
+
 struct komeda_pipeline_state *
 komeda_pipeline_get_new_state(struct komeda_pipeline *pipe,
 			      struct drm_atomic_state *state)
@@ -536,3 +548,28 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
 
 	return 0;
 }
+
+void komeda_pipeline_update(struct komeda_pipeline *pipe,
+			    struct drm_atomic_state *old_state)
+{
+	struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state);
+	struct komeda_pipeline_state *old;
+	struct komeda_component *c;
+	u32 id, changed_comps = 0;
+
+	old = komeda_pipeline_get_old_state(pipe, old_state);
+
+	changed_comps = new->active_comps | old->active_comps;
+
+	DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n",
+			 pipe->id, new->active_comps, changed_comps);
+
+	dp_for_each_set_bit(id, changed_comps) {
+		c = komeda_pipeline_get_component(pipe, id);
+
+		if (new->active_comps & BIT(c->id))
+			c->funcs->update(c, priv_to_comp_st(c->obj.state));
+		else
+			c->funcs->disable(c);
+	}
+}
-- 
2.17.1


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

* [PATCH v2 04/11] drm/komeda: Add komeda_crtc_mode_valid/fixup
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (2 preceding siblings ...)
  2019-01-22 11:10 ` [PATCH v2 03/11] drm/komeda: Add komeda_crtc_atomic_flush james qian wang (Arm Technology China)
@ 2019-01-22 11:10 ` james qian wang (Arm Technology China)
  2019-01-22 11:11 ` [PATCH v2 05/11] drm/komeda: Add komeda_crtc_prepare/unprepare james qian wang (Arm Technology China)
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:10 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

komeda_crtc_mode_valid compares the input mode->clk with main engine clk
and AXI clk, and reject the mode if the required pixel clk can not be
satisfied by main engine clk and AXI-clk.

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 52 +++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 95d8f2bcd523..7e0bf78da733 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -90,9 +90,61 @@ komeda_crtc_atomic_flush(struct drm_crtc *crtc,
 	komeda_crtc_do_flush(crtc, old);
 }
 
+static enum drm_mode_status
+komeda_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *m)
+{
+	struct komeda_dev *mdev = crtc->dev->dev_private;
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+	struct komeda_pipeline *master = kcrtc->master;
+	long mode_clk, pxlclk;
+
+	if (m->flags & DRM_MODE_FLAG_INTERLACE)
+		return MODE_NO_INTERLACE;
+
+	/* main clock/AXI clk must be faster than pxlclk*/
+	mode_clk = m->clock * 1000;
+	pxlclk = clk_round_rate(master->pxlclk, mode_clk);
+	if (pxlclk != mode_clk) {
+		DRM_DEBUG_ATOMIC("pxlclk doesn't support %ld Hz\n", mode_clk);
+
+		return MODE_NOCLOCK;
+	}
+
+	if (clk_round_rate(mdev->mclk, mode_clk) < pxlclk) {
+		DRM_DEBUG_ATOMIC("mclk can't satisfy the requirement of %s-clk: %ld.\n",
+				 m->name, pxlclk);
+
+		return MODE_CLOCK_HIGH;
+	}
+
+	if (clk_round_rate(master->aclk, mode_clk) < pxlclk) {
+		DRM_DEBUG_ATOMIC("aclk can't satisfy the requirement of %s-clk: %ld.\n",
+				 m->name, pxlclk);
+
+		return MODE_CLOCK_HIGH;
+	}
+
+	return MODE_OK;
+}
+
+static bool komeda_crtc_mode_fixup(struct drm_crtc *crtc,
+				   const struct drm_display_mode *m,
+				   struct drm_display_mode *adjusted_mode)
+{
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+	struct komeda_pipeline *master = kcrtc->master;
+	long mode_clk = m->clock * 1000;
+
+	adjusted_mode->clock = clk_round_rate(master->pxlclk, mode_clk) / 1000;
+
+	return true;
+}
+
 struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
 	.atomic_check	= komeda_crtc_atomic_check,
 	.atomic_flush	= komeda_crtc_atomic_flush,
+	.mode_valid	= komeda_crtc_mode_valid,
+	.mode_fixup	= komeda_crtc_mode_fixup,
 };
 
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
-- 
2.17.1


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

* [PATCH v2 05/11] drm/komeda: Add komeda_crtc_prepare/unprepare
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (3 preceding siblings ...)
  2019-01-22 11:10 ` [PATCH v2 04/11] drm/komeda: Add komeda_crtc_mode_valid/fixup james qian wang (Arm Technology China)
@ 2019-01-22 11:11 ` james qian wang (Arm Technology China)
  2019-01-22 11:11 ` [PATCH v2 06/11] drm/komeda: Add komeda_crtc_atomic_enable/disable james qian wang (Arm Technology China)
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:11 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

These two function will be used by komeda_crtc_enable/disable to do some
prepartion works when enable/disable a crtc. like enable a crtc:
  1. Adjust display operation mode.
  2. Enable/prepare needed clk.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  |  32 ++++++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 104 ++++++++++++++++++
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |   2 +
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  26 +++++
 4 files changed, 164 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 74aab4f23ea0..2fb29aea9f69 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -241,6 +241,37 @@ static int d71_disable_irq(struct komeda_dev *mdev)
 	return 0;
 }
 
+static int to_d71_opmode(int core_mode)
+{
+	switch (core_mode) {
+	case KOMEDA_MODE_DISP0:
+		return DO0_ACTIVE_MODE;
+	case KOMEDA_MODE_DISP1:
+		return DO1_ACTIVE_MODE;
+	case KOMEDA_MODE_DUAL_DISP:
+		return DO01_ACTIVE_MODE;
+	case KOMEDA_MODE_INACTIVE:
+		return INACTIVE_MODE;
+	default:
+		WARN(1, "Unknown operation mode");
+		return INACTIVE_MODE;
+	}
+}
+
+static int d71_change_opmode(struct komeda_dev *mdev, int new_mode)
+{
+	struct d71_dev *d71 = mdev->chip_data;
+	u32 opmode = to_d71_opmode(new_mode);
+	int ret;
+
+	malidp_write32_mask(d71->gcu_addr, BLK_CONTROL, 0x7, opmode);
+
+	ret = dp_wait_cond(((malidp_read32(d71->gcu_addr, BLK_CONTROL) & 0x7) == opmode),
+			   100, 1000, 10000);
+
+	return ret > 0 ? 0 : -ETIMEDOUT;
+}
+
 static void d71_flush(struct komeda_dev *mdev,
 		      int master_pipe, u32 active_pipes)
 {
@@ -467,6 +498,7 @@ static struct komeda_dev_funcs d71_chip_funcs = {
 	.irq_handler	= d71_irq_handler,
 	.enable_irq	= d71_enable_irq,
 	.disable_irq	= d71_disable_irq,
+	.change_opmode	= d71_change_opmode,
 	.flush		= d71_flush,
 };
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 7e0bf78da733..ef4c3ee2a688 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -40,6 +40,110 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc,
 	return 0;
 }
 
+u32 komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st)
+{
+	unsigned long mclk = kcrtc_st->base.adjusted_mode.clock * 1000;
+
+	return mclk;
+}
+
+/* For active a crtc, mainly need two parts of preparation
+ * 1. adjust display operation mode.
+ * 2. enable needed clk
+ */
+int
+komeda_crtc_prepare(struct komeda_crtc *kcrtc)
+{
+	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
+	struct komeda_pipeline *master = kcrtc->master;
+	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(kcrtc->base.state);
+	unsigned long pxlclk_rate = kcrtc_st->base.adjusted_mode.clock * 1000;
+	u32 new_mode;
+	int err;
+
+	mutex_lock(&mdev->lock);
+
+	new_mode = mdev->dpmode | BIT(master->id);
+	if (WARN_ON(new_mode == mdev->dpmode)) {
+		err = 0;
+		goto unlock;
+	}
+
+	err = mdev->funcs->change_opmode(mdev, new_mode);
+	if (err) {
+		DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,",
+			  mdev->dpmode, new_mode);
+		goto unlock;
+	}
+
+	mdev->dpmode = new_mode;
+	/* Only need to enable mclk on single display mode, but no need to
+	 * enable mclk it on dual display mode, since the dual mode always
+	 * switch from single display mode, the mclk already enabled, no need
+	 * to enable it again.
+	 */
+	if (new_mode != KOMEDA_MODE_DUAL_DISP) {
+		err = clk_set_rate(mdev->mclk, komeda_calc_mclk(kcrtc_st));
+		if (err)
+			DRM_ERROR("failed to set mclk.\n");
+		err = clk_prepare_enable(mdev->mclk);
+		if (err)
+			DRM_ERROR("failed to enable mclk.\n");
+	}
+
+	err = clk_prepare_enable(master->aclk);
+	if (err)
+		DRM_ERROR("failed to enable axi clk for pipe%d.\n", master->id);
+	err = clk_set_rate(master->pxlclk, pxlclk_rate);
+	if (err)
+		DRM_ERROR("failed to set pxlclk for pipe%d\n", master->id);
+	err = clk_prepare_enable(master->pxlclk);
+	if (err)
+		DRM_ERROR("failed to enable pxl clk for pipe%d.\n", master->id);
+
+unlock:
+	mutex_unlock(&mdev->lock);
+
+	return err;
+}
+
+int
+komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
+{
+	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
+	struct komeda_pipeline *master = kcrtc->master;
+	u32 new_mode;
+	int err;
+
+	mutex_lock(&mdev->lock);
+
+	new_mode = mdev->dpmode & (~BIT(master->id));
+
+	if (WARN_ON(new_mode == mdev->dpmode)) {
+		err = 0;
+		goto unlock;
+	}
+
+	err = mdev->funcs->change_opmode(mdev, new_mode);
+	if (err) {
+		DRM_ERROR("failed to change opmode: 0x%x -> 0x%x.\n,",
+			  mdev->dpmode, new_mode);
+		goto unlock;
+	}
+
+	mdev->dpmode = new_mode;
+
+	clk_disable_unprepare(master->pxlclk);
+	clk_disable_unprepare(master->aclk);
+	if (new_mode == KOMEDA_MODE_INACTIVE)
+		clk_disable_unprepare(mdev->mclk);
+
+unlock:
+	mutex_unlock(&mdev->lock);
+
+	return err;
+}
+
 void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 			      struct komeda_events *evts)
 {
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index a012b3bbf53b..7152f2c08e01 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -145,6 +145,8 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
 	if (!mdev)
 		return ERR_PTR(-ENOMEM);
 
+	mutex_init(&mdev->lock);
+
 	mdev->dev = dev;
 	mdev->reg_base = devm_ioremap_resource(dev, io_res);
 	if (IS_ERR(mdev->reg_base)) {
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 0bd38bdf0518..1ad1f6e49854 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -106,11 +106,34 @@ struct komeda_dev_funcs {
 
 	/** @dump_register: Optional, dump registers to seq_file */
 	void (*dump_register)(struct komeda_dev *mdev, struct seq_file *seq);
+	/**
+	 * @change_opmode:
+	 *
+	 * Notify HW to switch to a new display operation mode.
+	 */
+	int (*change_opmode)(struct komeda_dev *mdev, int new_mode);
 	/** @flush: Notify the HW to flush or kickoff the update */
 	void (*flush)(struct komeda_dev *mdev,
 		      int master_pipe, u32 active_pipes);
 };
 
+/**
+ * DISPLAY_MODE describes how many display been enabled, and which will be
+ * passed to CHIP by &komeda_dev_funcs->change_opmode(), then CHIP can do the
+ * pipeline resources assignment according to this usage hint.
+ * -   KOMEDA_MODE_DISP0: Only one display enabled, pipeline-0 work as master.
+ * -   KOMEDA_MODE_DISP1: Only one display enabled, pipeline-0 work as master.
+ * -   KOMEDA_MODE_DUAL_DISP: Dual display mode, both display has been enabled.
+ * And D71 supports assign two pipelines to one single display on mode
+ * KOMEDA_MODE_DISP0/DISP1
+ */
+enum {
+	KOMEDA_MODE_INACTIVE	= 0,
+	KOMEDA_MODE_DISP0	= BIT(0),
+	KOMEDA_MODE_DISP1	= BIT(1),
+	KOMEDA_MODE_DUAL_DISP	= KOMEDA_MODE_DISP0 | KOMEDA_MODE_DISP1,
+};
+
 /**
  * struct komeda_dev
  *
@@ -133,6 +156,9 @@ struct komeda_dev {
 	/** @irq: irq number */
 	int irq;
 
+	struct mutex lock; /* used to protect dpmode */
+	u32 dpmode; /* current display mode */
+
 	int n_pipelines;
 	struct komeda_pipeline *pipelines[KOMEDA_MAX_PIPELINES];
 
-- 
2.17.1


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

* [PATCH v2 06/11] drm/komeda: Add komeda_crtc_atomic_enable/disable
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (4 preceding siblings ...)
  2019-01-22 11:11 ` [PATCH v2 05/11] drm/komeda: Add komeda_crtc_prepare/unprepare james qian wang (Arm Technology China)
@ 2019-01-22 11:11 ` james qian wang (Arm Technology China)
  2019-01-22 11:11 ` [PATCH v2 07/11] drm/komeda: Add komeda_crtc_vblank_enable/disable james qian wang (Arm Technology China)
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:11 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

Pass enable/disable command to komeda and adjust komeda hardware for
enable/disable a display instance.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 106 +++++++++++++++++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |   3 +
 .../drm/arm/display/komeda/komeda_pipeline.h  |   3 +
 .../display/komeda/komeda_pipeline_state.c    |  32 ++++++
 4 files changed, 139 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index ef4c3ee2a688..9b370e1232e2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -51,7 +51,7 @@ u32 komeda_calc_mclk(struct komeda_crtc_state *kcrtc_st)
  * 1. adjust display operation mode.
  * 2. enable needed clk
  */
-int
+static int
 komeda_crtc_prepare(struct komeda_crtc *kcrtc)
 {
 	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
@@ -107,7 +107,7 @@ komeda_crtc_prepare(struct komeda_crtc *kcrtc)
 	return err;
 }
 
-int
+static int
 komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
 {
 	struct komeda_dev *mdev = kcrtc->base.dev->dev_private;
@@ -157,9 +157,28 @@ void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
 	if (events & KOMEDA_EVENT_EOW)
 		DRM_DEBUG("EOW.\n");
 
-	/* will handle it with crtc->flush */
-	if (events & KOMEDA_EVENT_FLIP)
-		DRM_DEBUG("FLIP Done.\n");
+	if (events & KOMEDA_EVENT_FLIP) {
+		unsigned long flags;
+		struct drm_pending_vblank_event *event;
+
+		spin_lock_irqsave(&crtc->dev->event_lock, flags);
+		if (kcrtc->disable_done) {
+			complete_all(kcrtc->disable_done);
+			kcrtc->disable_done = NULL;
+		} else if (crtc->state->event) {
+			event = crtc->state->event;
+			/*
+			 * Consume event before notifying drm core that flip
+			 * happened.
+			 */
+			crtc->state->event = NULL;
+			drm_crtc_send_vblank_event(crtc, event);
+		} else {
+			DRM_WARN("CRTC[%d]: FLIP happen but no pending commit.\n",
+				 drm_crtc_index(&kcrtc->base));
+		}
+		spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+	}
 }
 
 static void
@@ -183,6 +202,81 @@ komeda_crtc_do_flush(struct drm_crtc *crtc,
 	mdev->funcs->flush(mdev, master->id, kcrtc_st->active_pipes);
 }
 
+static void
+komeda_crtc_atomic_enable(struct drm_crtc *crtc,
+			  struct drm_crtc_state *old)
+{
+	komeda_crtc_prepare(to_kcrtc(crtc));
+	drm_crtc_vblank_on(crtc);
+	komeda_crtc_do_flush(crtc, old);
+}
+
+static void
+komeda_crtc_atomic_disable(struct drm_crtc *crtc,
+			   struct drm_crtc_state *old)
+{
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+	struct komeda_crtc_state *old_st = to_kcrtc_st(old);
+	struct komeda_dev *mdev = crtc->dev->dev_private;
+	struct komeda_pipeline *master = kcrtc->master;
+	struct completion *disable_done = &crtc->state->commit->flip_done;
+	struct completion temp;
+	int timeout;
+
+	DRM_DEBUG_ATOMIC("CRTC%d_DISABLE: active_pipes: 0x%x, affected: 0x%x.\n",
+			 drm_crtc_index(crtc),
+			 old_st->active_pipes, old_st->affected_pipes);
+
+	if (has_bit(master->id, old_st->active_pipes))
+		komeda_pipeline_disable(master, old->state);
+
+	/* crtc_disable has two scenarios according to the state->active switch.
+	 * 1. active -> inactive
+	 *    this commit is a disable commit. and the commit will be finished
+	 *    or done after the disable operation. on this case we can directly
+	 *    use the crtc->state->event to tracking the HW disable operation.
+	 * 2. active -> active
+	 *    the crtc->commit is not for disable, but a modeset operation when
+	 *    crtc is active, such commit actually has been completed by 3
+	 *    DRM operations:
+	 *    crtc_disable, update_planes(crtc_flush), crtc_enable
+	 *    so on this case the crtc->commit is for the whole process.
+	 *    we can not use it for tracing the disable, we need a temporary
+	 *    flip_done for tracing the disable. and crtc->state->event for
+	 *    the crtc_enable operation.
+	 *    That's also the reason why skip modeset commit in
+	 *    komeda_crtc_atomic_flush()
+	 */
+	if (crtc->state->active) {
+		struct komeda_pipeline_state *pipe_st;
+		/* clear the old active_comps to zero */
+		pipe_st = komeda_pipeline_get_old_state(master, old->state);
+		pipe_st->active_comps = 0;
+
+		init_completion(&temp);
+		kcrtc->disable_done = &temp;
+		disable_done = &temp;
+	}
+
+	mdev->funcs->flush(mdev, master->id, 0);
+
+	/* wait the disable take affect.*/
+	timeout = wait_for_completion_timeout(disable_done, HZ);
+	if (timeout == 0) {
+		DRM_ERROR("disable pipeline%d timeout.\n", kcrtc->master->id);
+		if (crtc->state->active) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&crtc->dev->event_lock, flags);
+			kcrtc->disable_done = NULL;
+			spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+		}
+	}
+
+	drm_crtc_vblank_off(crtc);
+	komeda_crtc_unprepare(kcrtc);
+}
+
 static void
 komeda_crtc_atomic_flush(struct drm_crtc *crtc,
 			 struct drm_crtc_state *old)
@@ -247,6 +341,8 @@ static bool komeda_crtc_mode_fixup(struct drm_crtc *crtc,
 struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
 	.atomic_check	= komeda_crtc_atomic_check,
 	.atomic_flush	= komeda_crtc_atomic_flush,
+	.atomic_enable	= komeda_crtc_atomic_enable,
+	.atomic_disable	= komeda_crtc_atomic_disable,
 	.mode_valid	= komeda_crtc_mode_valid,
 	.mode_fixup	= komeda_crtc_mode_fixup,
 };
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index 06394716367b..990071352040 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -69,6 +69,9 @@ struct komeda_crtc {
 	 * merge into the master.
 	 */
 	struct komeda_pipeline *slave;
+
+	/* this flip_done is for tracing the disable */
+	struct completion *disable_done;
 };
 
 /** struct komeda_crtc_state */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 3d7a9ee550b2..233e512319e8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -412,6 +412,9 @@ int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
 				       struct komeda_crtc_state *kcrtc_st);
 
+struct komeda_pipeline_state *
+komeda_pipeline_get_old_state(struct komeda_pipeline *pipe,
+			      struct drm_atomic_state *state);
 void komeda_pipeline_disable(struct komeda_pipeline *pipe,
 			     struct drm_atomic_state *old_state);
 void komeda_pipeline_update(struct komeda_pipeline *pipe,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 87fd6493d202..69a622f06453 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -549,6 +549,38 @@ int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
 	return 0;
 }
 
+void komeda_pipeline_disable(struct komeda_pipeline *pipe,
+			     struct drm_atomic_state *old_state)
+{
+	struct komeda_pipeline_state *old;
+	struct komeda_component *c;
+	struct komeda_component_state *c_st;
+	u32 id, disabling_comps = 0;
+
+	old = komeda_pipeline_get_old_state(pipe, old_state);
+
+	disabling_comps = old->active_comps;
+	DRM_DEBUG_ATOMIC("PIPE%d: disabling_comps: 0x%x.\n",
+			 pipe->id, disabling_comps);
+
+	dp_for_each_set_bit(id, disabling_comps) {
+		c = komeda_pipeline_get_component(pipe, id);
+		c_st = priv_to_comp_st(c->obj.state);
+
+		/*
+		 * If we disabled a component then all active_inputs should be
+		 * put in the list of changed_active_inputs, so they get
+		 * re-enabled.
+		 * This usually happens during a modeset when the pipeline is
+		 * first disabled and then the actual state gets committed
+		 * again.
+		 */
+		c_st->changed_active_inputs |= c_st->active_inputs;
+
+		c->funcs->disable(c);
+	}
+}
+
 void komeda_pipeline_update(struct komeda_pipeline *pipe,
 			    struct drm_atomic_state *old_state)
 {
-- 
2.17.1


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

* [PATCH v2 07/11] drm/komeda: Add komeda_crtc_vblank_enable/disable
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (5 preceding siblings ...)
  2019-01-22 11:11 ` [PATCH v2 06/11] drm/komeda: Add komeda_crtc_atomic_enable/disable james qian wang (Arm Technology China)
@ 2019-01-22 11:11 ` james qian wang (Arm Technology China)
  2019-01-22 11:11 ` [PATCH v2 08/11] drm/komeda: Add komeda_crtc_funcs james qian wang (Arm Technology China)
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:11 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

Add a new komeda_dev_func->on_off_vblank to enable/disable HW vblank event

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 10 ++++++++++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 19 +++++++++++++++++++
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  3 +++
 3 files changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 2fb29aea9f69..f517ab0ceae9 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -241,6 +241,15 @@ static int d71_disable_irq(struct komeda_dev *mdev)
 	return 0;
 }
 
+static void d71_on_off_vblank(struct komeda_dev *mdev, int master_pipe, bool on)
+{
+	struct d71_dev *d71 = mdev->chip_data;
+	struct d71_pipeline *pipe = d71->pipes[master_pipe];
+
+	malidp_write32_mask(pipe->dou_addr, BLK_IRQ_MASK,
+			    DOU_IRQ_PL0, on ? DOU_IRQ_PL0 : 0);
+}
+
 static int to_d71_opmode(int core_mode)
 {
 	switch (core_mode) {
@@ -498,6 +507,7 @@ static struct komeda_dev_funcs d71_chip_funcs = {
 	.irq_handler	= d71_irq_handler,
 	.enable_irq	= d71_enable_irq,
 	.disable_irq	= d71_disable_irq,
+	.on_off_vblank	= d71_on_off_vblank,
 	.change_opmode	= d71_change_opmode,
 	.flush		= d71_flush,
 };
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 9b370e1232e2..e19ba9468d31 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -347,7 +347,26 @@ struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
 	.mode_fixup	= komeda_crtc_mode_fixup,
 };
 
+static int komeda_crtc_vblank_enable(struct drm_crtc *crtc)
+{
+	struct komeda_dev *mdev = crtc->dev->dev_private;
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+
+	mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, true);
+	return 0;
+}
+
+static void komeda_crtc_vblank_disable(struct drm_crtc *crtc)
+{
+	struct komeda_dev *mdev = crtc->dev->dev_private;
+	struct komeda_crtc *kcrtc = to_kcrtc(crtc);
+
+	mdev->funcs->on_off_vblank(mdev, kcrtc->master->id, false);
+}
+
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
+	.enable_vblank		= komeda_crtc_vblank_enable,
+	.disable_vblank		= komeda_crtc_vblank_disable,
 };
 
 int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 1ad1f6e49854..8acd25afb3e9 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -103,6 +103,9 @@ struct komeda_dev_funcs {
 	int (*enable_irq)(struct komeda_dev *mdev);
 	/** @disable_irq: disable irq */
 	int (*disable_irq)(struct komeda_dev *mdev);
+	/** @on_off_vblank: notify HW to on/off vblank */
+	void (*on_off_vblank)(struct komeda_dev *mdev,
+			      int master_pipe, bool on);
 
 	/** @dump_register: Optional, dump registers to seq_file */
 	void (*dump_register)(struct komeda_dev *mdev, struct seq_file *seq);
-- 
2.17.1


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

* [PATCH v2 08/11] drm/komeda: Add komeda_crtc_funcs
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (6 preceding siblings ...)
  2019-01-22 11:11 ` [PATCH v2 07/11] drm/komeda: Add komeda_crtc_vblank_enable/disable james qian wang (Arm Technology China)
@ 2019-01-22 11:11 ` james qian wang (Arm Technology China)
  2019-01-22 11:11 ` [PATCH v2 09/11] drm/komeda: Add komeda_kms_check james qian wang (Arm Technology China)
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:11 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

Added functions:
-  komeda_crtc_reset
-  komeda_crtc_vblank_enable
-  komeda_crtc_vblank_disable

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 48 +++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index e19ba9468d31..7adda663b956 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -347,6 +347,47 @@ struct drm_crtc_helper_funcs komeda_crtc_helper_funcs = {
 	.mode_fixup	= komeda_crtc_mode_fixup,
 };
 
+static void komeda_crtc_reset(struct drm_crtc *crtc)
+{
+	struct komeda_crtc_state *state;
+
+	if (crtc->state)
+		__drm_atomic_helper_crtc_destroy_state(crtc->state);
+
+	kfree(to_kcrtc_st(crtc->state));
+	crtc->state = NULL;
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (state) {
+		crtc->state = &state->base;
+		crtc->state->crtc = crtc;
+	}
+}
+
+static struct drm_crtc_state *
+komeda_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
+{
+	struct komeda_crtc_state *old = to_kcrtc_st(crtc->state);
+	struct komeda_crtc_state *new;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return NULL;
+
+	__drm_atomic_helper_crtc_duplicate_state(crtc, &new->base);
+
+	new->affected_pipes = old->active_pipes;
+
+	return &new->base;
+}
+
+static void komeda_crtc_atomic_destroy_state(struct drm_crtc *crtc,
+					     struct drm_crtc_state *state)
+{
+	__drm_atomic_helper_crtc_destroy_state(state);
+	kfree(to_kcrtc_st(state));
+}
+
 static int komeda_crtc_vblank_enable(struct drm_crtc *crtc)
 {
 	struct komeda_dev *mdev = crtc->dev->dev_private;
@@ -365,6 +406,13 @@ static void komeda_crtc_vblank_disable(struct drm_crtc *crtc)
 }
 
 static const struct drm_crtc_funcs komeda_crtc_funcs = {
+	.gamma_set		= drm_atomic_helper_legacy_gamma_set,
+	.destroy		= drm_crtc_cleanup,
+	.set_config		= drm_atomic_helper_set_config,
+	.page_flip		= drm_atomic_helper_page_flip,
+	.reset			= komeda_crtc_reset,
+	.atomic_duplicate_state	= komeda_crtc_atomic_duplicate_state,
+	.atomic_destroy_state	= komeda_crtc_atomic_destroy_state,
 	.enable_vblank		= komeda_crtc_vblank_enable,
 	.disable_vblank		= komeda_crtc_vblank_disable,
 };
-- 
2.17.1


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

* [PATCH v2 09/11] drm/komeda: Add komeda_kms_check
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (7 preceding siblings ...)
  2019-01-22 11:11 ` [PATCH v2 08/11] drm/komeda: Add komeda_crtc_funcs james qian wang (Arm Technology China)
@ 2019-01-22 11:11 ` james qian wang (Arm Technology China)
  2019-01-22 11:11 ` [PATCH v2 10/11] drm/komeda: Add sysfs attribute: core_id and config_id james qian wang (Arm Technology China)
  2019-01-22 11:12 ` [PATCH v2 11/11] drm/komeda: Expose bus_width to Komeda-CORE james qian wang (Arm Technology China)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:11 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

Implement komeda_kms_check to add all affected_planes (even unchanged) to
drm_atomic_state. since komeda need to re-calculate the resources
assumption in every commit.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../gpu/drm/arm/display/komeda/komeda_kms.c   | 30 ++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 7d7fb5013464..337e6fddead0 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -95,9 +95,37 @@ static const struct drm_mode_config_helper_funcs komeda_mode_config_helpers = {
 	.atomic_commit_tail = komeda_kms_commit_tail,
 };
 
+static int komeda_kms_check(struct drm_device *dev,
+			    struct drm_atomic_state *state)
+{
+	struct drm_crtc *crtc;
+	struct drm_crtc_state *old_crtc_st, *new_crtc_st;
+	int i, err;
+
+	err = drm_atomic_helper_check_modeset(dev, state);
+	if (err)
+		return err;
+
+	/* komeda need to re-calculate resource assumption in every commit
+	 * so need to add all affected_planes (even unchanged) to
+	 * drm_atomic_state.
+	 */
+	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_st, new_crtc_st, i) {
+		err = drm_atomic_add_affected_planes(state, crtc);
+		if (err)
+			return err;
+	}
+
+	err = drm_atomic_helper_check_planes(dev, state);
+	if (err)
+		return err;
+
+	return 0;
+}
+
 static const struct drm_mode_config_funcs komeda_mode_config_funcs = {
 	.fb_create		= komeda_fb_create,
-	.atomic_check		= drm_atomic_helper_check,
+	.atomic_check		= komeda_kms_check,
 	.atomic_commit		= drm_atomic_helper_commit,
 };
 
-- 
2.17.1


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

* [PATCH v2 10/11] drm/komeda: Add sysfs attribute: core_id and config_id
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (8 preceding siblings ...)
  2019-01-22 11:11 ` [PATCH v2 09/11] drm/komeda: Add komeda_kms_check james qian wang (Arm Technology China)
@ 2019-01-22 11:11 ` james qian wang (Arm Technology China)
  2019-01-22 11:12 ` [PATCH v2 11/11] drm/komeda: Expose bus_width to Komeda-CORE james qian wang (Arm Technology China)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:11 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

Add two sysfs node: core_id, config_id, user can read them to fetch the
HW product information.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../drm/arm/display/include/malidp_product.h  | 12 +++++
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 48 +++++++++++++++++++
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  2 +
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |  7 +++
 4 files changed, 69 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h b/drivers/gpu/drm/arm/display/include/malidp_product.h
index b35fc5db866b..1053b11352eb 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_product.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
@@ -20,4 +20,16 @@
 /* Mali-display product IDs */
 #define MALIDP_D71_PRODUCT_ID   0x0071
 
+union komeda_config_id {
+	struct {
+		__u32	max_line_sz:16,
+			n_pipelines:2,
+			n_scalers:2, /* number of scalers per pipeline */
+			n_layers:3, /* number of layers per pipeline */
+			n_richs:3, /* number of rich layers per pipeline */
+			reserved_bits:6;
+	};
+	__u32 value;
+};
+
 #endif /* _MALIDP_PRODUCT_H_ */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 7152f2c08e01..9e017ce89d69 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -53,6 +53,46 @@ static void komeda_debugfs_init(struct komeda_dev *mdev)
 			    mdev, &komeda_register_fops);
 }
 
+static ssize_t
+core_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct komeda_dev *mdev = dev_to_mdev(dev);
+
+	return snprintf(buf, PAGE_SIZE, "0x%08x\n", mdev->chip.core_id);
+}
+static DEVICE_ATTR_RO(core_id);
+
+static ssize_t
+config_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct komeda_dev *mdev = dev_to_mdev(dev);
+	struct komeda_pipeline *pipe = mdev->pipelines[0];
+	union komeda_config_id config_id = {0,};
+	int i;
+
+	config_id.max_line_sz = pipe->layers[0]->hsize_in.end;
+	config_id.n_pipelines = mdev->n_pipelines;
+	config_id.n_scalers = pipe->n_scalers;
+	config_id.n_layers = pipe->n_layers;
+	config_id.n_richs = 0;
+	for (i = 0; i < pipe->n_layers; i++) {
+		if (pipe->layers[i]->layer_type == KOMEDA_FMT_RICH_LAYER)
+			config_id.n_richs++;
+	}
+	return snprintf(buf, PAGE_SIZE, "0x%08x\n", config_id.value);
+}
+static DEVICE_ATTR_RO(config_id);
+
+static struct attribute *komeda_sysfs_entries[] = {
+	&dev_attr_core_id.attr,
+	&dev_attr_config_id.attr,
+	NULL,
+};
+
+static struct attribute_group komeda_sysfs_attr_group = {
+	.attrs = komeda_sysfs_entries,
+};
+
 static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np)
 {
 	struct komeda_pipeline *pipe;
@@ -201,6 +241,12 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
 		goto err_cleanup;
 	}
 
+	err = sysfs_create_group(&dev->kobj, &komeda_sysfs_attr_group);
+	if (err) {
+		DRM_ERROR("create sysfs group failed.\n");
+		goto err_cleanup;
+	}
+
 #ifdef CONFIG_DEBUG_FS
 	komeda_debugfs_init(mdev);
 #endif
@@ -218,6 +264,8 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
 	struct komeda_dev_funcs *funcs = mdev->funcs;
 	int i;
 
+	sysfs_remove_group(&dev->kobj, &komeda_sysfs_attr_group);
+
 #ifdef CONFIG_DEBUG_FS
 	debugfs_remove_recursive(mdev->debugfs_root);
 #endif
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 8acd25afb3e9..0c3e32b596d9 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -190,4 +190,6 @@ d71_identify(u32 __iomem *reg, struct komeda_chip_info *chip);
 struct komeda_dev *komeda_dev_create(struct device *dev);
 void komeda_dev_destroy(struct komeda_dev *mdev);
 
+struct komeda_dev *dev_to_mdev(struct device *dev);
+
 #endif /*_KOMEDA_DEV_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
index 2bdd189b041d..0285fd37a016 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
@@ -17,6 +17,13 @@ struct komeda_drv {
 	struct komeda_kms_dev *kms;
 };
 
+struct komeda_dev *dev_to_mdev(struct device *dev)
+{
+	struct komeda_drv *mdrv = dev_get_drvdata(dev);
+
+	return mdrv ? mdrv->mdev : NULL;
+}
+
 static void komeda_unbind(struct device *dev)
 {
 	struct komeda_drv *mdrv = dev_get_drvdata(dev);
-- 
2.17.1


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

* [PATCH v2 11/11] drm/komeda: Expose bus_width to Komeda-CORE
  2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
                   ` (9 preceding siblings ...)
  2019-01-22 11:11 ` [PATCH v2 10/11] drm/komeda: Add sysfs attribute: core_id and config_id james qian wang (Arm Technology China)
@ 2019-01-22 11:12 ` james qian wang (Arm Technology China)
  10 siblings, 0 replies; 12+ messages in thread
From: james qian wang (Arm Technology China) @ 2019-01-22 11:12 UTC (permalink / raw)
  To: Liviu Dudau, airlied, Brian Starkey
  Cc: Jonathan Chai (Arm Technology China),
	Julien Yin (Arm Technology China),
	thomas Sun (Arm Technology China),
	Lowry Li (Arm Technology China),
	Ayan Halder, Tiannan Zhu (Arm Technology China),
	Jin Gao (Arm Technology China), Yiqi Kang (Arm Technology China),
	nd, malidp, linux-kernel, dri-devel,
	james qian wang (Arm Technology China)

From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>

CHIP set bus_width according to the HW configuration, and CORE will use
it as buffer alignment.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 1 +
 drivers/gpu/drm/arm/display/komeda/komeda_kms.c  | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index f517ab0ceae9..a6ca3ff16fef 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -518,6 +518,7 @@ d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
 	chip->arch_id	= malidp_read32(reg_base, GLB_ARCH_ID);
 	chip->core_id	= malidp_read32(reg_base, GLB_CORE_ID);
 	chip->core_info	= malidp_read32(reg_base, GLB_CORE_INFO);
+	chip->bus_width	= D71_BUS_WIDTH_16_BYTES;
 
 	return &d71_chip_funcs;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
index 337e6fddead0..ed54beaee2f9 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
@@ -21,10 +21,10 @@ static int komeda_gem_cma_dumb_create(struct drm_file *file,
 				      struct drm_device *dev,
 				      struct drm_mode_create_dumb *args)
 {
-	u32 alignment = 16; /* TODO get alignment from dev */
+	struct komeda_dev *mdev = dev->dev_private;
+	u32 pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
 
-	args->pitch = ALIGN(DIV_ROUND_UP(args->width * args->bpp, 8),
-			    alignment);
+	args->pitch = ALIGN(pitch, mdev->chip.bus_width);
 
 	return drm_gem_cma_dumb_create_internal(file, dev, args);
 }
-- 
2.17.1


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

end of thread, other threads:[~2019-01-22 11:12 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-22 11:10 [PATCH v2 00/11] Implement komeda DRM-Crtc james qian wang (Arm Technology China)
2019-01-22 11:10 ` [PATCH v2 01/11] drm/komeda: Add komeda_build_display_data_flow james qian wang (Arm Technology China)
2019-01-22 11:10 ` [PATCH v2 02/11] drm/komeda: Add komeda_release_unclaimed_resources james qian wang (Arm Technology China)
2019-01-22 11:10 ` [PATCH v2 03/11] drm/komeda: Add komeda_crtc_atomic_flush james qian wang (Arm Technology China)
2019-01-22 11:10 ` [PATCH v2 04/11] drm/komeda: Add komeda_crtc_mode_valid/fixup james qian wang (Arm Technology China)
2019-01-22 11:11 ` [PATCH v2 05/11] drm/komeda: Add komeda_crtc_prepare/unprepare james qian wang (Arm Technology China)
2019-01-22 11:11 ` [PATCH v2 06/11] drm/komeda: Add komeda_crtc_atomic_enable/disable james qian wang (Arm Technology China)
2019-01-22 11:11 ` [PATCH v2 07/11] drm/komeda: Add komeda_crtc_vblank_enable/disable james qian wang (Arm Technology China)
2019-01-22 11:11 ` [PATCH v2 08/11] drm/komeda: Add komeda_crtc_funcs james qian wang (Arm Technology China)
2019-01-22 11:11 ` [PATCH v2 09/11] drm/komeda: Add komeda_kms_check james qian wang (Arm Technology China)
2019-01-22 11:11 ` [PATCH v2 10/11] drm/komeda: Add sysfs attribute: core_id and config_id james qian wang (Arm Technology China)
2019-01-22 11:12 ` [PATCH v2 11/11] drm/komeda: Expose bus_width to Komeda-CORE james qian wang (Arm Technology China)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).