All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Mahesh Kumar <mahesh1.kumar@intel.com>
Cc: intel-gfx@lists.freedesktop.org, dhinakaran.pandiyan@intel.com,
	maarten.lankhorst@intel.com
Subject: Re: [PATCH] [RFC] drm/i915/skl+: enable PF_ID interlace mode in SKL
Date: Mon, 19 Jun 2017 16:05:37 +0300	[thread overview]
Message-ID: <20170619130537.GO12629@intel.com> (raw)
In-Reply-To: <ceaad868-7b1c-0789-7444-f1e0877bf607@intel.com>

On Mon, Jun 19, 2017 at 05:50:28PM +0530, Mahesh Kumar wrote:
> Hi Ville,
> 
> Thanks for review
> 
> 
> On Friday 16 June 2017 07:47 PM, Ville Syrjälä wrote:
> > On Wed, Jun 07, 2017 at 03:19:05PM +0530, Mahesh Kumar wrote:
> >> In previous GEN default Interlace mode enabled is IF-ID mode, but IF-ID
> >> mode has many limitations in SKL. This mode doesn't support y-tiling,
> >> 90-270 rotation is not supported & YUV-420 planar source pixel formats
> >> are not supported with above mode.
> > I think we'll want something much more simple for stable. And that
> > should probably be just -EINVAL if we try to do any of those
> > forbidden things with an interlaced mode.
> Agree.
> >
> >> This patch make changes to use PF-ID Interlace mode in SKL+ platforms.
> >> PF-ID mode require one scaler to be attached in pipe-scaling mode.
> >>    During WM calculation adjusted pixel rate need to be doubled.
> >>    During max_supported_pixel_format calculation vertical downscale is 2.0.
> >>
> >> Signed-off-by: Mahesh Kumar <mahesh1.kumar@intel.com>
> >> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90238
> >> ---
> >>   drivers/gpu/drm/i915/intel_atomic.c  | 13 ++++++++++
> >>   drivers/gpu/drm/i915/intel_display.c | 47 +++++++++++++++++++++++++++++++-----
> >>   drivers/gpu/drm/i915/intel_drv.h     | 10 ++++++++
> >>   drivers/gpu/drm/i915/intel_panel.c   |  9 +++++--
> >>   drivers/gpu/drm/i915/intel_pm.c      | 17 ++++++++++++-
> >>   5 files changed, 87 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
> >> index d791b3ef89b5..06ed2fc449d7 100644
> >> --- a/drivers/gpu/drm/i915/intel_atomic.c
> >> +++ b/drivers/gpu/drm/i915/intel_atomic.c
> >> @@ -248,6 +248,13 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
> >>   		return -EINVAL;
> >>   	}
> >>   
> >> +	if (num_scalers_need > 1 &&
> >> +			scaler_state->scaler_users & (1 << SKL_CRTC_INDEX) &&
> >> +			scaler_state->scaler_users & (1 << SKL_PF_ID_INDEX)) {
> >> +		DRM_ERROR("Can't attach scaler to CRTC in Interlace Mode\n");
> >> +		return -EINVAL;
> >> +	}
> > I thought the whole point of PF-ID here was that we can then do pipe
> > scaling (and other things). So this check looks wrong to me.
> With PF-ID we can have Y-tiled buffers, & 90/270 rotation enabled, It 
> doesn't explicitly talk about scaling.

PF-ID itself is scaling. Presumably you don't have to have exactly
2:1 scaling factor with PF-ID.

> BSpec doesn't limit us from using 2 scalers as a pipe scaler, still I 
> sent a query to HW team regarding same.

We don't want to use multiple scalers. I dubt that would even work. And
before SKL the panel fitter was a dedicated piece of hw anyway so there
was no way to even try to assign multiple scalers to the pipe.

>
> Current S/W framework doesn't allows us to attach multiple pipe-scalers 
> in a pipe (multiple scaler_id associated with one crtc_state). that's 
> the reason for above check.
> >
> > And I'm thinking we shouldn't be adding yet another scaler user for
> > this, and instead it should just be part of the normal pfit setup.
> To use existing scaler framework, we need one scaler-user to be 
> associated with it.
> If we use existing CRTC_INDEX user then there will be many corner cases 
> to handle.

I'm not 100% whether we need any adjustment in the pfit code itself.
The spec doesn't seem to tell us that we need to adjust the panel
fitter window in any way. That's a little inconsistent with the
resulting scaling factor, but I guess the hw will automagically reduce
the destination size by two when the pipe is in the PF-ID mode.

So I think it should mostly be a simple matter of calling the pfit
code to set up the pos/size, and then you should just adjust
ilk_pipe_pixel_rate() to double the resulting pixel rate.

That said, I'm not really sure we want to flip PF-ID on automagically.
It would result in scaling when the user doesn't necessarily want it.
So we might want to think about some kind if property to control this
stuff.

> To make it simple I added new scaler-user.
> This code uses pfit setup only  to attach/enable Pipe-scaler.
> Please let me know if I didn't understood your concern correctly.
> Any other suggestions/queries are welcome.
> 
> -Mahesh
> 
> >
> >> +
> >>   	/* walkthrough scaler_users bits and start assigning scalers */
> >>   	for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
> >>   		int *scaler_id;
> >> @@ -264,6 +271,12 @@ int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
> >>   
> >>   			/* panel fitter case: assign as a crtc scaler */
> >>   			scaler_id = &scaler_state->scaler_id;
> >> +		} else if (i == SKL_PF_ID_INDEX) {
> >> +			name = "PF-ID INTERLACE MODE";
> >> +			idx = intel_crtc->base.base.id;
> >> +
> >> +			/* PF-ID interlaced mode case: needs a pipe scaler */
> >> +			scaler_id = &scaler_state->scaler_id;
> >>   		} else {
> >>   			name = "PLANE";
> >>   
> >> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> >> index 85ac32549e85..15c79b46d645 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -4626,6 +4626,11 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
> >>   	 */
> >>   	need_scaling = src_w != dst_w || src_h != dst_h;
> >>   
> >> +	if ((crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> >> +		&& scaler_user == SKL_PF_ID_INDEX)
> >> +		/* PF-ID Interlace mode needs a scaler */
> >> +		need_scaling = true;
> >> +
> >>   	/*
> >>   	 * if plane is being disabled or scaler is no more required or force detach
> >>   	 *  - free scaler binded to this plane/crtc
> >> @@ -4635,16 +4640,24 @@ skl_update_scaler(struct intel_crtc_state *crtc_state, bool force_detach,
> >>   	 * scaler can be assigned to other user. Actual register
> >>   	 * update to free the scaler is done in plane/panel-fit programming.
> >>   	 * For this purpose crtc/plane_state->scaler_id isn't reset here.
> >> +	 * Now Interlace mode is a new user of pipe-scaler, so free the scaler-id
> >> +	 * only if call is for respective user. If no user for scaler free it.
> >>   	 */
> >>   	if (force_detach || !need_scaling) {
> >> -		if (*scaler_id >= 0) {
> >> +		if (*scaler_id >= 0 &&
> >> +		    scaler_state->scaler_users & (1 << scaler_user)) {
> >>   			scaler_state->scaler_users &= ~(1 << scaler_user);
> >>   			scaler_state->scalers[*scaler_id].in_use = 0;
> >>   
> >>   			DRM_DEBUG_KMS("scaler_user index %u.%u: "
> >>   				"Staged freeing scaler id %d scaler_users = 0x%x\n",
> >> -				intel_crtc->pipe, scaler_user, *scaler_id,
> >> -				scaler_state->scaler_users);
> >> +				intel_crtc->pipe, scaler_user,
> >> +				*scaler_id, scaler_state->scaler_users);
> >> +
> >> +			*scaler_id = -1;
> >> +		}
> >> +		if (*scaler_id >= 0 && !scaler_state->scaler_users) {
> >> +			scaler_state->scalers[*scaler_id].in_use = 0;
> >>   			*scaler_id = -1;
> >>   		}
> >>   		return 0;
> >> @@ -4691,6 +4704,16 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
> >>   		adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
> >>   }
> >>   
> >> +static int skl_update_scaler_crtc_pf_id_output(struct intel_crtc_state *state)
> >> +{
> >> +	const struct drm_display_mode *mode = &state->base.adjusted_mode;
> >> +
> >> +	return skl_update_scaler(state, !state->base.active,
> >> +		SKL_PF_ID_INDEX, &state->scaler_state.scaler_id,
> >> +		state->pipe_src_w, state->pipe_src_h,
> >> +		mode->crtc_hdisplay, mode->crtc_vdisplay);
> >> +}
> >> +
> >>   /**
> >>    * skl_update_scaler_plane - Stages update to scaler state for a given plane.
> >>    *
> >> @@ -6258,6 +6281,15 @@ static int intel_crtc_compute_config(struct intel_crtc *crtc,
> >>   		}
> >>   	}
> >>   
> >> +	if (INTEL_GEN(dev_priv) >= 9) {
> >> +		if (skl_update_scaler_crtc_pf_id_output(pipe_config)) {
> >> +			DRM_ERROR("Unable to set scaler for PF-ID mode\n");
> >> +			return -EINVAL;
> >> +		}
> >> +		intel_pch_panel_fitting(crtc, pipe_config,
> >> +					DRM_MODE_SCALE_FULLSCREEN);
> >> +	}
> >> +
> >>   	if (adjusted_mode->crtc_clock > clock_limit) {
> >>   		DRM_DEBUG_KMS("requested pixel clock (%d kHz) too high (max: %d kHz, double wide: %s)\n",
> >>   			      adjusted_mode->crtc_clock, clock_limit,
> >> @@ -8045,9 +8077,12 @@ static void haswell_set_pipeconf(struct drm_crtc *crtc)
> >>   	if (IS_HASWELL(dev_priv) && intel_crtc->config->dither)
> >>   		val |= (PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP);
> >>   
> >> -	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> >> -		val |= PIPECONF_INTERLACED_ILK;
> >> -	else
> >> +	if (intel_crtc->config->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
> >> +		if (INTEL_GEN(dev_priv) >= 9)
> >> +			val |= PIPECONF_PFIT_PF_INTERLACED_ILK;
> >> +		else
> >> +			val |= PIPECONF_INTERLACED_ILK;
> >> +	} else
> >>   		val |= PIPECONF_PROGRESSIVE;
> >>   
> >>   	I915_WRITE(PIPECONF(cpu_transcoder), val);
> >> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> >> index 83dd40905821..d4546f6498b9 100644
> >> --- a/drivers/gpu/drm/i915/intel_drv.h
> >> +++ b/drivers/gpu/drm/i915/intel_drv.h
> >> @@ -483,6 +483,7 @@ struct intel_crtc_scaler_state {
> >>   	 * avilability.
> >>   	 */
> >>   #define SKL_CRTC_INDEX 31
> >> +#define SKL_PF_ID_INDEX 29
> >>   	unsigned scaler_users;
> >>   
> >>   	/* scaler used by crtc for panel fitting purpose */
> >> @@ -1206,6 +1207,15 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
> >>   	return container_of(intel_hdmi, struct intel_digital_port, hdmi);
> >>   }
> >>   
> >> +static inline bool
> >> +is_skl_interlace_mode(struct drm_i915_private *dev_priv,
> >> +		      const struct drm_display_mode *mode)
> >> +{
> >> +	if (INTEL_GEN(dev_priv) < 9)
> >> +		return false;
> >> +	return mode->flags & DRM_MODE_FLAG_INTERLACE;
> >> +}
> >> +
> >>   /* intel_fifo_underrun.c */
> >>   bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
> >>   					   enum pipe pipe, bool enable);
> >> diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
> >> index 4114cb3f14e7..fae7fe7802f8 100644
> >> --- a/drivers/gpu/drm/i915/intel_panel.c
> >> +++ b/drivers/gpu/drm/i915/intel_panel.c
> >> @@ -108,9 +108,14 @@ intel_pch_panel_fitting(struct intel_crtc *intel_crtc,
> >>   	const struct drm_display_mode *adjusted_mode = &pipe_config->base.adjusted_mode;
> >>   	int x = 0, y = 0, width = 0, height = 0;
> >>   
> >> -	/* Native modes don't need fitting */
> >> +	/*
> >> +	 * Native modes don't need fitting
> >> +	 * PF-ID Interlace mode in SKL+ require a pipe scaler
> >> +	 */
> >>   	if (adjusted_mode->crtc_hdisplay == pipe_config->pipe_src_w &&
> >> -	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h)
> >> +	    adjusted_mode->crtc_vdisplay == pipe_config->pipe_src_h &&
> >> +	    !(is_skl_interlace_mode(to_i915(intel_crtc->base.dev),
> >> +				    adjusted_mode)))
> >>   		goto done;
> >>   
> >>   	switch (fitting_mode) {
> >> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> >> index aa9d8cef7ce0..dfb21f00fbed 100644
> >> --- a/drivers/gpu/drm/i915/intel_pm.c
> >> +++ b/drivers/gpu/drm/i915/intel_pm.c
> >> @@ -3873,15 +3873,18 @@ static uint_fixed_16_16_t
> >>   skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
> >>   {
> >>   	uint_fixed_16_16_t pipe_downscale = u32_to_fixed_16_16(1);
> >> +	const struct drm_display_mode *mode;
> >>   
> >>   	if (!crtc_state->base.enable)
> >>   		return pipe_downscale;
> >>   
> >> +	mode = &crtc_state->base.adjusted_mode;
> >>   	if (crtc_state->pch_pfit.enabled) {
> >>   		uint32_t src_w, src_h, dst_w, dst_h;
> >>   		uint32_t pfit_size = crtc_state->pch_pfit.size;
> >>   		uint_fixed_16_16_t fp_w_ratio, fp_h_ratio;
> >>   		uint_fixed_16_16_t downscale_h, downscale_w;
> >> +		uint_fixed_16_16_t min_h_downscale;
> >>   
> >>   		src_w = crtc_state->pipe_src_w;
> >>   		src_h = crtc_state->pipe_src_h;
> >> @@ -3891,10 +3894,19 @@ skl_pipe_downscale_amount(const struct intel_crtc_state *crtc_state)
> >>   		if (!dst_w || !dst_h)
> >>   			return pipe_downscale;
> >>   
> >> +		/*
> >> +		 * Interlace mode require 1 scaler so no other scaler can be
> >> +		 * attached to pipe. PF-ID mode is equivalent to 2.0 vertical
> >> +		 * downscale.
> >> +		 */
> >> +		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
> >> +			min_h_downscale = u32_to_fixed_16_16(2);
> >> +		else
> >> +			min_h_downscale = u32_to_fixed_16_16(1);
> >>   		fp_w_ratio = fixed_16_16_div(src_w, dst_w);
> >>   		fp_h_ratio = fixed_16_16_div(src_h, dst_h);
> >>   		downscale_w = max_fixed_16_16(fp_w_ratio, u32_to_fixed_16_16(1));
> >> -		downscale_h = max_fixed_16_16(fp_h_ratio, u32_to_fixed_16_16(1));
> >> +		downscale_h = max_fixed_16_16(fp_h_ratio, min_h_downscale);
> >>   
> >>   		pipe_downscale = mul_fixed16(downscale_w, downscale_h);
> >>   	}
> >> @@ -4418,6 +4430,9 @@ skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cstate,
> >>   	 * with additional adjustments for plane-specific scaling.
> >>   	 */
> >>   	adjusted_pixel_rate = cstate->pixel_rate;
> >> +	if (cstate->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE)
> >> +		adjusted_pixel_rate *= 2;
> >> +
> >>   	downscale_amount = skl_plane_downscale_amount(cstate, pstate);
> >>   
> >>   	return mul_round_up_u32_fixed16(adjusted_pixel_rate,
> >> -- 
> >> 2.11.0
> >>
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> https://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

  reply	other threads:[~2017-06-19 13:05 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-07  9:49 [PATCH] [RFC] drm/i915/skl+: enable PF_ID interlace mode in SKL Mahesh Kumar
2017-06-07 10:51 ` ✓ Fi.CI.BAT: success for " Patchwork
2017-06-16 14:17 ` [PATCH] [RFC] " Ville Syrjälä
2017-06-19 12:20   ` Mahesh Kumar
2017-06-19 13:05     ` Ville Syrjälä [this message]
2017-06-20  7:45       ` Mahesh Kumar

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=20170619130537.GO12629@intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=dhinakaran.pandiyan@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=maarten.lankhorst@intel.com \
    --cc=mahesh1.kumar@intel.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.