public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>
To: Mihail Atanassov <Mihail.Atanassov@arm.com>
Cc: nd <nd@arm.com>, 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>,
	"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>,
	"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>
Subject: Re: [PATCH v3 2/6] drm/komeda: Add side by side plane_state split
Date: Tue, 19 Nov 2019 08:42:51 +0000	[thread overview]
Message-ID: <20191119084244.GB2881@jamwan02-TSP300> (raw)
In-Reply-To: <2843645.837eivR4I8@e123338-lin>

On Fri, Nov 15, 2019 at 12:00:01AM +0000, Mihail Atanassov wrote:
> On Thursday, 14 November 2019 08:37:31 GMT james qian wang (Arm Technology China) wrote:
> > On side by side mode, The full display frame will be split into two parts
> > (Left/Right), and each part will be handled by a single pipeline separately
> > master pipeline for left part, slave for right.
> > 
> > To simplify the usage and implementation, komeda use the following scheme
> > to do the side by side split
> > 1. The planes also have been grouped into two classes:
> >    master-planes and slave-planes.
> > 2. The master plane can display its image on any location of the final/full
> >    display frame, komeda will help to split the plane configuration to two
> >    parts and fed them into master and slave pipelines.
> > 3. The slave plane only can put its display rect on the right part of the
> >    final display frame, and its data is only can be fed into the slave
> >    pipeline.
> > 
> > From the perspective of resource usage and assignment:
> > The master plane can use the resources from the master pipeline and slave
> > pipeline both, but slave plane only can use the slave pipeline resources.
> > 
> > With such scheme, the usage of master planes are same as the none
> > side_by_side mode. user can easily skip the slave planes and no need to
> > consider side_by_side for them.
> > 
> > Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
> > ---
> >  .../drm/arm/display/komeda/komeda_pipeline.h  |  33 ++-
> >  .../display/komeda/komeda_pipeline_state.c    | 188 ++++++++++++++++++
> >  .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
> >  3 files changed, 220 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
> > index 20a076cce635..4c0946fbaac1 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
> > @@ -521,6 +521,20 @@ komeda_component_pickup_output(struct komeda_component *c, u32 avail_comps)
> >  	return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
> >  }
> >  
> > +static inline const char *
> > +komeda_data_flow_msg(struct komeda_data_flow_cfg *config)
> > +{
> > +	static char str[128];
> > +
> > +	snprintf(str, sizeof(str),
> > +		 "rot: %x src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]",
> > +		 config->rot,
> > +		 config->in_x, config->in_y, config->in_w, config->in_h,
> > +		 config->out_x, config->out_y, config->out_w, config->out_h);
> > +
> > +	return str;
> > +}
> > +
> >  struct komeda_plane_state;
> >  struct komeda_crtc_state;
> >  struct komeda_crtc;
> > @@ -532,22 +546,27 @@ 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_wb_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_build_display_data_flow(struct komeda_crtc *kcrtc,
> > -				   struct komeda_crtc_state *kcrtc_st);
> > -
> >  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_layer_sbs_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_wb_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_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_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);
> >  
> > 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 0930234abb9d..5de0d231a1c3 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
> > @@ -1130,6 +1130,194 @@ int komeda_build_layer_split_data_flow(struct komeda_layer *left,
> >  	return err;
> >  }
> >  
> > +/* split func will split configuration of master plane to two layer data
> > + * flows, which will be fed into master and slave pipeline then.
> > + * NOTE: @m_dflow is first used as input argument to pass the configuration of
> > + *	 master_plane. when the split is done, @*m_dflow @*s_dflow are the
> > + *	 output data flow for pipeline.
> > + */
> > +static int
> > +komeda_split_sbs_master_data_flow(struct komeda_crtc_state *kcrtc_st,
> > +				  struct komeda_data_flow_cfg **m_dflow,
> > +				  struct komeda_data_flow_cfg **s_dflow)
> > +{
> > +	struct komeda_data_flow_cfg *master = *m_dflow;
> > +	struct komeda_data_flow_cfg *slave = *s_dflow;
> > +	u32 disp_end = master->out_x + master->out_w;
> > +	u16 boundary;
> > +
> > +	pipeline_composition_size(kcrtc_st, &boundary, NULL);
> > +
> > +	if (disp_end <= boundary) {
> > +		/* the master viewport only located in master side, no need
> > +		 * slave anymore
> > +		 */
> > +		*s_dflow = NULL;
> > +	} else if ((master->out_x < boundary) && (disp_end > boundary)) {
> > +		/* the master viewport across two pipelines, split it */
> > +		bool flip_h = has_flip_h(master->rot);
> > +		bool r90  = drm_rotation_90_or_270(master->rot);
> > +		u32 src_x = master->in_x;
> > +		u32 src_y = master->in_y;
> > +		u32 src_w = master->in_w;
> > +		u32 src_h = master->in_h;
> > +
> > +		if (master->en_scaling || master->en_img_enhancement) {
> > +			DRM_DEBUG_ATOMIC("sbs doesn't support to split a scaling image.\n");
> > +			return -EINVAL;
> > +		}
> > +
> > +		memcpy(slave, master, sizeof(*master));
> > +
> > +		/* master for left part of display, slave for the right part */
> > +		/* split the disp_rect */
> > +		master->out_w = boundary - master->out_x;
> > +		slave->out_w  = disp_end - boundary;
> > +		slave->out_x  = 0;
> > +
> > +		if (r90) {
> > +			master->in_h = master->out_w;
> > +			slave->in_h = slave->out_w;
> > +
> > +			if (flip_h)
> > +				master->in_y = src_y + src_h - master->in_h;
> > +			else
> > +				slave->in_y = src_y + src_h - slave->in_h;
> > +		} else {
> > +			master->in_w = master->out_w;
> > +			slave->in_w = slave->out_w;
> > +
> > +			/* on flip_h, the left display content from the right-source */
> > +			if (flip_h)
> > +				master->in_x = src_w + src_x - master->in_w;
> > +			else
> > +				slave->in_x = src_w + src_x - slave->in_w;
> 
> It really bugs me that the order here is w/x/w but in the block above
> it's y/h/h.

will refine the order to x/w/w.

> > +		}
> > +	} else if (master->out_x >= boundary) {
> > +		/* disp_rect only locate in right part, move the dflow to slave */
> > +		master->out_x -= boundary;
> > +		*s_dflow = master;
> > +		*m_dflow = NULL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int
> > +komeda_split_sbs_slave_data_flow(struct komeda_crtc_state *kcrtc_st,
> > +				 struct komeda_data_flow_cfg *slave)
> > +{
> > +	u16 boundary;
> > +
> > +	pipeline_composition_size(kcrtc_st, &boundary, NULL);
> > +
> > +	if (slave->out_x < boundary) {
> > +		DRM_DEBUG_ATOMIC("SBS Slave plane is only allowed to configure the right part frame.\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	/* slave->disp_rect locate in the right part */
> > +	slave->out_x -= boundary;
> > +
> > +	return 0;
> > +}
> > +
> > +/* On side by side mode, The full display frame will be split to two parts
> > + * (Left/Right), and each part will be handled by a single pipeline separately,
> > + * master pipeline for left part, slave for right.
> > + *
> > + * To simplify the usage and implementation, komeda use the following scheme
> > + * to do the side by side split
> > + * 1. The planes also have been grouped into two classes:
> > + *    master-planes and slave-planes.
> > + * 2. The master plane can display its image on any location of the final/full
> > + *    display frame, komeda will help to split the plane configuration to two
> > + *    parts and fed them into master and slave pipelines.
> > + * 3. The slave plane only can put its display rect on the right part of the
> > + *    final display frame, and its data is only can be fed into the slave
> > + *    pipeline.
> > + *
> > + * From the perspective of resource usage and assignment:
> > + * The master plane can use the resources from the master pipeline and slave
> > + * pipeline both, but slave plane only can use the slave pipeline resources.
> > + *
> > + * With such scheme, the usage of master planes are same as the none
> > + * side_by_side mode. user can easily skip the slave planes and no need to
> > + * consider side_by_side for them.
> > + *
> > + * NOTE: side_by_side split is occurred on pipeline level which split the plane
> > + *	 data flow into pipelines, but the layer split is a pipeline
> > + *	 internal split which splits the data flow into pipeline layers.
> > + *	 So komeda still supports to apply a further layer split to the sbs
> > + *	 split data flow.
> > + */
> > +int komeda_build_layer_sbs_data_flow(struct komeda_layer *layer,
> > +				     struct komeda_plane_state *kplane_st,
> > +				     struct komeda_crtc_state *kcrtc_st,
> > +				     struct komeda_data_flow_cfg *dflow)
> > +{
> > +	struct komeda_crtc *kcrtc = to_kcrtc(kcrtc_st->base.crtc);
> > +	struct drm_plane *plane = kplane_st->base.plane;
> > +	struct komeda_data_flow_cfg temp, *master_dflow, *slave_dflow;
> > +	struct komeda_layer *master, *slave;
> > +	bool master_plane = layer->base.pipeline == kcrtc->master;
> > +	int err;
> > +
> > +	DRM_DEBUG_ATOMIC("SBS prepare %s-[PLANE:%d:%s]: %s.\n",
> > +			 master_plane ? "Master" : "Slave",
> > +			 plane->base.id, plane->name,
> > +			 komeda_data_flow_msg(dflow));
> > +
> > +	if (master_plane) {
> > +		master = layer;
> > +		slave = layer->sbs_slave;
> > +		master_dflow = dflow;
> > +		slave_dflow  = &temp;
> > +		err = komeda_split_sbs_master_data_flow(kcrtc_st,
> > +				&master_dflow, &slave_dflow);
> > +	} else {
> > +		master = NULL;
> > +		slave = layer;
> > +		master_dflow = NULL;
> > +		slave_dflow = dflow;
> > +		err = komeda_split_sbs_slave_data_flow(kcrtc_st, slave_dflow);
> > +	}
> > +
> > +	if (err)
> > +		return err;
> > +
> > +	if (master_dflow) {
> > +		DRM_DEBUG_ATOMIC("SBS Master-%s assigned: %s\n",
> > +			master->base.name, komeda_data_flow_msg(master_dflow));
> > +
> > +		if (master_dflow->en_split)
> > +			err = komeda_build_layer_split_data_flow(master,
> > +					kplane_st, kcrtc_st, master_dflow);
> > +		else
> > +			err = komeda_build_layer_data_flow(master,
> > +					kplane_st, kcrtc_st, master_dflow);
> > +
> > +		if (err)
> > +			return err;
> > +	}
> > +
> > +	if (slave_dflow) {
> > +		DRM_DEBUG_ATOMIC("SBS Slave-%s assigned: %s\n",
> > +			slave->base.name, komeda_data_flow_msg(slave_dflow));
> > +
> > +		if (slave_dflow->en_split)
> > +			err = komeda_build_layer_split_data_flow(slave,
> > +					kplane_st, kcrtc_st, slave_dflow);
> > +		else
> > +			err = komeda_build_layer_data_flow(slave,
> > +					kplane_st, kcrtc_st, slave_dflow);
> > +		if (err)
> > +			return err;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  /* writeback data path: compiz -> scaler -> wb_layer -> memory */
> >  int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
> >  			      struct drm_connector_state *conn_st,
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> > index 98e915e325dd..2644f0727570 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
> > @@ -77,6 +77,7 @@ komeda_plane_atomic_check(struct drm_plane *plane,
> >  	struct komeda_plane_state *kplane_st = to_kplane_st(state);
> >  	struct komeda_layer *layer = kplane->layer;
> >  	struct drm_crtc_state *crtc_st;
> > +	struct komeda_crtc *kcrtc;
> >  	struct komeda_crtc_state *kcrtc_st;
> >  	struct komeda_data_flow_cfg dflow;
> >  	int err;
> > @@ -94,13 +95,17 @@ komeda_plane_atomic_check(struct drm_plane *plane,
> >  	if (!crtc_st->active)
> >  		return 0;
> >  
> > +	kcrtc = to_kcrtc(crtc_st->crtc);
> >  	kcrtc_st = to_kcrtc_st(crtc_st);
> >  
> >  	err = komeda_plane_init_data_flow(state, kcrtc_st, &dflow);
> >  	if (err)
> >  		return err;
> >  
> > -	if (dflow.en_split)
> > +	if (kcrtc->side_by_side)
> > +		err = komeda_build_layer_sbs_data_flow(layer,
> > +				kplane_st, kcrtc_st, &dflow);
> > +	else if (dflow.en_split)
> >  		err = komeda_build_layer_split_data_flow(layer,
> >  				kplane_st, kcrtc_st, &dflow);
> >  	else
> > 
> 
> 
> -- 
> Mihail
> 
> 

  reply	other threads:[~2019-11-19  8:43 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-14  8:37 [PATCH v3 0/6] arm/komeda: Add side_by_side support james qian wang (Arm Technology China)
2019-11-14  8:37 ` [PATCH v3 1/6] drm/komeda: Add side by side assembling james qian wang (Arm Technology China)
2019-11-15  0:02   ` Mihail Atanassov
2019-11-19  9:22     ` james qian wang (Arm Technology China)
2019-11-14  8:37 ` [PATCH v3 2/6] drm/komeda: Add side by side plane_state split james qian wang (Arm Technology China)
2019-11-15  0:00   ` Mihail Atanassov
2019-11-19  8:42     ` james qian wang (Arm Technology China) [this message]
2019-11-14  8:37 ` [PATCH v3 3/6] drm/komeda: Build side by side display output pipeline james qian wang (Arm Technology China)
2019-11-14  8:37 ` [PATCH v3 4/6] drm/komeda: Add side by side support for writeback james qian wang (Arm Technology China)
2019-11-14  8:37 ` [PATCH v3 5/6] drm/komeda: Update writeback signal for side_by_side james qian wang (Arm Technology China)
2019-11-14  8:37 ` [PATCH v3 6/6] drm/komeda: Expose side_by_side by sysfs/config_id 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=20191119084244.GB2881@jamwan02-TSP300 \
    --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=Mihail.Atanassov@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox