All of lore.kernel.org
 help / color / mirror / Atom feed
From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>
To: Liviu Dudau <Liviu.Dudau@arm.com>,
	"airlied@linux.ie" <airlied@linux.ie>,
	Brian Starkey <Brian.Starkey@arm.com>,
	"maarten.lankhorst@linux.intel.com" 
	<maarten.lankhorst@linux.intel.com>,
	"sean@poorly.run" <sean@poorly.run>
Cc: "Jonathan Chai (Arm Technology China)" <Jonathan.Chai@arm.com>,
	"Julien Yin (Arm Technology China)" <Julien.Yin@arm.com>,
	"thomas Sun (Arm Technology China)" <thomas.Sun@arm.com>,
	"Lowry Li (Arm Technology China)" <Lowry.Li@arm.com>,
	Ayan Halder <Ayan.Halder@arm.com>,
	"Tiannan Zhu (Arm Technology China)" <Tiannan.Zhu@arm.com>,
	"Yiqi Kang (Arm Technology China)" <Yiqi.Kang@arm.com>,
	nd <nd@arm.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>, Ben Davis <Ben.Davis@arm.com>,
	"Oscar Zhang (Arm Technology China)" <Oscar.Zhang@arm.com>,
	"Channing Chen (Arm Technology China)" <Channing.Chen@arm.com>,
	"james qian wang (Arm Technology China)"
	<james.qian.wang@arm.com>
Subject: [PATCH 2/2] drm/komeda: Enable writeback split support
Date: Thu, 30 May 2019 10:44:11 +0000	[thread overview]
Message-ID: <20190530104335.2395-3-james.qian.wang@arm.com> (raw)
In-Reply-To: <20190530104335.2395-1-james.qian.wang@arm.com>

Writeback split is also for workaround the size limitation of d71 scaler.
Like layer_split, writeback downscaling also can use two scalers to handle
the scaling half-by-half. The only differnence is writback needs a
standalone component (splitter)'s help to split the composition result.
The data pipeline of writeback split as below:

                   /-> scaler-0 ->\
 compiz -> splitter                merger -> wb_layer -> memory
                   \-> scaler-1 ->/

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |   4 +
 .../display/komeda/komeda_pipeline_state.c    | 117 ++++++++++++++++--
 .../arm/display/komeda/komeda_wb_connector.c  |  17 ++-
 3 files changed, 124 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 4632fc5ec71f..9057dc512cf2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -524,6 +524,10 @@ int komeda_build_layer_split_data_flow(struct komeda_layer *left,
 				       struct komeda_plane_state *kplane_st,
 				       struct komeda_crtc_state *kcrtc_st,
 				       struct komeda_data_flow_cfg *dflow);
+int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer,
+				    struct drm_connector_state *conn_st,
+				    struct komeda_crtc_state *kcrtc_st,
+				    struct komeda_data_flow_cfg *dflow);

 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
 				       struct komeda_crtc_state *kcrtc_st);
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 82ea6cf9a989..afd857ef2239 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -284,30 +284,33 @@ komeda_layer_check_cfg(struct komeda_layer *layer,
 		       struct komeda_fb *kfb,
 		       struct komeda_data_flow_cfg *dflow)
 {
-	u32 hsize_in, vsize_in;
+	u32 src_x, src_y, src_w, src_h;

 	if (!komeda_fb_is_layer_supported(kfb, layer->layer_type, dflow->rot))
 		return -EINVAL;

-	if (komeda_fb_check_src_coords(kfb, dflow->in_x, dflow->in_y,
-				       dflow->in_w, dflow->in_h))
-		return -EINVAL;
-
 	if (layer->base.id == KOMEDA_COMPONENT_WB_LAYER) {
-		hsize_in = dflow->out_w;
-		vsize_in = dflow->out_h;
+		src_x = dflow->out_x;
+		src_y = dflow->out_y;
+		src_w = dflow->out_w;
+		src_h = dflow->out_h;
 	} else {
-		hsize_in = dflow->in_w;
-		vsize_in = dflow->in_h;
+		src_x = dflow->in_x;
+		src_y = dflow->in_y;
+		src_w = dflow->in_w;
+		src_h = dflow->in_h;
 	}

-	if (!in_range(&layer->hsize_in, hsize_in)) {
-		DRM_DEBUG_ATOMIC("invalidate src_w %d.\n", hsize_in);
+	if (komeda_fb_check_src_coords(kfb, src_x, src_y, src_w, src_h))
+		return -EINVAL;
+
+	if (!in_range(&layer->hsize_in, src_w)) {
+		DRM_DEBUG_ATOMIC("invalidate src_w %d.\n", src_w);
 		return -EINVAL;
 	}

-	if (!in_range(&layer->vsize_in, vsize_in)) {
-		DRM_DEBUG_ATOMIC("invalidate src_h %d.\n", vsize_in);
+	if (!in_range(&layer->vsize_in, src_h)) {
+		DRM_DEBUG_ATOMIC("invalidate src_h %d.\n", src_h);
 		return -EINVAL;
 	}

@@ -534,6 +537,59 @@ komeda_scaler_validate(void *user,
 	return err;
 }

+static void komeda_split_data_flow(struct komeda_scaler *scaler,
+				   struct komeda_data_flow_cfg *dflow,
+				   struct komeda_data_flow_cfg *l_dflow,
+				   struct komeda_data_flow_cfg *r_dflow);
+
+static int
+komeda_splitter_validate(struct komeda_splitter *splitter,
+			 struct drm_connector_state *conn_st,
+			 struct komeda_data_flow_cfg *dflow,
+			 struct komeda_data_flow_cfg *l_output,
+			 struct komeda_data_flow_cfg *r_output)
+{
+	struct komeda_component_state *c_st;
+	struct komeda_splitter_state *st;
+
+	if (!splitter) {
+		DRM_DEBUG_ATOMIC("Current HW doesn't support splitter.\n");
+		return -EINVAL;
+	}
+
+	if (!in_range(&splitter->hsize, dflow->in_w)) {
+		DRM_DEBUG_ATOMIC("split in_w:%d is out of the acceptable range.\n",
+				 dflow->in_w);
+		return -EINVAL;
+	}
+
+	if (!in_range(&splitter->vsize, dflow->in_h)) {
+		DRM_DEBUG_ATOMIC("split in_in: %d exceed the acceptable range.\n",
+				 dflow->in_w);
+		return -EINVAL;
+	}
+
+	c_st = komeda_component_get_state_and_set_user(&splitter->base,
+			conn_st->state, conn_st->connector, conn_st->crtc);
+
+	if (IS_ERR(c_st))
+		return PTR_ERR(c_st);
+
+	komeda_split_data_flow(splitter->base.pipeline->scalers[0],
+			       dflow, l_output, r_output);
+
+	st = to_splitter_st(c_st);
+	st->hsize = dflow->in_w;
+	st->vsize = dflow->in_h;
+	st->overlap = dflow->overlap;
+
+	komeda_component_add_input(&st->base, &dflow->input, 0);
+	komeda_component_set_output(&l_output->input, &splitter->base, 0);
+	komeda_component_set_output(&r_output->input, &splitter->base, 1);
+
+	return 0;
+}
+
 static int
 komeda_merger_validate(struct komeda_merger *merger,
 		       void *user,
@@ -1031,6 +1087,41 @@ int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
 	return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
 }

+/* writeback scaling split data path:
+ *                   /-> scaler ->\
+ * compiz -> splitter              merger -> wb_layer -> memory
+ *                   \-> scaler ->/
+ */
+int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer,
+				    struct drm_connector_state *conn_st,
+				    struct komeda_crtc_state *kcrtc_st,
+				    struct komeda_data_flow_cfg *dflow)
+{
+	struct komeda_pipeline *pipe = wb_layer->base.pipeline;
+	struct drm_connector *conn = conn_st->connector;
+	struct komeda_data_flow_cfg l_dflow, r_dflow;
+	int err;
+
+	err = komeda_splitter_validate(pipe->splitter, conn_st,
+				       dflow, &l_dflow, &r_dflow);
+	if (err)
+		return err;
+	err = komeda_scaler_validate(conn, kcrtc_st, &l_dflow);
+	if (err)
+		return err;
+
+	err = komeda_scaler_validate(conn, kcrtc_st, &r_dflow);
+	if (err)
+		return err;
+
+	err = komeda_merger_validate(pipe->merger, conn_st, kcrtc_st,
+				     &l_dflow, &r_dflow, dflow);
+	if (err)
+		return err;
+
+	return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
+}
+
 /* build display output data flow, the data path is:
  * compiz -> improc -> timing_ctrlr
  */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 2613bb0d79ce..4e26b2786ce0 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -13,6 +13,7 @@ komeda_wb_init_data_flow(struct komeda_layer *wb_layer,
 			 struct komeda_crtc_state *kcrtc_st,
 			 struct komeda_data_flow_cfg *dflow)
 {
+	struct komeda_scaler *scaler = wb_layer->base.pipeline->scalers[0];
 	struct drm_framebuffer *fb = conn_st->writeback_job->fb;

 	memset(dflow, 0, sizeof(*dflow));
@@ -29,6 +30,13 @@ komeda_wb_init_data_flow(struct komeda_layer *wb_layer,

 	komeda_complete_data_flow_cfg(dflow, fb);

+	/* if scaling exceed the acceptable scaler input/output range, try to
+	 * enable split.
+	 */
+	if (dflow->needs_scaling && scaler)
+		dflow->needs_split = !in_range(&scaler->hsize, dflow->in_w) ||
+				     !in_range(&scaler->hsize, dflow->out_w);
+
 	return 0;
 }

@@ -65,7 +73,14 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
 	if (err)
 		return err;

-	return komeda_build_wb_data_flow(wb_layer, conn_st, kcrtc_st, &dflow);
+	if (dflow.needs_split)
+		err = komeda_build_wb_split_data_flow(wb_layer,
+				conn_st, kcrtc_st, &dflow);
+	else
+		err = komeda_build_wb_data_flow(wb_layer,
+				conn_st, kcrtc_st, &dflow);
+
+	return err;
 }

 static const struct drm_encoder_helper_funcs komeda_wb_encoder_helper_funcs = {
--
2.17.1

  parent reply	other threads:[~2019-05-30 10:44 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-30 10:43 [PATCH 0/2] drm/komeda: Add writeback downscaling split support james qian wang (Arm Technology China)
2019-05-30 10:43 ` james qian wang (Arm Technology China)
2019-05-30 10:44 ` [PATCH 1/2] drm/komeda: Add new component komeda_splitter james qian wang (Arm Technology China)
2019-05-30 10:44   ` james qian wang (Arm Technology China)
2019-05-30 10:44 ` james qian wang (Arm Technology China) [this message]
2019-05-30 10:44   ` [PATCH 2/2] drm/komeda: Enable writeback split support james qian wang (Arm Technology China)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190530104335.2395-3-james.qian.wang@arm.com \
    --to=james.qian.wang@arm.com \
    --cc=Ayan.Halder@arm.com \
    --cc=Ben.Davis@arm.com \
    --cc=Brian.Starkey@arm.com \
    --cc=Channing.Chen@arm.com \
    --cc=Jonathan.Chai@arm.com \
    --cc=Julien.Yin@arm.com \
    --cc=Liviu.Dudau@arm.com \
    --cc=Lowry.Li@arm.com \
    --cc=Oscar.Zhang@arm.com \
    --cc=Tiannan.Zhu@arm.com \
    --cc=Yiqi.Kang@arm.com \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=nd@arm.com \
    --cc=sean@poorly.run \
    --cc=thomas.Sun@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.