Re: [PATCH 1/2] drm/framebuffer: Format modifier for Intel Gen-12 render compression

2019-09-07 Thread Dhinakaran Pandiyan
On Sat, 2019-09-07 at 00:21 -0700, Dhinakaran Pandiyan wrote:
> Gen-12 has a new compression format, add a new modifier to indicate that.
> 
> Cc: Ville Syrjälä 
> Cc: Matt Roper 
> Cc: Nanley G Chery 
> Cc: Jason Ekstrand 
Cc: dri-devel@lists.freedesktop.org 

> Signed-off-by: Dhinakaran Pandiyan 
> Signed-off-by: Lucas De Marchi 
> ---
>  include/uapi/drm/drm_fourcc.h | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index 3feeaa3f987a..1f0fbf0398f6 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -410,6 +410,17 @@ extern "C" {
>  #define I915_FORMAT_MOD_Y_TILED_CCS  fourcc_mod_code(INTEL, 4)
>  #define I915_FORMAT_MOD_Yf_TILED_CCS fourcc_mod_code(INTEL, 5)
>  
> +/*
> + * Intel color control surfaces (CCS) for Gen-12 render compression.
> + *
> + * The main surface is Y-tiled and at plane index 0, the CCS is linear and
> + * at index 1. A 64B CCS cache line corresponds to an area of 4x1 tiles in
> + * main surface. In other words, 4 bits in CCS map to a main surface cache
> + * line pair. The main surface pitch is required to be a multiple of four
> + * Y-tile widths.
> + */
> +#define I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS fourcc_mod_code(INTEL, 6)
> +
>  /*
>   * Tiled, NV12MT, grouped in 64 (pixels) x 32 (lines) -sized macroblocks
>   *

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

Re: [Intel-gfx] [PATCH] drm/connector: Allow max possible encoders to attach to a connector

2019-06-26 Thread Dhinakaran Pandiyan
On Wed, 2019-06-26 at 16:31 +0200, Daniel Vetter wrote:
> On Wed, Jun 26, 2019 at 04:43:28PM +0300, Ville Syrjälä wrote:
> > On Tue, Jun 25, 2019 at 04:40:45PM -0700, Dhinakaran Pandiyan wrote:
> > > Currently we restrict the number of encoders that can be linked to
> > > a connector to 3, increase it to match the maximum number of encoders
> > > that can be initialized - 32. The current limitation looks artificial.
> > > Increasing the limit to 32 does however increases the size of the static
> > > u32 array keeping track of the encoder IDs.
> > > 
> > > Cc: José Roberto de Souza 
> > > Cc: Ville Syrjälä 
> > > Cc: dri-devel@lists.freedesktop.org
> > > Signed-off-by: Dhinakaran Pandiyan 
> > > ---
> > >  include/drm/drm_connector.h | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > > index ca745d9feaf5..91455b4a9360 100644
> > > --- a/include/drm/drm_connector.h
> > > +++ b/include/drm/drm_connector.h
> > > @@ -1278,7 +1278,7 @@ struct drm_connector {
> > >   /** @override_edid: has the EDID been overwritten through debugfs for
> > > testing? */
> > >   bool override_edid;
> > >  
> > > -#define DRM_CONNECTOR_MAX_ENCODER 3
> > > +#define DRM_CONNECTOR_MAX_ENCODER 32
> > >   /**
> > >* @encoder_ids: Valid encoders for this connector. Please only use
> > >* drm_connector_for_each_possible_encoder() to enumerate these.
> > 
> > I wonder if we couldn't just replace this array with a bitmask?
> > I think the for_each_possible_encoder() thing I did a while back
> > should make this easier potentially because most driver code just
> > uses that.
> 
> +1 on possible encoders bitmask. More consistent at least.

Agreed, I'll make this change.

-DK

> -Daniel

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

[PATCH] drm/connector: Allow max possible encoders to attach to a connector

2019-06-25 Thread Dhinakaran Pandiyan
Currently we restrict the number of encoders that can be linked to
a connector to 3, increase it to match the maximum number of encoders
that can be initialized - 32. The current limitation looks artificial.
Increasing the limit to 32 does however increases the size of the static
u32 array keeping track of the encoder IDs.

Cc: José Roberto de Souza 
Cc: Ville Syrjälä 
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Dhinakaran Pandiyan 
---
 include/drm/drm_connector.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ca745d9feaf5..91455b4a9360 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1278,7 +1278,7 @@ struct drm_connector {
/** @override_edid: has the EDID been overwritten through debugfs for 
testing? */
bool override_edid;
 
-#define DRM_CONNECTOR_MAX_ENCODER 3
+#define DRM_CONNECTOR_MAX_ENCODER 32
/**
 * @encoder_ids: Valid encoders for this connector. Please only use
 * drm_connector_for_each_possible_encoder() to enumerate these.
-- 
2.17.1

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

Re: [PATCH v2 3/3] drm/i915: DDI: call intel_psr_ and _edp_drrs_enable() on pipe updates (v2)

2018-12-21 Thread Dhinakaran Pandiyan
On Thu, 2018-12-20 at 15:13 -0800, Dhinakaran Pandiyan wrote:
> On Thu, 2018-12-20 at 09:10 -0800, Rodrigo Vivi wrote:
> > On Thu, Dec 20, 2018 at 02:21:20PM +0100, Hans de Goede wrote:
> > > Call intel_psr_enable() and intel_edp_drrs_enable() on pipe
> > > updates
> > > to make
> > > sure that we enable PSR / DRRS (when applicable) on fastsets.
> 
> I am probably missing something, doesn't intel_pipe_config_compare()
> need to check for pipe_config->has_psr? And also read the hardware
> PSR
> state at boot?
Answering my own question here, pipe_config_compare() returns true
lacking a comparison for ->has_psr. And we assume the bios does not
enable PSR, so no need to read the hardware state.
> > > 
> > > Note calling these functions when PSR / DRRS has already been
> > > enabled is a
> > > no-op, so it is safe to do this on every encoder->update_pipe
> > > callback.
> > > 
> > > Changes in v2:
> > > -Merge the patches adding the intel_psr_enable() and
> > > intel_edp_drrs_enable()
> > >  calls into a single patch
> > > 
> > > Reviewed-by: Maarten Lankhorst  > > >
> > > Signed-off-by: Hans de Goede 
> > 
> > Cc: Dhinakaran Pandiyan 
> > Cc: José Roberto de Souza 
> > 
> > Acked-by: Rodrigo Vivi 
> > 
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c | 19 +++
> > >  1 file changed, 19 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> > > b/drivers/gpu/drm/i915/intel_ddi.c
> > > index e3cc19e19199..fdf57f451b72 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -3537,6 +3537,24 @@ static void intel_disable_ddi(struct
> > > intel_encoder *encoder,
> > >   intel_disable_ddi_dp(encoder, old_crtc_state,
> > > old_conn_state);
> > >  }
> > >  
> > > +static void intel_ddi_update_pipe_dp(struct intel_encoder
> > > *encoder,
> > > +  const struct intel_crtc_state
> > > *crtc_state,
> > > +  const struct drm_connector_state
> > > *conn_state)
> > > +{
> > > + struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> > > +
> > > + intel_psr_enable(intel_dp, crtc_state);
> > > + intel_edp_drrs_enable(intel_dp, crtc_state);
> > > +}
> > > +
> > > +static void intel_ddi_update_pipe(struct intel_encoder *encoder,
> > > +   const struct intel_crtc_state
> > > *crtc_state,
> > > +   const struct drm_connector_state
> > > *conn_state)
> > > +{
> > > + if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> 
> We could restrict this to eDP outputs as both PSR and DRRS are eDP
> features.
> 
> > > + intel_ddi_update_pipe_dp(encoder, crtc_state,
> > > conn_state);
> > > +}
> > > +
> > >  static void intel_ddi_set_fia_lane_count(struct intel_encoder
> > > *encoder,
> > >const struct intel_crtc_state
> > > *pipe_config,
> > >enum port port)
> > > @@ -4169,6 +4187,7 @@ void intel_ddi_init(struct drm_i915_private
> > > *dev_priv, enum port port)
> > >   intel_encoder->pre_enable = intel_ddi_pre_enable;
> > >   intel_encoder->disable = intel_disable_ddi;
> > >   intel_encoder->post_disable = intel_ddi_post_disable;
> > > + intel_encoder->update_pipe = intel_ddi_update_pipe;
> > >   intel_encoder->get_hw_state = intel_ddi_get_hw_state;
> > >   intel_encoder->get_config = intel_ddi_get_config;
> > >   intel_encoder->suspend = intel_ddi_encoder_suspend;
> > > -- 
> > > 2.20.1
> > > 

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


Re: [PATCH] drm/i915/psr: simplify enable_psr handling

2018-12-21 Thread Dhinakaran Pandiyan
On Fri, 2018-12-21 at 10:23 -0700, Ross Zwisler wrote:
> The following commit:
> 
> commit 2bdd045e3a30 ("drm/i915/psr: Check if VBT says PSR can be
> enabled.")
> 
> added some code with no usable functionality.  Regardless of how the
> psr
> default is set up in the BDB_DRIVER_FEATURES section, if the
> enable_psr
> module parameter isn't specified it defaults to 0.
Right, that was intentional and the commit message even makes a note of
it 
" Note: The feature currently remains disabled by default for all
platforms irrespective of what VBT says."


Anyway, we've enabled the feature by default now and the current code
should take into account the VBT flag if the module parameter is left
to a default value. Please check git://anongit.freedesktop.org/drm-tip
drm-tip.

-DK
> 
> Remove this dead code, simplify the way that enable_psr is handled
> and
> update the module parameter string to match the actual functionality.
> 
> Cc: Dhinakaran Pandiyan 
> Cc: Rodrigo Vivi 
> Signed-off-by: Ross Zwisler 
> ---
>  drivers/gpu/drm/i915/i915_drv.h| 1 -
>  drivers/gpu/drm/i915/i915_params.c | 4 +---
>  drivers/gpu/drm/i915/i915_params.h | 2 +-
>  drivers/gpu/drm/i915/intel_bios.c  | 1 -
>  drivers/gpu/drm/i915/intel_psr.c   | 7 ---
>  5 files changed, 2 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 872a2e159a5f9..b4c50ba0b22a6 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1115,7 +1115,6 @@ struct intel_vbt_data {
>   } edp;
>  
>   struct {
> - bool enable;
>   bool full_link;
>   bool require_aux_wakeup;
>   int idle_frames;
> diff --git a/drivers/gpu/drm/i915/i915_params.c
> b/drivers/gpu/drm/i915/i915_params.c
> index 295e981e4a398..80ce8758c3c69 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -87,9 +87,7 @@ i915_param_named_unsafe(enable_ppgtt, int, 0400,
>   "(-1=auto [default], 0=disabled, 1=aliasing, 2=full, 3=full
> with extended address space)");
>  
>  i915_param_named_unsafe(enable_psr, int, 0600,
> - "Enable PSR "
> - "(0=disabled, 1=enabled) "
> - "Default: -1 (use per-chip default)");
> + "Enable PSR (default: false)");
>  
>  i915_param_named_unsafe(alpha_support, bool, 0400,
>   "Enable alpha quality driver support for latest hardware. "
> diff --git a/drivers/gpu/drm/i915/i915_params.h
> b/drivers/gpu/drm/i915/i915_params.h
> index 6c4d4a21474b5..144572f17a83d 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -42,7 +42,7 @@ struct drm_printer;
>   param(int, enable_dc, -1) \
>   param(int, enable_fbc, -1) \
>   param(int, enable_ppgtt, -1) \
> - param(int, enable_psr, -1) \
> + param(int, enable_psr, 0) \
>   param(int, disable_power_well, -1) \
>   param(int, enable_ips, 1) \
>   param(int, invert_brightness, 0) \
> diff --git a/drivers/gpu/drm/i915/intel_bios.c
> b/drivers/gpu/drm/i915/intel_bios.c
> index 1faa494e2bc91..d676d483d5cf1 100644
> --- a/drivers/gpu/drm/i915/intel_bios.c
> +++ b/drivers/gpu/drm/i915/intel_bios.c
> @@ -551,7 +551,6 @@ parse_driver_features(struct drm_i915_private
> *dev_priv,
>*/
>   if (!driver->drrs_enabled)
>   dev_priv->vbt.drrs_type = DRRS_NOT_SUPPORTED;
> - dev_priv->vbt.psr.enable = driver->psr_enabled;
>  }
>  
>  static void
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index b6838b525502e..26e7eb318cf07 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -1065,13 +1065,6 @@ void intel_psr_init(struct drm_i915_private
> *dev_priv)
>   if (!dev_priv->psr.sink_support)
>   return;
>  
> - if (i915_modparams.enable_psr == -1) {
> - i915_modparams.enable_psr = dev_priv->vbt.psr.enable;
> -
> - /* Per platform default: all disabled. */
> - i915_modparams.enable_psr = 0;
> - }
> -
>   /* Set link_standby x link_off defaults */
>   if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
>   /* HSW and BDW require workarounds that we don't
> implement. */

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


Re: [PATCH v2 3/3] drm/i915: DDI: call intel_psr_ and _edp_drrs_enable() on pipe updates (v2)

2018-12-20 Thread Dhinakaran Pandiyan
On Thu, 2018-12-20 at 09:10 -0800, Rodrigo Vivi wrote:
> On Thu, Dec 20, 2018 at 02:21:20PM +0100, Hans de Goede wrote:
> > Call intel_psr_enable() and intel_edp_drrs_enable() on pipe updates
> > to make
> > sure that we enable PSR / DRRS (when applicable) on fastsets.

I am probably missing something, doesn't intel_pipe_config_compare()
need to check for pipe_config->has_psr? And also read the hardware PSR
state at boot?

> > 
> > Note calling these functions when PSR / DRRS has already been
> > enabled is a
> > no-op, so it is safe to do this on every encoder->update_pipe
> > callback.
> > 
> > Changes in v2:
> > -Merge the patches adding the intel_psr_enable() and
> > intel_edp_drrs_enable()
> >  calls into a single patch
> > 
> > Reviewed-by: Maarten Lankhorst 
> > Signed-off-by: Hans de Goede 
> 
> Cc: Dhinakaran Pandiyan 
> Cc: José Roberto de Souza 
> 
> Acked-by: Rodrigo Vivi 
> 
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c | 19 +++
> >  1 file changed, 19 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c
> > b/drivers/gpu/drm/i915/intel_ddi.c
> > index e3cc19e19199..fdf57f451b72 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -3537,6 +3537,24 @@ static void intel_disable_ddi(struct
> > intel_encoder *encoder,
> > intel_disable_ddi_dp(encoder, old_crtc_state,
> > old_conn_state);
> >  }
> >  
> > +static void intel_ddi_update_pipe_dp(struct intel_encoder
> > *encoder,
> > +const struct intel_crtc_state
> > *crtc_state,
> > +const struct drm_connector_state
> > *conn_state)
> > +{
> > +   struct intel_dp *intel_dp = enc_to_intel_dp(>base);
> > +
> > +   intel_psr_enable(intel_dp, crtc_state);
> > +   intel_edp_drrs_enable(intel_dp, crtc_state);
> > +}
> > +
> > +static void intel_ddi_update_pipe(struct intel_encoder *encoder,
> > + const struct intel_crtc_state
> > *crtc_state,
> > + const struct drm_connector_state
> > *conn_state)
> > +{
> > +   if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))

We could restrict this to eDP outputs as both PSR and DRRS are eDP
features.

> > +   intel_ddi_update_pipe_dp(encoder, crtc_state,
> > conn_state);
> > +}
> > +
> >  static void intel_ddi_set_fia_lane_count(struct intel_encoder
> > *encoder,
> >  const struct intel_crtc_state
> > *pipe_config,
> >  enum port port)
> > @@ -4169,6 +4187,7 @@ void intel_ddi_init(struct drm_i915_private
> > *dev_priv, enum port port)
> > intel_encoder->pre_enable = intel_ddi_pre_enable;
> > intel_encoder->disable = intel_disable_ddi;
> > intel_encoder->post_disable = intel_ddi_post_disable;
> > +   intel_encoder->update_pipe = intel_ddi_update_pipe;
> > intel_encoder->get_hw_state = intel_ddi_get_hw_state;
> > intel_encoder->get_config = intel_ddi_get_config;
> > intel_encoder->suspend = intel_ddi_encoder_suspend;
> > -- 
> > 2.20.1
> > 

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


Re: [Intel-gfx] [PATCH 2/4] drm/i915: Use drm_hdmi_avi_infoframe_quant_range() for SDVO HDMI as well

2018-12-17 Thread Dhinakaran Pandiyan
On Thu, 2018-12-13 at 15:09 -0800, Dhinakaran Pandiyan wrote:
> On Thu, 2018-12-13 at 07:18 +0200, Ville Syrjälä wrote:
> > On Wed, Dec 12, 2018 at 04:32:02PM -0800, Dhinakaran Pandiyan
> > wrote:
> > > On Tue, 2018-11-20 at 18:13 +0200, Ville Syrjala wrote:
> > > > From: Ville Syrjälä 
> > > > 
> > > > Fill out the AVI infoframe quantization range bits using
> > > > drm_hdmi_avi_infoframe_quant_range() for SDVO HDMI encoder as
> > > > well.
> > > > 
> > > > Signed-off-by: Ville Syrjälä 
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_sdvo.c | 19 ++-
> > > >  1 file changed, 10 insertions(+), 9 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c
> > > > b/drivers/gpu/drm/i915/intel_sdvo.c
> > > > index 1277d31adb54..9c16e273fb8d 100644
> > > > --- a/drivers/gpu/drm/i915/intel_sdvo.c
> > > > +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> > > > @@ -984,6 +984,8 @@ static bool
> > > > intel_sdvo_set_avi_infoframe(struct
> > > > intel_sdvo *intel_sdvo,
> > > >  const struct
> > > > intel_crtc_state
> > > > *pipe_config,
> > > >  const struct
> > > > drm_connector_state *conn_state)
> > > >  {
> > > > +   const struct drm_display_mode *adjusted_mode =
> > > > +   _config->base.adjusted_mode;
> > > > uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)];
> > > > union hdmi_infoframe frame;
> > > > int ret;
> > > > @@ -991,20 +993,19 @@ static bool
> > > > intel_sdvo_set_avi_infoframe(struct
> > > > intel_sdvo *intel_sdvo,
> > > >  
> > > > ret =
> > > > drm_hdmi_avi_infoframe_from_display_mode(,
> > > >conn_sta
> > > > te-
> > > > > connector,
> > > > 
> > > > -  _co
> > > > nfig-
> > > > > base.adjusted_mode);
> > > > 
> > > > +  adjusted
> > > > _mode);
> > > > if (ret < 0) {
> > > > DRM_ERROR("couldn't fill AVI infoframe\n");
> > > > return false;
> > > > }
> > > >  
> > > > -   if (intel_sdvo->rgb_quant_range_selectable) {
> > > > -   if (pipe_config->limited_color_range)
> > > > -   frame.avi.quantization_range =
> > > > -   HDMI_QUANTIZATION_RANGE_LIMITED
> > > > ;
> > > > -   else
> > > > -   frame.avi.quantization_range =
> > > > -   HDMI_QUANTIZATION_RANGE_FULL;
> > > > -   }
> > > > +   drm_hdmi_avi_infoframe_quant_range(,
> > > > +  conn_state-
> > > > >connector,
> > > > +  adjusted_mode,
> > > > +  pipe_config-
> > > > > limited_color_range ?
> > > > 
> > > > +  rgb_quant_range_sele
> > > > ctableTE
> > > > D :
> > > > +  HDMI_QUANTIZATION_RA
> > > > NGE_FULL
> > > > ,
> > > > +  intel_sdvo-
> > > > > rgb_quant_range_selectable);
> > > 
> > > Seems like avi.quantization_range can now get set to _LIMITED or
> > > _FULL
> > > even when ->rgb_quant_range_selectable == false, i.e., it is not
> > > _DEFAULT anymore. Is that change in behavior intended?
> > 
> > ->quant_range_selectable will be passed to
> > drm_hdmi_avi_infoframe_quant_range() which will do the right thing
> > with
> > it.
> > 
> > That said, there is a slight behavioural change in that it will set
> 
> Okay, I was indeed referring to this case.
> 
> > the Q bit even with QS==1 iff the quantization range matches the
> > default quantization range for the mode. I noted this in the radeon
> > patch but forgot to mention it here.
> 
> I'll let someone else with knowledge of HDMI to review this
> behavioral 
> change. I'm trying to get hold of the HDMI spec now and will review
> if
> this hasn't been looked at by then.
> 
Looks alright now that I went through the specs. With commit message
updated to make note of the Q value changes

Reviewed-by: Dhinakaran Pandiyan 
> 
> > 
> > > 
> > > 
> > > >  
> > > > len = hdmi_infoframe_pack(, sdvo_data,
> > > > sizeof(sdvo_data));
> > > > if (len < 0)
> > 
> > 

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


Re: [Intel-gfx] [PATCH 2/4] drm/i915: Use drm_hdmi_avi_infoframe_quant_range() for SDVO HDMI as well

2018-12-13 Thread Dhinakaran Pandiyan
On Thu, 2018-12-13 at 07:18 +0200, Ville Syrjälä wrote:
> On Wed, Dec 12, 2018 at 04:32:02PM -0800, Dhinakaran Pandiyan wrote:
> > On Tue, 2018-11-20 at 18:13 +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > Fill out the AVI infoframe quantization range bits using
> > > drm_hdmi_avi_infoframe_quant_range() for SDVO HDMI encoder as
> > > well.
> > > 
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/intel_sdvo.c | 19 ++-
> > >  1 file changed, 10 insertions(+), 9 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_sdvo.c
> > > b/drivers/gpu/drm/i915/intel_sdvo.c
> > > index 1277d31adb54..9c16e273fb8d 100644
> > > --- a/drivers/gpu/drm/i915/intel_sdvo.c
> > > +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> > > @@ -984,6 +984,8 @@ static bool
> > > intel_sdvo_set_avi_infoframe(struct
> > > intel_sdvo *intel_sdvo,
> > >const struct intel_crtc_state
> > > *pipe_config,
> > >const struct
> > > drm_connector_state *conn_state)
> > >  {
> > > + const struct drm_display_mode *adjusted_mode =
> > > + _config->base.adjusted_mode;
> > >   uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)];
> > >   union hdmi_infoframe frame;
> > >   int ret;
> > > @@ -991,20 +993,19 @@ static bool
> > > intel_sdvo_set_avi_infoframe(struct
> > > intel_sdvo *intel_sdvo,
> > >  
> > >   ret = drm_hdmi_avi_infoframe_from_display_mode(,
> > >  conn_state-
> > > > connector,
> > > 
> > > -_config-
> > > > base.adjusted_mode);
> > > 
> > > +adjusted_mode);
> > >   if (ret < 0) {
> > >   DRM_ERROR("couldn't fill AVI infoframe\n");
> > >   return false;
> > >   }
> > >  
> > > - if (intel_sdvo->rgb_quant_range_selectable) {
> > > - if (pipe_config->limited_color_range)
> > > - frame.avi.quantization_range =
> > > - HDMI_QUANTIZATION_RANGE_LIMITED;
> > > - else
> > > - frame.avi.quantization_range =
> > > - HDMI_QUANTIZATION_RANGE_FULL;
> > > - }
> > > + drm_hdmi_avi_infoframe_quant_range(,
> > > +conn_state->connector,
> > > +adjusted_mode,
> > > +pipe_config-
> > > > limited_color_range ?
> > > 
> > > +rgb_quant_range_selectableTE
> > > D :
> > > +HDMI_QUANTIZATION_RANGE_FULL
> > > ,
> > > +intel_sdvo-
> > > > rgb_quant_range_selectable);
> > 
> > Seems like avi.quantization_range can now get set to _LIMITED or
> > _FULL
> > even when ->rgb_quant_range_selectable == false, i.e., it is not
> > _DEFAULT anymore. Is that change in behavior intended?
> 
> ->quant_range_selectable will be passed to
> drm_hdmi_avi_infoframe_quant_range() which will do the right thing
> with
> it.
> 
> That said, there is a slight behavioural change in that it will set
Okay, I was indeed referring to this case.

> the Q bit even with QS==1 iff the quantization range matches the
> default quantization range for the mode. I noted this in the radeon
> patch but forgot to mention it here.
I'll let someone else with knowledge of HDMI to review this behavioral 
change. I'm trying to get hold of the HDMI spec now and will review if
this hasn't been looked at by then.


> 
> > 
> > 
> > >  
> > >   len = hdmi_infoframe_pack(, sdvo_data,
> > > sizeof(sdvo_data));
> > >   if (len < 0)
> 
> 

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


Re: [Intel-gfx] [PATCH 2/4] drm/i915: Use drm_hdmi_avi_infoframe_quant_range() for SDVO HDMI as well

2018-12-12 Thread Dhinakaran Pandiyan
On Tue, 2018-11-20 at 18:13 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Fill out the AVI infoframe quantization range bits using
> drm_hdmi_avi_infoframe_quant_range() for SDVO HDMI encoder as well.
> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_sdvo.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c
> b/drivers/gpu/drm/i915/intel_sdvo.c
> index 1277d31adb54..9c16e273fb8d 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -984,6 +984,8 @@ static bool intel_sdvo_set_avi_infoframe(struct
> intel_sdvo *intel_sdvo,
>const struct intel_crtc_state
> *pipe_config,
>const struct
> drm_connector_state *conn_state)
>  {
> + const struct drm_display_mode *adjusted_mode =
> + _config->base.adjusted_mode;
>   uint8_t sdvo_data[HDMI_INFOFRAME_SIZE(AVI)];
>   union hdmi_infoframe frame;
>   int ret;
> @@ -991,20 +993,19 @@ static bool intel_sdvo_set_avi_infoframe(struct
> intel_sdvo *intel_sdvo,
>  
>   ret = drm_hdmi_avi_infoframe_from_display_mode(,
>  conn_state-
> >connector,
> -_config-
> >base.adjusted_mode);
> +adjusted_mode);
>   if (ret < 0) {
>   DRM_ERROR("couldn't fill AVI infoframe\n");
>   return false;
>   }
>  
> - if (intel_sdvo->rgb_quant_range_selectable) {
> - if (pipe_config->limited_color_range)
> - frame.avi.quantization_range =
> - HDMI_QUANTIZATION_RANGE_LIMITED;
> - else
> - frame.avi.quantization_range =
> - HDMI_QUANTIZATION_RANGE_FULL;
> - }
> + drm_hdmi_avi_infoframe_quant_range(,
> +conn_state->connector,
> +adjusted_mode,
> +pipe_config-
> >limited_color_range ?
> +rgb_quant_range_selectableTE
> D :
> +HDMI_QUANTIZATION_RANGE_FULL
> ,
> +intel_sdvo-
> >rgb_quant_range_selectable);

Seems like avi.quantization_range can now get set to _LIMITED or _FULL
even when ->rgb_quant_range_selectable == false, i.e., it is not
_DEFAULT anymore. Is that change in behavior intended?


>  
>   len = hdmi_infoframe_pack(, sdvo_data,
> sizeof(sdvo_data));
>   if (len < 0)

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


Re: [Intel-gfx] [PATCH 3/5] drm/dp: Implement I2C_M_STOP for i2c-over-aux

2018-12-10 Thread Dhinakaran Pandiyan
On Fri, 2018-09-28 at 21:04 +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Consult the I2C_M_STOP flag to determine whether to set the MOT bit
> or
> not. Makes it possible to send multiple messages in one go with
> stop+start generated between the messages (as opposed nothing or
> repstart depending on whether thr address/rw changed).
> 
> Not sure anyone has actual use for this but figured I'd handle it
> since I started to look at that flag for MST remote i2c xfers.
> 
Don't see the I2C_M_STOP flag anywhere in drm_edid.c, but the change
introduced here does make sense.

Reviewed-by: Dhinakaran Pandiyan 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c
> b/drivers/gpu/drm/drm_dp_helper.c
> index 37c01b6076ec..e85cea299d2a 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -884,7 +884,8 @@ static void drm_dp_i2c_msg_set_request(struct
> drm_dp_aux_msg *msg,
>  {
>   msg->request = (i2c_msg->flags & I2C_M_RD) ?
>   DP_AUX_I2C_READ : DP_AUX_I2C_WRITE;
> - msg->request |= DP_AUX_I2C_MOT;
> + if (!(i2c_msg->flags & I2C_M_STOP))
> + msg->request |= DP_AUX_I2C_MOT;
>  }
>  
>  /*

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


Re: [PATCH] drm/dp: Set the MOT bit for Write_Status_Update_Request transactions

2018-12-10 Thread Dhinakaran Pandiyan
On Mon, 2018-12-10 at 23:29 +0200, Ville Syrjälä wrote:
> On Mon, Dec 10, 2018 at 01:07:49PM -0800, Dhinakaran Pandiyan wrote:
> > The Write_Status_Update_Request I2C transaction requires the MOT
> > bit to
> > be set, Change the logical AND to OR to fix what looks like a typo.
> 
> It's not a type. We're just preserving MOT. What makes you think it
> should always be set?
> 
The table defining request commands (2-148) has the MOT bit set for
Write_Status_Update_Request, doesn't make it look like an option when
querying the status. Checking the callers again, I see that we could
get a defer when ending an i2c transaction and that will require a
Write_Status_Update_Request with MOT unset. Sorry for the noise.




> > 
> > Cc: dri-devel@lists.freedesktop.org
> > Cc: Jani Nikula 
> > Cc: Ville Syrjälä 
> > Fixes: 68ec2a2a2481 ("drm/dp: Use I2C_WRITE_STATUS_UPDATE to drain
> > partial I2C_WRITE requests")
> > Signed-off-by: Dhinakaran Pandiyan 
> > ---
> >  drivers/gpu/drm/drm_dp_helper.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_dp_helper.c
> > b/drivers/gpu/drm/drm_dp_helper.c
> > index 2d6c491a0542..d98805b517f0 100644
> > --- a/drivers/gpu/drm/drm_dp_helper.c
> > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > @@ -677,7 +677,7 @@ static void
> > drm_dp_i2c_msg_write_status_update(struct drm_dp_aux_msg *msg)
> >  * rest of the message
> >  */
> > if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE) {
> > -   msg->request &= DP_AUX_I2C_MOT;
> > +   msg->request |= DP_AUX_I2C_MOT;
> > msg->request |= DP_AUX_I2C_WRITE_STATUS_UPDATE;
> > }
> >  }
> > -- 
> > 2.17.1
> 
> 

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


[PATCH] drm/dp: Set the MOT bit for Write_Status_Update_Request transactions

2018-12-10 Thread Dhinakaran Pandiyan
The Write_Status_Update_Request I2C transaction requires the MOT bit to
be set, Change the logical AND to OR to fix what looks like a typo.

Cc: dri-devel@lists.freedesktop.org
Cc: Jani Nikula 
Cc: Ville Syrjälä 
Fixes: 68ec2a2a2481 ("drm/dp: Use I2C_WRITE_STATUS_UPDATE to drain partial 
I2C_WRITE requests")
Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/drm_dp_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 2d6c491a0542..d98805b517f0 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -677,7 +677,7 @@ static void drm_dp_i2c_msg_write_status_update(struct 
drm_dp_aux_msg *msg)
 * rest of the message
 */
if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE) {
-   msg->request &= DP_AUX_I2C_MOT;
+   msg->request |= DP_AUX_I2C_MOT;
msg->request |= DP_AUX_I2C_WRITE_STATUS_UPDATE;
}
 }
-- 
2.17.1

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


Re: [Intel-gfx] [PATCH 1/5] drm/dp/mst: Configure no_stop_bit correctly for remote i2c xfers

2018-12-10 Thread Dhinakaran Pandiyan
On Mon, 2018-12-10 at 18:39 +0200, Ville Syrjälä wrote:
> On Fri, Dec 07, 2018 at 12:45:25PM -0800, Dhinakaran Pandiyan wrote:
> > On Fri, 2018-09-28 at 21:03 +0300, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > We aren't supposed to force a stop+start between every i2c msg
> > > when performing multi message transfers. This should eg. cause
> > > the DDC segment address to be reset back to 0 between writing
> > > the segment address and reading the actual EDID extension block.
> > > 
> > > To quote the E-DDC spec:
> > > "... this standard requires that the segment pointer be
> > >  reset to 00h when a NO ACK or a STOP condition is received."
> > 
> > Related question, do you know why the segment and ddc addresses are
> > defined as 0x30 and 0x50? The E-DDC spec says they should be at
> > 0x60
> > and 0xA0/0xA1.
> 
> The spec uses 'slave_address << 1 | r/w'.
Got it, thanks.

-DK

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


Re: [Intel-gfx] [PATCH 5/5] drm/dp/mst: Provide better debugs for NAK replies

2018-12-07 Thread Dhinakaran Pandiyan
On Fri, 2018-12-07 at 16:57 -0800, Dhinakaran Pandiyan wrote:
> On Fri, 2018-09-28 at 21:04 +0300, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > Decode the NAK reply fields to make it easier to parse the logs.
> 
> A lot better than seeing the error codes. 
> 
> 
> 0-day's found a conflicting definition that's missing an undef. With
> that addressed, 
> Reviewed-by: Dhinakaran Pandiyan 
> > 
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/drm_dp_mst_topology.c | 65
> > ++-
> >  include/drm/drm_dp_helper.h   |  1 +
> >  2 files changed, 65 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > index c0f754364cc7..1178c1655f9a 100644
> > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > @@ -66,6 +66,64 @@ static bool drm_dp_validate_guid(struct
> > drm_dp_mst_topology_mgr *mgr,
> >  static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux);
> >  static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux);
> >  static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr
> > *mgr);
> > +
> > +#define STR(x) [DP_ ## x] = #x
> > +
> > +static const char *drm_dp_mst_req_type_str(u8 req_type)
> > +{
> > +   static const char * const req_type_str[] = {
> > +   STR(GET_MSG_TRANSACTION_VERSION),
> > +   STR(LINK_ADDRESS),
> > +   STR(CONNECTION_STATUS_NOTIFY),
> > +   STR(ENUM_PATH_RESOURCES),
> > +   STR(ALLOCATE_PAYLOAD),
> > +   STR(QUERY_PAYLOAD),
> > +   STR(RESOURCE_STATUS_NOTIFY),
> > +   STR(CLEAR_PAYLOAD_ID_TABLE),
> > +   STR(REMOTE_DPCD_READ),
> > +   STR(REMOTE_DPCD_WRITE),
> > +   STR(REMOTE_I2C_READ),
> > +   STR(REMOTE_I2C_WRITE),
> > +   STR(POWER_UP_PHY),
> > +   STR(POWER_DOWN_PHY),
> > +   STR(SINK_EVENT_NOTIFY),
> > +   STR(QUERY_STREAM_ENC_STATUS),
> > +   };
> > +
> > +   if (req_type >= ARRAY_SIZE(req_type_str) ||
> > +   !req_type_str[req_type])
> > +   return "unknown";
> > +
> > +   return req_type_str[req_type];
> > +}

drm_dp_sideband_parse_reply() could also use the decoded string.

-DK

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


Re: [Intel-gfx] [PATCH 5/5] drm/dp/mst: Provide better debugs for NAK replies

2018-12-07 Thread Dhinakaran Pandiyan
On Fri, 2018-09-28 at 21:04 +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Decode the NAK reply fields to make it easier to parse the logs.
A lot better than seeing the error codes. 


0-day's found a conflicting definition that's missing an undef. With
that addressed, 
Reviewed-by: Dhinakaran Pandiyan 
> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 65
> ++-
>  include/drm/drm_dp_helper.h   |  1 +
>  2 files changed, 65 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index c0f754364cc7..1178c1655f9a 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -66,6 +66,64 @@ static bool drm_dp_validate_guid(struct
> drm_dp_mst_topology_mgr *mgr,
>  static int drm_dp_mst_register_i2c_bus(struct drm_dp_aux *aux);
>  static void drm_dp_mst_unregister_i2c_bus(struct drm_dp_aux *aux);
>  static void drm_dp_mst_kick_tx(struct drm_dp_mst_topology_mgr *mgr);
> +
> +#define STR(x) [DP_ ## x] = #x
> +
> +static const char *drm_dp_mst_req_type_str(u8 req_type)
> +{
> + static const char * const req_type_str[] = {
> + STR(GET_MSG_TRANSACTION_VERSION),
> + STR(LINK_ADDRESS),
> + STR(CONNECTION_STATUS_NOTIFY),
> + STR(ENUM_PATH_RESOURCES),
> + STR(ALLOCATE_PAYLOAD),
> + STR(QUERY_PAYLOAD),
> + STR(RESOURCE_STATUS_NOTIFY),
> + STR(CLEAR_PAYLOAD_ID_TABLE),
> + STR(REMOTE_DPCD_READ),
> + STR(REMOTE_DPCD_WRITE),
> + STR(REMOTE_I2C_READ),
> + STR(REMOTE_I2C_WRITE),
> + STR(POWER_UP_PHY),
> + STR(POWER_DOWN_PHY),
> + STR(SINK_EVENT_NOTIFY),
> + STR(QUERY_STREAM_ENC_STATUS),
> + };
> +
> + if (req_type >= ARRAY_SIZE(req_type_str) ||
> + !req_type_str[req_type])
> + return "unknown";
> +
> + return req_type_str[req_type];
> +}
> +
> +#undef STR
> +#define STR(x) [DP_NAK_ ## x] = #x
> +
> +static const char *drm_dp_mst_nak_reason_str(u8 nak_reason)
> +{
> + static const char * const nak_reason_str[] = {
> + STR(WRITE_FAILURE),
> + STR(INVALID_READ),
> + STR(CRC_FAILURE),
> + STR(BAD_PARAM),
> + STR(DEFER),
> + STR(LINK_FAILURE),
> + STR(NO_RESOURCES),
> + STR(DPCD_FAIL),
> + STR(I2C_NAK),
> + STR(ALLOCATE_FAIL),
> + };
> +
> + if (nak_reason >= ARRAY_SIZE(nak_reason_str) ||
> + !nak_reason_str[nak_reason])
> + return "unknown";
> +
> + return nak_reason_str[nak_reason];
> +}
> +
> +#undef STR
> +
>  /* sideband msg handling */
>  static u8 drm_dp_msg_header_crc4(const uint8_t *data, size_t
> num_nibbles)
>  {
> @@ -2349,7 +2407,12 @@ static int drm_dp_mst_handle_down_rep(struct
> drm_dp_mst_topology_mgr *mgr)
>  
>   drm_dp_sideband_parse_reply(>down_rep_recv,
> >reply);
>   if (txmsg->reply.reply_type == DP_REPLY_NAK) {
> - DRM_DEBUG_KMS("Got NAK reply: req 0x%02x,
> reason 0x%02x, nak data 0x%02x\n", txmsg->reply.req_type, txmsg-
> >reply.u.nak.reason, txmsg->reply.u.nak.nak_data);
> + DRM_DEBUG_KMS("Got NAK reply: req 0x%02x (%s),
> reason 0x%02x (%s), nak data 0x%02x\n",
> +   txmsg->reply.req_type,
> +   drm_dp_mst_req_type_str(txmsg-
> >reply.req_type),
> +   txmsg->reply.u.nak.reason,
> +   drm_dp_mst_nak_reason_str(txmsg-
> >reply.u.nak.reason),
> +   txmsg->reply.u.nak.nak_data);
>   }
>  
>   memset(>down_rep_recv, 0, sizeof(struct
> drm_dp_sideband_msg_rx));
> diff --git a/include/drm/drm_dp_helper.h
> b/include/drm/drm_dp_helper.h
> index 2a0fd9d7066e..2453767246fb 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -918,6 +918,7 @@
>  #define DP_PEER_DEVICE_DP_LEGACY_CONV0x4
>  
>  /* DP 1.2 MST sideband request names DP 1.2a Table 2-80 */
> +#define DP_GET_MSG_TRANSACTION_VERSION   0x00 /* DP 1.3 */
>  #define DP_LINK_ADDRESS  0x01
>  #define DP_CONNECTION_STATUS_NOTIFY  0x02
>  #define DP_ENUM_PATH_RESOURCES   0x10

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


Re: [Intel-gfx] [PATCH 4/5] drm/dp/mst: Provide defines for ACK vs. NAK reply type

2018-12-07 Thread Dhinakaran Pandiyan
 == 1) {
> + if (txmsg->reply.reply_type == DP_REPLY_NAK) {
>   DRM_DEBUG_KMS("Got NAK reply: req 0x%02x,
> reason 0x%02x, nak data 0x%02x\n", txmsg->reply.req_type, txmsg-
> >reply.u.nak.reason, txmsg->reply.u.nak.nak_data);
>   }
>  
> @@ -3306,7 +3306,7 @@ static int drm_dp_mst_i2c_xfer(struct
> i2c_adapter *adapter, struct i2c_msg *msgs
>   ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
>   if (ret > 0) {
>  
> - if (txmsg->reply.reply_type == 1) { /* got a NAK back
> */
> + if (txmsg->reply.reply_type == DP_REPLY_NAK) {
>   ret = -EREMOTEIO;
>   goto out;
>   }
> diff --git a/include/drm/drm_dp_helper.h
> b/include/drm/drm_dp_helper.h
> index 2a3843f248cf..2a0fd9d7066e 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -905,6 +905,10 @@
>  #define DP_AUX_HDCP_KSV_FIFO 0x6802C
>  #define DP_AUX_HDCP_AINFO0x6803B
>  
> +/* DP 1.2 MST sideband reply types */
> +#define DP_REPLY_ACK 0x00
> +#define DP_REPLY_NAK 0x01
> +
bikeshed: How about calling these DP_SIDEBAND_ACK or DP_SIDEBAND_NAK to
differentiate from native AUX replies? And also move it right next to
the NAK reason definition.

Will leave it to you if you want to implement those bikesheds,
Reviewed-by: Dhinakaran Pandiyan 


>  /* DP 1.2 Sideband message defines */
>  /* peer device type - DP 1.2a Table 2-92 */
>  #define DP_PEER_DEVICE_NONE  0x0

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


Re: [Intel-gfx] [PATCH 2/5] drm/dp/mst: Validate REMOTE_I2C_READ harder

2018-12-07 Thread Dhinakaran Pandiyan
On Fri, 2018-09-28 at 21:04 +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Make sure i2c msgs we're asked to transfer conform to the
> requirements of REMOTE_I2C_READ. We were only checking that the
> last message is a read, but we must also check that the preceding
> messages are all writes. Also check that the length of each
> message isn't too long.

Right, the syntax for i2c_remote_read allows only 8 bits for length.
Reviewed-by: Dhinakaran Pandiyan 


> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 25 ++---
>  1 file changed, 18 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 3b400eab18a2..a0652fc166c6 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3239,6 +3239,23 @@ void drm_dp_mst_topology_mgr_destroy(struct
> drm_dp_mst_topology_mgr *mgr)
>  }
>  EXPORT_SYMBOL(drm_dp_mst_topology_mgr_destroy);
>  
> +static bool remote_i2c_read_ok(const struct i2c_msg msgs[], int num)
> +{
> + int i;
> +
> + if (num - 1 > DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)
> + return false;
> +
> + for (i = 0; i < num - 1; i++) {
> + if (msgs[i].flags & I2C_M_RD ||
> + msgs[i].len > 0xff)
> + return false;
> + }
> +
> + return msgs[num - 1].flags & I2C_M_RD &&
> + msgs[num - 1].len <= 0xff;
> +}
> +
>  /* I2C device */
>  static int drm_dp_mst_i2c_xfer(struct i2c_adapter *adapter, struct
> i2c_msg *msgs,
>  int num)
> @@ -3248,7 +3265,6 @@ static int drm_dp_mst_i2c_xfer(struct
> i2c_adapter *adapter, struct i2c_msg *msgs
>   struct drm_dp_mst_branch *mstb;
>   struct drm_dp_mst_topology_mgr *mgr = port->mgr;
>   unsigned int i;
> - bool reading = false;
>   struct drm_dp_sideband_msg_req_body msg;
>   struct drm_dp_sideband_msg_tx *txmsg = NULL;
>   int ret;
> @@ -3257,12 +3273,7 @@ static int drm_dp_mst_i2c_xfer(struct
> i2c_adapter *adapter, struct i2c_msg *msgs
>   if (!mstb)
>   return -EREMOTEIO;
>  
> - /* construct i2c msg */
> - /* see if last msg is a read */
> - if (msgs[num - 1].flags & I2C_M_RD)
> - reading = true;
> -
> - if (!reading || (num - 1 >
> DP_REMOTE_I2C_READ_MAX_TRANSACTIONS)) {
> + if (!remote_i2c_read_ok(msgs, num)) {
>   DRM_DEBUG_KMS("Unsupported I2C transaction for MST
> device\n");
>   ret = -EIO;
>   goto out;

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


Re: [Intel-gfx] [PATCH 1/5] drm/dp/mst: Configure no_stop_bit correctly for remote i2c xfers

2018-12-07 Thread Dhinakaran Pandiyan
On Fri, 2018-12-07 at 12:45 -0800, Dhinakaran Pandiyan wrote:
> On Fri, 2018-09-28 at 21:03 +0300, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > We aren't supposed to force a stop+start between every i2c msg
> > when performing multi message transfers. This should eg. cause
> > the DDC segment address to be reset back to 0 between writing
> > the segment address and reading the actual EDID extension block.
> > 
> > To quote the E-DDC spec:
> > "... this standard requires that the segment pointer be
> >  reset to 00h when a NO ACK or a STOP condition is received."
> 
> Related question, do you know why the segment and ddc addresses are
> defined as 0x30 and 0x50? The E-DDC spec says they should be at 0x60
> and 0xA0/0xA1.
> 
> > 
> > Since we're going to touch this might as well consult the
> > I2C_M_STOP flag to determine whether we want to force the stop
> > or not.
> 
> Reviewing this took a lot of spec reading than I expected.
> 
> Setting the no_stop_bit after writing the segment address makes
> sense.
> I have one concern though. drm_do_probe_ddc_edid does not make use of
> the I2C_M_STOP flag, which in turn means we won't reset the
> no_stop_bit
> at the end of edid read. Pass the i2c stop flag from the caller?
> 
Never mind, the no_stop_bit is relevant only between i2c writes.
Reviewed-by: Dhinakaran Pandiyan 

> 
> > 
> > Cc: Brian Vincent 
> > References: https://bugs.freedesktop.org/show_bug.cgi?id=108081
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/drm_dp_mst_topology.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> > b/drivers/gpu/drm/drm_dp_mst_topology.c
> > index 5ff1d79b86c4..3b400eab18a2 100644
> > --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> > +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> > @@ -3276,6 +3276,7 @@ static int drm_dp_mst_i2c_xfer(struct
> > i2c_adapter *adapter, struct i2c_msg *msgs
> > msg.u.i2c_read.transactions[i].i2c_dev_id =
> > msgs[i].addr;
> > msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len;
> > msg.u.i2c_read.transactions[i].bytes = msgs[i].buf;
> > +   msg.u.i2c_read.transactions[i].no_stop_bit =
> > !(msgs[i].flags & I2C_M_STOP);
> > }
> > msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr;
> > msg.u.i2c_read.num_bytes_read = msgs[num - 1].len;

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


Re: [Intel-gfx] [PATCH 1/5] drm/dp/mst: Configure no_stop_bit correctly for remote i2c xfers

2018-12-07 Thread Dhinakaran Pandiyan
On Fri, 2018-09-28 at 21:03 +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> We aren't supposed to force a stop+start between every i2c msg
> when performing multi message transfers. This should eg. cause
> the DDC segment address to be reset back to 0 between writing
> the segment address and reading the actual EDID extension block.
> 
> To quote the E-DDC spec:
> "... this standard requires that the segment pointer be
>  reset to 00h when a NO ACK or a STOP condition is received."
Related question, do you know why the segment and ddc addresses are
defined as 0x30 and 0x50? The E-DDC spec says they should be at 0x60
and 0xA0/0xA1.

> 
> Since we're going to touch this might as well consult the
> I2C_M_STOP flag to determine whether we want to force the stop
> or not.
Reviewing this took a lot of spec reading than I expected.

Setting the no_stop_bit after writing the segment address makes sense.
I have one concern though. drm_do_probe_ddc_edid does not make use of
the I2C_M_STOP flag, which in turn means we won't reset the no_stop_bit
at the end of edid read. Pass the i2c stop flag from the caller?


> 
> Cc: Brian Vincent 
> References: https://bugs.freedesktop.org/show_bug.cgi?id=108081
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/drm_dp_mst_topology.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c
> b/drivers/gpu/drm/drm_dp_mst_topology.c
> index 5ff1d79b86c4..3b400eab18a2 100644
> --- a/drivers/gpu/drm/drm_dp_mst_topology.c
> +++ b/drivers/gpu/drm/drm_dp_mst_topology.c
> @@ -3276,6 +3276,7 @@ static int drm_dp_mst_i2c_xfer(struct
> i2c_adapter *adapter, struct i2c_msg *msgs
>   msg.u.i2c_read.transactions[i].i2c_dev_id =
> msgs[i].addr;
>   msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len;
>   msg.u.i2c_read.transactions[i].bytes = msgs[i].buf;
> + msg.u.i2c_read.transactions[i].no_stop_bit =
> !(msgs[i].flags & I2C_M_STOP);
>   }
>   msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr;
>   msg.u.i2c_read.num_bytes_read = msgs[num - 1].len;

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


Re: [PATCH] drm: Fix documentation generation for DP_DPCD_QUIRK_NO_PSR

2018-12-05 Thread Dhinakaran Pandiyan
On Wed, 2018-12-05 at 10:48 -0800, José Roberto de Souza wrote:
> The DP_DPCD_QUIRK_NO_PSR comment is missing colon causing this
> warning when generating kernel documentation.
> 
> ./include/drm/drm_dp_helper.h:1374: warning: Incorrect use of kernel-
> doc format:  * @DP_DPCD_QUIRK_NO_PSR
> 
Cc: dri-devel@lists.freedesktop.org
Reviewed-by: Dhinakaran Pandiyan 
> Fixes: 7c5c641a930e (drm/i915: Disable PSR in Apple panels)
> Cc: Dhinakaran Pandiyan 
> Signed-off-by: José Roberto de Souza 
> ---
>  include/drm/drm_dp_helper.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/drm/drm_dp_helper.h
> b/include/drm/drm_dp_helper.h
> index 18cfde45b8ed..c223c87ef119 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1370,7 +1370,7 @@ enum drm_dp_quirk {
>*/
>   DP_DPCD_QUIRK_CONSTANT_N,
>   /**
> -  * @DP_DPCD_QUIRK_NO_PSR
> +  * @DP_DPCD_QUIRK_NO_PSR:
>*
>* The device does not support PSR even if reports that it
> supports or
>* driver still need to implement proper handling for such
> device.

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


Re: [PATCH v2 10/11] drm/i915: Improve PSR2 CTL macros

2018-12-03 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> - Reusing the EDP_PSR2_FRAME_BEFORE_SU_SHIFT in
> EDP_PSR2_FRAME_BEFORE_SU
> - Removing unused EDP_PSR2_FRAME_BEFORE_SU_MASK
> - Adding EDP_PSR2_FRAME_BEFORE_SU_MAX
> - Adding EDP_PSR2_IDLE_FRAME()
> - Adding EDP_PSR2_IDLE_FRAME_MAX
> 
> In the next patch the new macros will be used.
> 
> Cc: Dhinakaran Pandiyan 
> Cc: Rodrigo Vivi 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/i915/i915_reg.h | 7 ---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index d3ef97915455..9e46da5032c0 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4216,10 +4216,11 @@ enum {
>  #define   EDP_PSR2_TP2_TIME_50us (3 << 8)
>  #define   EDP_PSR2_TP2_TIME_MASK (3 << 8)
>  #define   EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4
> -#define   EDP_PSR2_FRAME_BEFORE_SU_MASK  (0xf << 4)
_MASKs are useful when we want to read back the register for debugging.
So, I'm not fully convinced this is an improvement.

Rodrigo, your thoughts on this?


> -#define   EDP_PSR2_FRAME_BEFORE_SU(a)((a) << 4)
> -#define   EDP_PSR2_IDLE_FRAME_MASK   0xf
> +#define   EDP_PSR2_FRAME_BEFORE_SU_MAX   0xf
> +#define   EDP_PSR2_FRAME_BEFORE_SU(a)((a) <<
> EDP_PSR2_FRAME_BEFORE_SU_SHIFT)
>  #define   EDP_PSR2_IDLE_FRAME_SHIFT  0
> +#define   EDP_PSR2_IDLE_FRAME_MAX0xf
Not sure if this is better than re-using _MASK here. I'm sure there are
places in the driver where we already do that.

> +#define   EDP_PSR2_IDLE_FRAME(a) ((a) <<
> EDP_PSR2_IDLE_FRAME_SHIFT)
>  
>  #define _PSR_EVENT_TRANS_A   0x60848
>  #define _PSR_EVENT_TRANS_B   0x61848

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


Re: [PATCH v2 01/11] drm/i915: Disable PSR in Apple panels

2018-12-03 Thread Dhinakaran Pandiyan
On Mon, 2018-12-03 at 12:14 -0800, Souza, Jose wrote:
> On Fri, 2018-11-30 at 15:35 -0800, Dhinakaran Pandiyan wrote:
> > On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> > > i915 yet don't support PSR in Apple panels, so lets keep it
> > > disabled
> > > while we work on that.
> > > 
> > > v2: Renamed DP_DPCD_QUIRK_PSR_NOT_CURRENTLY_SUPPORTED to
> > > DP_DPCD_QUIRK_NO_PSR (Ville)
> > > 
> > > Fixes: 598c6cfe0690 (drm/i915/psr: Enable PSR1 on gen-9+ HW)
> > > Cc: Ville Syrjälä 
> > > Cc: Rodrigo Vivi 
> > > Cc: Dhinakaran Pandiyan 
> > > Signed-off-by: José Roberto de Souza 
> > > ---
> > >  drivers/gpu/drm/drm_dp_helper.c  | 2 ++
> > >  drivers/gpu/drm/i915/intel_psr.c | 6 ++
> > >  include/drm/drm_dp_helper.h  | 1 +
> > >  3 files changed, 9 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_dp_helper.c
> > > b/drivers/gpu/drm/drm_dp_helper.c
> > > index 2d6c491a0542..b00fd5ced0a0 100644
> > > --- a/drivers/gpu/drm/drm_dp_helper.c
> > > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > > @@ -1273,6 +1273,8 @@ static const struct dpcd_quirk
> > > dpcd_quirk_list[] = {
> > >   { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true,
> > > BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> > >   /* LG LP140WF6-SPM1 eDP panel */
> > >   { OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r',
> > > 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> > > + /* Apple panels needs some additional handling to support PSR
> > > */
> > > + { OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false,
> > > BIT(DP_DPCD_QUIRK_NO_PSR) }
> > >  };
> > >  
> > >  #undef OUI
> > > diff --git a/drivers/gpu/drm/i915/intel_psr.c
> > > b/drivers/gpu/drm/i915/intel_psr.c
> > > index 2084784f320d..40ca6cc43cc4 100644
> > > --- a/drivers/gpu/drm/i915/intel_psr.c
> > > +++ b/drivers/gpu/drm/i915/intel_psr.c
> > > @@ -278,6 +278,12 @@ void intel_psr_init_dpcd(struct intel_dp
> > > *intel_dp)
> > >   DRM_DEBUG_KMS("Panel lacks power state control, PSR
> > > cannot be enabled\n");
> > >   return;
> > >   }
> > > +
> > > + if (drm_dp_has_quirk(_dp->desc, DP_DPCD_QUIRK_NO_PSR)) {
> > > + DRM_DEBUG_KMS("PSR support not currently available for
> > > this panel\n");
> > > + return;
> > > + }
> > > +
> > >   dev_priv->psr.sink_support = true;
> > >   dev_priv->psr.sink_sync_latency =
> > >   intel_dp_get_sink_sync_latency(intel_dp);
> > > diff --git a/include/drm/drm_dp_helper.h
> > > b/include/drm/drm_dp_helper.h
> > > index 5736c942c85b..047314ce25d6 100644
> > > --- a/include/drm/drm_dp_helper.h
> > > +++ b/include/drm/drm_dp_helper.h
> > > @@ -1365,6 +1365,7 @@ enum drm_dp_quirk {
> > >* to 16 bits. So will give a constant value (0x8000) for
> > > compatability.
> > >*/
> > >   DP_DPCD_QUIRK_CONSTANT_N,
> > 
> > nit: Documentation missing here. I guess we need something along
> > the
> > lines of "PSR not supported" without referring to the specific DP
> > device. With that,
> > Reviewed-by: Dhinakaran Pandiyan 
> 
> 
> Adding here:
> 
>   /**
>* @DP_DPCD_QUIRK_NO_PSR
>*
>* The device don't properly support PSR even if reports that
nit: "device does not support"
> it
>* supports or driver still need to implement proper handling
^needs
> for such
>* device.
>*/
> 
> > 
> > 
> > > + DP_DPCD_QUIRK_NO_PSR,
> > >  };
> > >  
> > >  /**

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


Re: [PATCH v2 08/11] drm/i915/psr: Check if source supports sink specific SU granularity

2018-12-03 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> According to eDP spec, sink can required specific selective update
> granularity that source must comply.
> Here caching the value if required and checking if source supports
> it.
> 
> Cc: Rodrigo Vivi 
> Cc: Dhinakaran Pandiyan 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/i915/i915_drv.h  |  1 +
>  drivers/gpu/drm/i915/intel_psr.c | 21 -
>  2 files changed, 21 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 43ac6873a2bb..0727d8051dd3 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -507,6 +507,7 @@ struct i915_psr {
>   ktime_t last_exit;
>   bool sink_not_reliable;
>   bool irq_aux_error;
> + u16 su_x_granularity;
>  };
>  
>  enum intel_pch {
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index 282ff1bc68a7..f9eccaac850a 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -261,6 +261,23 @@ static u8 intel_dp_get_sink_sync_latency(struct
> intel_dp *intel_dp)
>   return val;
>  }
>  
> +static u16 intel_dp_get_su_x_granulartiy(struct intel_dp *intel_dp)
> +{
> + u16 val;
> + ssize_t r;
> +
> + if (!(intel_dp->psr_dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED))
> {
> + /* Returning the default X granularity */
> + return 4;
> + }
nit: Braces not needed, you could move the comment a line above.

A value of 0 in this DPCD indicates there is no granularity
requirement, why assume 4? 

> +
> + r = drm_dp_dpcd_read(_dp->aux, DP_PSR2_SU_X_GRANULARITY,
> , 2);
> + if (r != 2)
> + DRM_WARN("Unable to read DP_PSR2_SU_X_GRANULARITY\n");
Please change this to the warning level that we use elsewhere for aux
failures.

If I'm reading the spec correctly, a value of 0 in this DPCD means the
sink expects a granularity of 4, so returning 0 would be incorrect.

> +
> + return val;
Assume the default value of 4 if aux read fails (after printing an
error)

> +}
> +
>  void intel_psr_init_dpcd(struct intel_dp *intel_dp)
>  {
>   struct drm_i915_private *dev_priv =
> @@ -315,6 +332,8 @@ void intel_psr_init_dpcd(struct intel_dp
> *intel_dp)
>   if (dev_priv->psr.sink_psr2_support) {
>   dev_priv->psr.colorimetry_support =
>   intel_dp_get_colorimetry_status(intel_d
> p);
> + dev_priv->psr.su_x_granularity =
> + intel_dp_get_su_x_granulartiy(intel_dp)
> ;
>   }
>   }
>  }
> @@ -546,7 +565,7 @@ static bool intel_psr2_config_valid(struct
> intel_dp *intel_dp,
>* at each 4 lines with height of 4 lines, what eDP states
>* that sink should support.
>*/
> - if (crtc_hdisplay % 4) {
> + if (crtc_hdisplay % dev_priv->psr.su_x_granularity) {
>   DRM_DEBUG_KMS("PSR2 not enabled, default SU granularity
> not match\n");
>   return false;
>   }

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


Re: [PATCH v2 01/11] drm/i915: Disable PSR in Apple panels

2018-12-03 Thread Dhinakaran Pandiyan
On Fri, 2018-11-30 at 15:35 -0800, Dhinakaran Pandiyan wrote:
> On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> > i915 yet don't support PSR in Apple panels, so lets keep it
> > disabled
> > while we work on that.
> > 
> > v2: Renamed DP_DPCD_QUIRK_PSR_NOT_CURRENTLY_SUPPORTED to
> > DP_DPCD_QUIRK_NO_PSR (Ville)
> > 
> > Fixes: 598c6cfe0690 (drm/i915/psr: Enable PSR1 on gen-9+ HW)
> > Cc: Ville Syrjälä 
> > Cc: Rodrigo Vivi 
> > Cc: Dhinakaran Pandiyan 
> > Signed-off-by: José Roberto de Souza 
> > ---
> >  drivers/gpu/drm/drm_dp_helper.c  | 2 ++
> >  drivers/gpu/drm/i915/intel_psr.c | 6 ++
> >  include/drm/drm_dp_helper.h  | 1 +
> >  3 files changed, 9 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_dp_helper.c
> > b/drivers/gpu/drm/drm_dp_helper.c
> > index 2d6c491a0542..b00fd5ced0a0 100644
> > --- a/drivers/gpu/drm/drm_dp_helper.c
> > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > @@ -1273,6 +1273,8 @@ static const struct dpcd_quirk
> > dpcd_quirk_list[] = {
> > { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true,
> > BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> > /* LG LP140WF6-SPM1 eDP panel */
> > { OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r',
> > 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> > +   /* Apple panels needs some additional handling to support PSR
> > */
> > +   { OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false,
> > BIT(DP_DPCD_QUIRK_NO_PSR) }
> >  };
> >  
> >  #undef OUI
> > diff --git a/drivers/gpu/drm/i915/intel_psr.c
> > b/drivers/gpu/drm/i915/intel_psr.c
> > index 2084784f320d..40ca6cc43cc4 100644
> > --- a/drivers/gpu/drm/i915/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/intel_psr.c
> > @@ -278,6 +278,12 @@ void intel_psr_init_dpcd(struct intel_dp
> > *intel_dp)
> > DRM_DEBUG_KMS("Panel lacks power state control, PSR
> > cannot be enabled\n");
> > return;
> > }
> > +
> > +   if (drm_dp_has_quirk(_dp->desc, DP_DPCD_QUIRK_NO_PSR)) {
> > +   DRM_DEBUG_KMS("PSR support not currently available for
> > this panel\n");
> > +   return;
> > +   }
Another nitpick: While you make other changes, please also move this
above the power state check. Checking for power state control is not
very useful if we are never going to enable PSR on this panel.

> > +
> > dev_priv->psr.sink_support = true;
> > dev_priv->psr.sink_sync_latency =
> > intel_dp_get_sink_sync_latency(intel_dp);
> > diff --git a/include/drm/drm_dp_helper.h
> > b/include/drm/drm_dp_helper.h
> > index 5736c942c85b..047314ce25d6 100644
> > --- a/include/drm/drm_dp_helper.h
> > +++ b/include/drm/drm_dp_helper.h
> > @@ -1365,6 +1365,7 @@ enum drm_dp_quirk {
> >  * to 16 bits. So will give a constant value (0x8000) for
> > compatability.
> >  */
> > DP_DPCD_QUIRK_CONSTANT_N,
> 
> nit: Documentation missing here. I guess we need something along the
> lines of "PSR not supported" without referring to the specific DP
> device. With that,
> Reviewed-by: Dhinakaran Pandiyan 
> 
> 
> > +   DP_DPCD_QUIRK_NO_PSR,
> >  };
> >  
> >  /**

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


Re: [PATCH v2 07/11] drm/i915/psr: Check if resolution is supported by default SU granularity

2018-11-30 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> Selective updates have a default granularity requirements as stated
> by eDP spec
Needs reference to the location in the spec.

> , so check if HW can match those requirements before
> enable PSR2.
typo: enabling*

> 
> Cc: Dhinakaran Pandiyan 
> Cc: Rodrigo Vivi 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/i915/intel_psr.c | 12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index c4a8f476eea9..282ff1bc68a7 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -539,6 +539,18 @@ static bool intel_psr2_config_valid(struct
> intel_dp *intel_dp,
>   return false;
>   }
>  
> + /* HW will always send full lines in SU blocks, so X will
s/X/starting X coordinate

> +  * always be 0 and we only need to check the width to validate
> +  * horizontal granularity.

> +  * About vertical granularity HW works by SU blocks starting
> +  * at each 4 lines with height of 4 lines, what eDP states
> +  * that sink should support.
How about rewriting this as -  
"HW sends SU blocks of size four scan lines, which means the starting X
coordinate and Y granularity requirements will always be met. We only
need to validate the SU block width is a multiple of 4."?




> +  */
> + if (crtc_hdisplay % 4) {
> + DRM_DEBUG_KMS("PSR2 not enabled, default SU granularity
> not match\n");
"PSR2 not enabled, hdisplay(%d) not multiple of 4\n"

With nits addressed,

Reviewed-by: Dhinakaran Pandiyan 

> + return false;
> + }
> +
>   return true;
>  }
>  

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


Re: [PATCH v2 06/11] drm: Add the PSR SU granularity registers offsets

2018-11-30 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> Source is required to comply to sink SU granularity when
> DP_PSR2_SU_GRANULARITY_REQUIRED is set in DP_PSR_CAPS,
> so adding the registers offsets.
> 
> v2: Also adding DP_PSR2_SU_Y_GRANULARITY(Rodrigo)
> 
> Cc: Dhinakaran Pandiyan 
> Cc: Rodrigo Vivi 
> Signed-off-by: José Roberto de Souza 
> ---
>  include/drm/drm_dp_helper.h | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/include/drm/drm_dp_helper.h
> b/include/drm/drm_dp_helper.h
> index 047314ce25d6..0e04b2db3dde 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -314,6 +314,10 @@
>  # define DP_PSR_SETUP_TIME_SHIFT1
>  # define DP_PSR2_SU_Y_COORDINATE_REQUIRED   (1 << 4)  /* eDP 1.4a */
>  # define DP_PSR2_SU_GRANULARITY_REQUIRED(1 << 5)  /* eDP 1.4b */
> +
> +#define DP_PSR2_SU_X_GRANULARITY 0x072 /* eDP 1.4b */
> +#define DP_PSR2_SU_Y_GRANULARITY 0x074 /* eDP 1.4b */
Definitions above use spaces instead of tabs, so it'd have been good to
be consistent. But, there are places in the file where tabs are used
too, so will leave it to you if you want to switch.

> +
Verified against eDP spec 1.4b
Reviewed-by: Dhinakaran Pandiyan 

>  /*
>   * 0x80-0x8f describe downstream port capabilities, but there are
> two layouts
>   * based on whether DP_DETAILED_CAP_INFO_AVAILABLE was set.  If it
> was not,

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


Re: [PATCH v2 04/11] drm/i915/psr: Enable sink to trigger a interruption on PSR2 CRC mismatch

2018-11-30 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> eDP spec states 2 different bits to enable sink to trigger a
> interruption when there is a CRC mismatch.
> DP_PSR_CRC_VERIFICATION is for PSR only and
> DP_PSR_IRQ_HPD_WITH_CRC_ERRORS is for PSR2 only.

With PSR short pulse handling implemented, I think we are ready for
this.

Reviewed-by: Dhinakaran Pandiyan 
> 
> Cc: Dhinakaran Pandiyan 
> Reviewed-by: Rodrigo Vivi 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/i915/intel_psr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index b04472e637c8..77162c469079 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -394,7 +394,7 @@ static void intel_psr_enable_sink(struct intel_dp
> *intel_dp)
>   if (dev_priv->psr.psr2_enabled) {
>   drm_dp_dpcd_writeb(_dp->aux,
> DP_RECEIVER_ALPM_CONFIG,
>  DP_ALPM_ENABLE);
> - dpcd_val |= DP_PSR_ENABLE_PSR2;
> + dpcd_val |= DP_PSR_ENABLE_PSR2 |
> DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
>   } else {
>   if (dev_priv->psr.link_standby)
>   dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;

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


Re: [PATCH v2 03/11] drm/i915/psr: Set PSR CRC verification bit in sink inside PSR1 block

2018-11-30 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> As we have a else block for the 'if (dev_priv->psr.psr2_enabled) {'
> and this bit is only set for PSR1 move it to that block to make it
> more easy to read.
> 
> Cc: Dhinakaran Pandiyan 
> Cc: Rodrigo Vivi 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/i915/intel_psr.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index 8515f4a6f4f1..b04472e637c8 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -398,10 +398,11 @@ static void intel_psr_enable_sink(struct
> intel_dp *intel_dp)
>   } else {
>   if (dev_priv->psr.link_standby)
>   dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
> +
> + if (INTEL_GEN(dev_priv) >= 8)
> + dpcd_val |= DP_PSR_CRC_VERIFICATION;
>   }
>  
> - if (!dev_priv->psr.psr2_enabled && INTEL_GEN(dev_priv) >= 8)
> - dpcd_val |= DP_PSR_CRC_VERIFICATION;
>   drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);
>  
>   drm_dp_dpcd_writeb(_dp->aux, DP_SET_POWER,
> DP_SET_POWER_D0);

Do we need this DPCD write? The panel should already be awake by this
point, I think it's worth removing it if there's no regression.

Your change in this patch looks good, so
Reviewed-by: Dhinakaran Pandiyan 




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


Re: [PATCH v2 02/11] drm/i915/psr: Don't tell sink that main link will be active while is active PSR2

2018-11-30 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> For PSR2 there is no register to tell HW to keep main link enabled
Right, there is no bit in PSR2_CTL
Reviewed-by: Dhinakaran Pandiyan 


> while PSR2 is active, so don't configure sink DPCD with a
> misleading value.
> 
> v2: Moving the set of DP_PSR_CRC_VERIFICATION to the else block
> of 'if (dev_priv->psr.psr2_enabled)' to another patch. (Rodrigo)
> 
> Cc: Dhinakaran Pandiyan 
> Cc: Rodrigo Vivi 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/i915/intel_psr.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index 40ca6cc43cc4..8515f4a6f4f1 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -395,10 +395,11 @@ static void intel_psr_enable_sink(struct
> intel_dp *intel_dp)
>   drm_dp_dpcd_writeb(_dp->aux,
> DP_RECEIVER_ALPM_CONFIG,
>  DP_ALPM_ENABLE);
>   dpcd_val |= DP_PSR_ENABLE_PSR2;
> + } else {
> + if (dev_priv->psr.link_standby)
> + dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
>   }
>  
> - if (dev_priv->psr.link_standby)
> - dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
>   if (!dev_priv->psr.psr2_enabled && INTEL_GEN(dev_priv) >= 8)
>   dpcd_val |= DP_PSR_CRC_VERIFICATION;
>   drm_dp_dpcd_writeb(_dp->aux, DP_PSR_EN_CFG, dpcd_val);

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


Re: [PATCH v2 01/11] drm/i915: Disable PSR in Apple panels

2018-11-30 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 18:25 -0800, José Roberto de Souza wrote:
> i915 yet don't support PSR in Apple panels, so lets keep it disabled
> while we work on that.
> 
> v2: Renamed DP_DPCD_QUIRK_PSR_NOT_CURRENTLY_SUPPORTED to
> DP_DPCD_QUIRK_NO_PSR (Ville)
> 
> Fixes: 598c6cfe0690 (drm/i915/psr: Enable PSR1 on gen-9+ HW)
> Cc: Ville Syrjälä 
> Cc: Rodrigo Vivi 
> Cc: Dhinakaran Pandiyan 
> Signed-off-by: José Roberto de Souza 
> ---
>  drivers/gpu/drm/drm_dp_helper.c  | 2 ++
>  drivers/gpu/drm/i915/intel_psr.c | 6 ++
>  include/drm/drm_dp_helper.h  | 1 +
>  3 files changed, 9 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c
> b/drivers/gpu/drm/drm_dp_helper.c
> index 2d6c491a0542..b00fd5ced0a0 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -1273,6 +1273,8 @@ static const struct dpcd_quirk
> dpcd_quirk_list[] = {
>   { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true,
> BIT(DP_DPCD_QUIRK_CONSTANT_N) },
>   /* LG LP140WF6-SPM1 eDP panel */
>   { OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r',
> 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> + /* Apple panels needs some additional handling to support PSR
> */
> + { OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false,
> BIT(DP_DPCD_QUIRK_NO_PSR) }
>  };
>  
>  #undef OUI
> diff --git a/drivers/gpu/drm/i915/intel_psr.c
> b/drivers/gpu/drm/i915/intel_psr.c
> index 2084784f320d..40ca6cc43cc4 100644
> --- a/drivers/gpu/drm/i915/intel_psr.c
> +++ b/drivers/gpu/drm/i915/intel_psr.c
> @@ -278,6 +278,12 @@ void intel_psr_init_dpcd(struct intel_dp
> *intel_dp)
>   DRM_DEBUG_KMS("Panel lacks power state control, PSR
> cannot be enabled\n");
>   return;
>   }
> +
> + if (drm_dp_has_quirk(_dp->desc, DP_DPCD_QUIRK_NO_PSR)) {
> + DRM_DEBUG_KMS("PSR support not currently available for
> this panel\n");
> + return;
> + }
> +
>   dev_priv->psr.sink_support = true;
>   dev_priv->psr.sink_sync_latency =
>   intel_dp_get_sink_sync_latency(intel_dp);
> diff --git a/include/drm/drm_dp_helper.h
> b/include/drm/drm_dp_helper.h
> index 5736c942c85b..047314ce25d6 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -1365,6 +1365,7 @@ enum drm_dp_quirk {
>* to 16 bits. So will give a constant value (0x8000) for
> compatability.
>    */
>   DP_DPCD_QUIRK_CONSTANT_N,

nit: Documentation missing here. I guess we need something along the
lines of "PSR not supported" without referring to the specific DP
device. With that,
Reviewed-by: Dhinakaran Pandiyan 


> + DP_DPCD_QUIRK_NO_PSR,
>  };
>  
>  /**

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


Re: [Intel-gfx] [PATCH 1/9] drm/i915: Disable PSR in Apple panels

2018-11-29 Thread Dhinakaran Pandiyan
On Tue, 2018-11-27 at 13:55 -0800, Souza, Jose wrote:
> On Tue, 2018-11-27 at 15:38 +0200, Ville Syrjälä wrote:
> > On Mon, Nov 26, 2018 at 04:37:02PM -0800, José Roberto de Souza
> > wrote:
> > > i915 yet don't support PSR in Apple panels, so lets keep
Replace "Apple" with specific model name?

> > > disabled
> > > while we work on that.
> > > 
> > > Fixes: 598c6cfe0690 (drm/i915/psr: Enable PSR1 on gen-9+ HW)
Bugzilla please. Also Cc the bug reporter?


> > > Cc: Rodrigo Vivi 
> > > Cc: Dhinakaran Pandiyan 
> > > Signed-off-by: José Roberto de Souza 
> > > ---
> > >  drivers/gpu/drm/drm_dp_helper.c  | 2 ++
> > >  drivers/gpu/drm/i915/intel_psr.c | 6 ++
> > >  include/drm/drm_dp_helper.h  | 1 +
> > >  3 files changed, 9 insertions(+)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_dp_helper.c
> > > b/drivers/gpu/drm/drm_dp_helper.c
> > > index 6d483487f2b4..6b5a19d3e347 100644
> > > --- a/drivers/gpu/drm/drm_dp_helper.c
> > > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > > @@ -1273,6 +1273,8 @@ static const struct dpcd_quirk
> > > dpcd_quirk_list[] = {
> > >   { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true,
> > > BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> > >   /* LG LP140WF6-SPM1 eDP panel */
> > >   { OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a', 'r',
> > > 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> > > + /* Apple panels needs some additional handling to support PSR
> > > */
> > > + { OUI(0x00, 0x10, 0xfa), DEVICE_ID_ANY, false,
> > > BIT(DP_DPCD_QUIRK_PSR_NOT_CURRENTLY_SUPPORTED) }
> > >  };
> > >  
> > >  #undef OUI
> > > diff --git a/drivers/gpu/drm/i915/intel_psr.c
> > > b/drivers/gpu/drm/i915/intel_psr.c
> > > index 572e626eadff..f5d27a02eb28 100644
> > > --- a/drivers/gpu/drm/i915/intel_psr.c
> > > +++ b/drivers/gpu/drm/i915/intel_psr.c
> > > @@ -274,6 +274,12 @@ void intel_psr_init_dpcd(struct intel_dp
> > > *intel_dp)
> > >   DRM_DEBUG_KMS("Panel lacks power state control, PSR
> > > cannot be enabled\n");
> > >   return;
> > >   }
> > > +
> > > + if (drm_dp_has_quirk(_dp->desc,
> > > DP_DPCD_QUIRK_PSR_NOT_CURRENTLY_SUPPORTED)) {
> > > + DRM_DEBUG_KMS("PSR support not currently available for
> > > this panel\n");
> > > + return;
> > > + }
> > > +
> > >   dev_priv->psr.sink_support = true;
> > >   dev_priv->psr.sink_sync_latency =
> > >   intel_dp_get_sink_sync_latency(intel_dp);
> > > diff --git a/include/drm/drm_dp_helper.h
> > > b/include/drm/drm_dp_helper.h
> > > index 3314e91f6eb3..db516c48cda3 100644
> > > --- a/include/drm/drm_dp_helper.h
> > > +++ b/include/drm/drm_dp_helper.h
> > > @@ -1364,6 +1364,7 @@ enum drm_dp_quirk {
> > >* to 16 bits. So will give a constant value (0x8000) for
> > > compatability.
> > >*/
> > >   DP_DPCD_QUIRK_CONSTANT_N,
> > > + DP_DPCD_QUIRK_PSR_NOT_CURRENTLY_SUPPORTED,
> > 
> > Why such a convoluted name? DP_DPCD_QUIRK_NO_PSR?
> 
> Okay changing to DP_DPCD_QUIRK_NO_PSR.
> 
> > 
> > >  };
> > >  
> > >  /**
> > > -- 
> > > 2.19.2
> > > 
> > > ___
> > > Intel-gfx mailing list
> > > intel-...@lists.freedesktop.org
> > > https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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


Re: [PATCH 3/9] drm/i915/psr: Enable sink to trigger a interruption on PSR2 CRC mismatch

2018-11-29 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 14:04 -0800, Rodrigo Vivi wrote:
> On Mon, Nov 26, 2018 at 04:37:04PM -0800, José Roberto de Souza
> wrote:
> > eDP spec states 2 different bits to enable sink to trigger a
> > interruption when there is a CRC mismatch.
> > DP_PSR_CRC_VERIFICATION is for PSR only and
> > DP_PSR_IRQ_HPD_WITH_CRC_ERRORS is for PSR2 only.
> > 
> > Cc: Dhinakaran Pandiyan 
> > Cc: Rodrigo Vivi 
> > Signed-off-by: José Roberto de Souza 
> > ---
> >  drivers/gpu/drm/i915/intel_psr.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_psr.c
> > b/drivers/gpu/drm/i915/intel_psr.c
> > index 888e348cc1b4..607c3ec41679 100644
> > --- a/drivers/gpu/drm/i915/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/intel_psr.c
> > @@ -390,7 +390,7 @@ static void intel_psr_enable_sink(struct
> > intel_dp *intel_dp)
> > if (dev_priv->psr.psr2_enabled) {
> > drm_dp_dpcd_writeb(_dp->aux,
> > DP_RECEIVER_ALPM_CONFIG,
> >DP_ALPM_ENABLE);
> > -   dpcd_val |= DP_PSR_ENABLE_PSR2;
> > +   dpcd_val |= DP_PSR_ENABLE_PSR2 |
> > DP_PSR_IRQ_HPD_WITH_CRC_ERRORS;
> 
> good catch!
> 
> 
> Reviewed-by: Rodrigo Vivi 

Is there a commit that this patch Fixes?

> 
> 
> 
> > } else {
> > if (dev_priv->psr.link_standby)
> > dpcd_val |= DP_PSR_MAIN_LINK_ACTIVE;
> > -- 
> > 2.19.2
> > 

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


Re: [PATCH 9/9] drm/i915: Remove old PSR2 FIXME about frontbuffer tracking

2018-11-29 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 15:11 -0800, Rodrigo Vivi wrote:
> On Mon, Nov 26, 2018 at 04:37:10PM -0800, José Roberto de Souza
> wrote:
> > Our frontbuffer tracking improved over the years + the WA #0884
> > helped us keep PSR2 enabled while triggering screen updates when
> > necessary so this FIXME is not valid anymore.
> > 
> > Cc: Dhinakaran Pandiyan 
> > Cc: Rodrigo Vivi 
> > Signed-off-by: José Roberto de Souza 
> 
> Reviewed-by: Rodrigo Vivi 
Acked-by: Dhinakaran Pandiyan 


> 
> > ---
> >  drivers/gpu/drm/i915/intel_psr.c | 3 ---
> >  1 file changed, 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_psr.c
> > b/drivers/gpu/drm/i915/intel_psr.c
> > index 6fd793fec5e9..a1bde8bbd85b 100644
> > --- a/drivers/gpu/drm/i915/intel_psr.c
> > +++ b/drivers/gpu/drm/i915/intel_psr.c
> > @@ -490,9 +490,6 @@ static void hsw_activate_psr2(struct intel_dp
> > *intel_dp)
> > /* Avoid deep sleep as much as possible to avoid PSR2 idle
> > state */
> > val |= EDP_PSR2_IDLE_FRAMES_TO_DEEP_SLEEP(15);
> >  
> > -   /* FIXME: selective update is probably totally broken because
> > it doesn't
> > -* mesh at all with our frontbuffer tracking. And the hw alone
> > isn't
> > -* good enough. */
> > val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
> > if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
> > val |= EDP_Y_COORDINATE_ENABLE;
> > -- 
> > 2.19.2
> > 

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


Re: [PATCH 7/9] drm/i915/psr: Rename PSR2 macros to better match meaning

2018-11-29 Thread Dhinakaran Pandiyan
On Thu, 2018-11-29 at 15:07 -0800, Rodrigo Vivi wrote:
> On Mon, Nov 26, 2018 at 04:37:08PM -0800, José Roberto de Souza
> wrote:
> > The first 8 bits of PSR2_CTL have 2 fields to set frames count, the
> > first one is to set how many idle frames PSR2 HW needs to wait
> > before
> > enter in deep sleep and the second one it is how many frames(it
> > don't
> > need to be idle frames) PSR2 HW will wait before start the PSR
> > activation sequence.
> > The previous names was really misleading and caused wrong values 
The idea was to setup a conservative configuration for PSR2 until we
were ready to enable the feature and some testing was done. Not sure
why you think the values are wrong.

> > being
> > set so better rename to make it clear.
> 
> I honestly prefer the old names for 2 reasons:
> 
> - they are shorter
> - they follow the exact name we have on spec
+1 for the above reason.

> 
> > 
> > Also taking the oportunity to improve those macros.
> > 
> > Cc: Rodrigo Vivi 
> > Cc: Dhinakaran Pandiyan 
> > Signed-off-by: José Roberto de Souza 
> > ---
> >  drivers/gpu/drm/i915/i915_reg.h  | 35 --
> > --
> >  drivers/gpu/drm/i915/intel_psr.c |  7 ---
> >  2 files changed, 22 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index 47baf2fe8f71..73046bb9ec7c 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -4203,23 +4203,24 @@ enum {
> >  #define   EDP_PSR_DEBUG_MASK_DISP_REG_WRITE(1 << 16) /*
> > Reserved in ICL+ */
> >  #define   EDP_PSR_DEBUG_EXIT_ON_PIXEL_UNDERRUN (1 << 15) /* SKL+
> > */
> >  
> > -#define EDP_PSR2_CTL   _MMIO(0x6f900)
> > -#define   EDP_PSR2_ENABLE  (1 << 31)
> > -#define   EDP_SU_TRACK_ENABLE  (1 << 30)
> > -#define   EDP_Y_COORDINATE_VALID   (1 << 26) /* GLK and CNL+ */
> > -#define   EDP_Y_COORDINATE_ENABLE  (1 << 25) /* GLK and CNL+ */
> > -#define   EDP_MAX_SU_DISABLE_TIME(t)   ((t) << 20)
> > -#define   EDP_MAX_SU_DISABLE_TIME_MASK (0x1f << 20)
> > -#define   EDP_PSR2_TP2_TIME_500us  (0 << 8)
> > -#define   EDP_PSR2_TP2_TIME_100us  (1 << 8)
> > -#define   EDP_PSR2_TP2_TIME_2500us (2 << 8)
> > -#define   EDP_PSR2_TP2_TIME_50us   (3 << 8)
> > -#define   EDP_PSR2_TP2_TIME_MASK   (3 << 8)
> > -#define   EDP_PSR2_FRAME_BEFORE_SU_SHIFT 4
> > -#define   EDP_PSR2_FRAME_BEFORE_SU_MASK(0xf << 4)
> > -#define   EDP_PSR2_FRAME_BEFORE_SU(a)  ((a) << 4)
> > -#define   EDP_PSR2_IDLE_FRAME_MASK 0xf
> > -#define   EDP_PSR2_IDLE_FRAME_SHIFT0
> > +#define EDP_PSR2_CTL   _MMIO(0
> > x6f900)
> > +#define   EDP_PSR2_ENABLE  (1 << 31)
> > +#define   EDP_SU_TRACK_ENABLE  (1 <<
> > 30)
> > +#define   EDP_Y_COORDINATE_VALID   (1 << 26) /*
> > GLK and CNL+ */
> > +#define   EDP_Y_COORDINATE_ENABLE  (1 << 25) /*
> > GLK and CNL+ */
> > +#define   EDP_MAX_SU_DISABLE_TIME(t)   ((t) <<
> > 20)
> > +#define   EDP_MAX_SU_DISABLE_TIME_MASK (0x1f
> > << 20)
> > +#define   EDP_PSR2_TP2_TIME_500us  (0 << 8)
> > +#define   EDP_PSR2_TP2_TIME_100us  (1 << 8)
> > +#define   EDP_PSR2_TP2_TIME_2500us (2 << 8)
> > +#define   EDP_PSR2_TP2_TIME_50us   (3 << 8)
> > +#define   EDP_PSR2_TP2_TIME_MASK   (3 << 8)
> > +#define   EDP_PSR2_FRAMES_BEFORE_ACTIVATE_SHIFT(4)
> > +#define   EDP_PSR2_FRAMES_BEFORE_ACTIVATE_MASK (0xf <<
> > EDP_PSR2_FRAMES_BEFORE_ACTIVATE_SHIFT)
> > +#define   EDP_PSR2_FRAMES_BEFORE_ACTIVATE(n)   (((n)
> > << EDP_PSR2_FRAMES_BEFORE_ACTIVATE_SHIFT) &
> > EDP_PSR2_FRAMES_BEFORE_ACTIVATE_MASK)
> > +#define   EDP_PSR2_IDLE_FRAMES_TO_DEEP_SLEEP_MASK  (0xf)
> > +#define   EDP_PSR2_IDLE_FRAMES_TO_DEEP_SLEEP_SHIFT (0)
> > +#define   EDP_PSR2_IDLE_FRAMES_TO_DEEP_SLEEP(n)(((n)
> > << EDP_PSR2_IDLE_FRAMES_TO_DEEP_SLEEP_SHIFT) &
> > EDP_PSR2_IDLE_FRAMES_TO_DEEP_SLEEP_MASK)
> >  
> >  #define _PSR_EVENT_TRANS_A 0x60848
> >  #define _PSR_EVENT_TRANS_B 0x61848
> > diff --git a/dri

Re: [PATCH] drm/framebuffer: Expose only modifiers that support at least a format

2018-11-06 Thread Dhinakaran Pandiyan
On Tue, 2018-11-06 at 22:21 +0200, Ville Syrjälä wrote:
> On Tue, Nov 06, 2018 at 11:54:45AM -0800, Dhinakaran Pandiyan wrote:
> > On Tue, 2018-11-06 at 16:13 +0200, Ville Syrjälä wrote:
> > > On Mon, Nov 05, 2018 at 06:44:34PM -0800, Dhinakaran Pandiyan
> > > wrote:
> > > > Allows drivers to pass a larger modifier array, thereby
> > > > avoiding
> > > > declarations of static modifier arrays that are only slight
> > > > different
> > > > for each plane.
> > > > 
> > > > Cc: dri-devel@lists.freedesktop.org
> > > > Cc: Ville Syrjälä 
> > > > Suggested-by: Ville Syrjälä 
> > > > Signed-off-by: Dhinakaran Pandiyan <
> > > > dhinakaran.pandi...@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/drm_plane.c | 35 +++
> > > > 
> > > > 
> > > >  1 file changed, 27 insertions(+), 8 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_plane.c
> > > > b/drivers/gpu/drm/drm_plane.c
> > > > index 1fa98bd12003..1546ffbf8e36 100644
> > > > --- a/drivers/gpu/drm/drm_plane.c
> > > > +++ b/drivers/gpu/drm/drm_plane.c
> > > > @@ -179,8 +179,8 @@ int drm_universal_plane_init(struct
> > > > drm_device
> > > > *dev, struct drm_plane *plane,
> > > >  const char *name, ...)
> > > >  {
> > > > struct drm_mode_config *config = >mode_config;
> > > > -   unsigned int format_modifier_count = 0;
> > > > -   int ret;
> > > > +   unsigned int format_modifier_count, in_modifier_count =
> > > > 0;
> > > > +   int ret, i;
> > > >  
> > > > /* plane index is used with 32bit bitmasks */
> > > > if (WARN_ON(config->num_total_plane >= 32))
> > > > @@ -216,22 +216,43 @@ int drm_universal_plane_init(struct
> > > > drm_device *dev, struct drm_plane *plane,
> > > >  
> > > > if (format_modifiers) {
> > > > const uint64_t *temp_modifiers =
> > > > format_modifiers;
> > > > +
> > > > while (*temp_modifiers++ !=
> > > > DRM_FORMAT_MOD_INVALID)
> > > > -   format_modifier_count++;
> > > > +   in_modifier_count++;
> > > > }
> > > >  
> > > > -   plane->modifier_count = format_modifier_count;
> > > > -   plane->modifiers = kmalloc_array(format_modifier_count,
> > > > +   plane->modifiers = kmalloc_array(in_modifier_count,
> > > >  sizeof(format_modifier
> > > > s[0]),
> > > >  GFP_KERNEL);
> > > >  
> > > > -   if (format_modifier_count && !plane->modifiers) {
> > > > +   if (in_modifier_count && !plane->modifiers) {
> > > > DRM_DEBUG_KMS("out of memory when allocating
> > > > plane\n");
> > > > kfree(plane->format_types);
> > > > drm_mode_object_unregister(dev, >base);
> > > > return -ENOMEM;
> > > > }
> > > >  
> > > > +   for (i = 0, format_modifier_count = 0; i <
> > > > in_modifier_count;
> > > > i++) {
> > > > +   int j;
> > > > +
> > > > +   for (j = 0; funcs->format_mod_supported && j <
> > > > format_count; j++)
> > > > +   if (funcs->format_mod_supported(plane,
> > > > formats[j],
> > > > +   format_
> > > > modifier
> > > > s[i]))
> > > > +   break;
> > > > +
> > > > +   if (j < format_count)
> > > > +   plane-
> > > > >modifiers[format_modifier_count++] =
> > > > +   format_modifiers[i];
> > > > +   }
> > > > +
> > > > +   if (format_modifier_count < in_modifier_count) {
> > > > +   size_t size;
> > > > +
> > > > +   size = format_modifier_count *
> > > > sizeof(format_modifiers[0]);
>

Re: [PATCH] drm/framebuffer: Expose only modifiers that support at least a format

2018-11-06 Thread Dhinakaran Pandiyan
On Tue, 2018-11-06 at 16:13 +0200, Ville Syrjälä wrote:
> On Mon, Nov 05, 2018 at 06:44:34PM -0800, Dhinakaran Pandiyan wrote:
> > Allows drivers to pass a larger modifier array, thereby avoiding
> > declarations of static modifier arrays that are only slight
> > different
> > for each plane.
> > 
> > Cc: dri-devel@lists.freedesktop.org
> > Cc: Ville Syrjälä 
> > Suggested-by: Ville Syrjälä 
> > Signed-off-by: Dhinakaran Pandiyan 
> > ---
> >  drivers/gpu/drm/drm_plane.c | 35 +++
> > 
> >  1 file changed, 27 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_plane.c
> > b/drivers/gpu/drm/drm_plane.c
> > index 1fa98bd12003..1546ffbf8e36 100644
> > --- a/drivers/gpu/drm/drm_plane.c
> > +++ b/drivers/gpu/drm/drm_plane.c
> > @@ -179,8 +179,8 @@ int drm_universal_plane_init(struct drm_device
> > *dev, struct drm_plane *plane,
> >  const char *name, ...)
> >  {
> > struct drm_mode_config *config = >mode_config;
> > -   unsigned int format_modifier_count = 0;
> > -   int ret;
> > +   unsigned int format_modifier_count, in_modifier_count = 0;
> > +   int ret, i;
> >  
> > /* plane index is used with 32bit bitmasks */
> > if (WARN_ON(config->num_total_plane >= 32))
> > @@ -216,22 +216,43 @@ int drm_universal_plane_init(struct
> > drm_device *dev, struct drm_plane *plane,
> >  
> > if (format_modifiers) {
> > const uint64_t *temp_modifiers = format_modifiers;
> > +
> > while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
> > -   format_modifier_count++;
> > +   in_modifier_count++;
> > }
> >  
> > -   plane->modifier_count = format_modifier_count;
> > -   plane->modifiers = kmalloc_array(format_modifier_count,
> > +   plane->modifiers = kmalloc_array(in_modifier_count,
> >  sizeof(format_modifiers[0]),
> >  GFP_KERNEL);
> >  
> > -   if (format_modifier_count && !plane->modifiers) {
> > +   if (in_modifier_count && !plane->modifiers) {
> > DRM_DEBUG_KMS("out of memory when allocating plane\n");
> > kfree(plane->format_types);
> > drm_mode_object_unregister(dev, >base);
> > return -ENOMEM;
> > }
> >  
> > +   for (i = 0, format_modifier_count = 0; i < in_modifier_count;
> > i++) {
> > +   int j;
> > +
> > +   for (j = 0; funcs->format_mod_supported && j <
> > format_count; j++)
> > +   if (funcs->format_mod_supported(plane,
> > formats[j],
> > +   format_modifier
> > s[i]))
> > +   break;
> > +
> > +   if (j < format_count)
> > +   plane->modifiers[format_modifier_count++] =
> > +   format_modifiers[i];
> > +   }
> > +
> > +   if (format_modifier_count < in_modifier_count) {
> > +   size_t size;
> > +
> > +   size = format_modifier_count *
> > sizeof(format_modifiers[0]);
> > +   plane->modifiers = krealloc(plane->modifiers, size,
> > GFP_KERNEL);
> 
> Should check that the realloc actually succeeded.
Didn't see a failure path for new size smaller than old, the return is
the same pointer passed to krealloc().

> 
> And I think we might want to give this same treatment to plane-
> >formats[]
> as well.
> 
> And perhaps we could even throw out plane->modifiers[] and just rely
> on
> the IN_FORMATS blob exclusively? Hmm. Looks like that is not getting
> fully
> populated unless the driver has provided .format_mod_supported(). Not
> sure why that is, and not sure what userspace is supposed to do with
> a
> partially filled blob like that. I'm thinking we shouldn't even
> attach
> the property to the plane in that case.

Shouldn't it copy the modifier array into the blob and mark all formats
as supported? drm_plane_check_pixel_format() seems to allow any valid
format for a modifier in this case.


-DK

> 
> > +   }
> > +   plane->modifier_count = format_modifier_count;
> > +
> > if (name) {
> > va_list ap;
> >  
> > @@ -251,8 +272,6 @@ int drm_universal_plane_init(struct drm_device
> > *dev, struct drm_plane *plane,
> >  
> > memcpy(plane->format_types, formats, format_count *
> > sizeof(uint32_t));
> > plane->format_count = format_count;
> > -   memcpy(plane->modifiers, format_modifiers,
> > -  format_modifier_count * sizeof(format_modifiers[0]));
> > plane->possible_crtcs = possible_crtcs;
> > plane->type = type;
> >  
> > -- 
> > 2.14.1
> 
> 

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


[PATCH] drm/framebuffer: Expose only modifiers that support at least a format

2018-11-05 Thread Dhinakaran Pandiyan
Allows drivers to pass a larger modifier array, thereby avoiding
declarations of static modifier arrays that are only slight different
for each plane.

Cc: dri-devel@lists.freedesktop.org
Cc: Ville Syrjälä 
Suggested-by: Ville Syrjälä 
Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/drm_plane.c | 35 +++
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 1fa98bd12003..1546ffbf8e36 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -179,8 +179,8 @@ int drm_universal_plane_init(struct drm_device *dev, struct 
drm_plane *plane,
 const char *name, ...)
 {
struct drm_mode_config *config = >mode_config;
-   unsigned int format_modifier_count = 0;
-   int ret;
+   unsigned int format_modifier_count, in_modifier_count = 0;
+   int ret, i;
 
/* plane index is used with 32bit bitmasks */
if (WARN_ON(config->num_total_plane >= 32))
@@ -216,22 +216,43 @@ int drm_universal_plane_init(struct drm_device *dev, 
struct drm_plane *plane,
 
if (format_modifiers) {
const uint64_t *temp_modifiers = format_modifiers;
+
while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)
-   format_modifier_count++;
+   in_modifier_count++;
}
 
-   plane->modifier_count = format_modifier_count;
-   plane->modifiers = kmalloc_array(format_modifier_count,
+   plane->modifiers = kmalloc_array(in_modifier_count,
 sizeof(format_modifiers[0]),
 GFP_KERNEL);
 
-   if (format_modifier_count && !plane->modifiers) {
+   if (in_modifier_count && !plane->modifiers) {
DRM_DEBUG_KMS("out of memory when allocating plane\n");
kfree(plane->format_types);
drm_mode_object_unregister(dev, >base);
return -ENOMEM;
}
 
+   for (i = 0, format_modifier_count = 0; i < in_modifier_count; i++) {
+   int j;
+
+   for (j = 0; funcs->format_mod_supported && j < format_count; 
j++)
+   if (funcs->format_mod_supported(plane, formats[j],
+   format_modifiers[i]))
+   break;
+
+   if (j < format_count)
+   plane->modifiers[format_modifier_count++] =
+   format_modifiers[i];
+   }
+
+   if (format_modifier_count < in_modifier_count) {
+   size_t size;
+
+   size = format_modifier_count * sizeof(format_modifiers[0]);
+   plane->modifiers = krealloc(plane->modifiers, size, GFP_KERNEL);
+   }
+   plane->modifier_count = format_modifier_count;
+
if (name) {
va_list ap;
 
@@ -251,8 +272,6 @@ int drm_universal_plane_init(struct drm_device *dev, struct 
drm_plane *plane,
 
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
plane->format_count = format_count;
-   memcpy(plane->modifiers, format_modifiers,
-  format_modifier_count * sizeof(format_modifiers[0]));
plane->possible_crtcs = possible_crtcs;
plane->type = type;
 
-- 
2.14.1

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


Re: [PATCH v4 2/2] drm/i915: Eliminate the horrendous format check code

2018-10-29 Thread Dhinakaran Pandiyan
On Mon, 2018-10-29 at 20:34 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Replace the messy framebuffer format/modifier validation code
> with a single call to drm_any_plane_has_format(). The code was
> extremely annoying to maintain as you had to have a lot of platform
> checks for different formats. The new code requires zero maintenance.
> 
> v2: Nuke the modifier checks as well since the core does that too now
> v3: Call drm_any_plane_has_format() from the driver code
> v4: Rebase
> 
> Cc: Dhinakaran Pandiyan 
Reviewed-by: Dhinakaran Pandiyan 


-DK
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 105 ++---
> --
>  1 file changed, 8 insertions(+), 97 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 9b549d3dd055..de38d5545f3b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -14368,7 +14368,6 @@ static int intel_framebuffer_init(struct
> intel_framebuffer *intel_fb,
>  {
>   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
>   struct drm_framebuffer *fb = _fb->base;
> - struct drm_format_name_buf format_name;
>   u32 pitch_limit;
>   unsigned int tiling, stride;
>   int ret = -EINVAL;
> @@ -14399,39 +14398,14 @@ static int intel_framebuffer_init(struct
> intel_framebuffer *intel_fb,
>   }
>   }
>  
> - /* Passed in modifier sanity checking. */
> - switch (mode_cmd->modifier[0]) {
> - case I915_FORMAT_MOD_Y_TILED_CCS:
> - case I915_FORMAT_MOD_Yf_TILED_CCS:
> - switch (mode_cmd->pixel_format) {
> - case DRM_FORMAT_XBGR:
> - case DRM_FORMAT_ABGR:
> - case DRM_FORMAT_XRGB:
> - case DRM_FORMAT_ARGB:
> - break;
> - default:
> - DRM_DEBUG_KMS("RC supported only with RGB
> formats\n");
> - goto err;
> - }
> - /* fall through */
> - case I915_FORMAT_MOD_Yf_TILED:
> - if (mode_cmd->pixel_format == DRM_FORMAT_C8) {
> - DRM_DEBUG_KMS("Indexed format does not support
> Yf tiling\n");
> - goto err;
> - }
> - /* fall through */
> - case I915_FORMAT_MOD_Y_TILED:
> - if (INTEL_GEN(dev_priv) < 9) {
> - DRM_DEBUG_KMS("Unsupported tiling 0x%llx!\n",
> -   mode_cmd->modifier[0]);
> - goto err;
> - }
> - break;
> - case DRM_FORMAT_MOD_LINEAR:
> - case I915_FORMAT_MOD_X_TILED:
> - break;
> - default:
> - DRM_DEBUG_KMS("Unsupported fb modifier 0x%llx!\n",
> + if (!drm_any_plane_has_format(_priv->drm,
> +   mode_cmd->pixel_format,
> +   mode_cmd->modifier[0])) {
> + struct drm_format_name_buf format_name;
> +
> + DRM_DEBUG_KMS("unsupported pixel format %s / modifier
> 0x%llx\n",
> +   drm_get_format_name(mode_cmd-
> >pixel_format,
> +   _name),
> mode_cmd->modifier[0]);
>   goto err;
>   }
> @@ -14466,69 +14440,6 @@ static int intel_framebuffer_init(struct
> intel_framebuffer *intel_fb,
>   goto err;
>   }
>  
> - /* Reject formats not supported by any plane early. */
> - switch (mode_cmd->pixel_format) {
> - case DRM_FORMAT_C8:
> - case DRM_FORMAT_RGB565:
> - case DRM_FORMAT_XRGB:
> - case DRM_FORMAT_ARGB:
> - break;
> - case DRM_FORMAT_XRGB1555:
> - if (INTEL_GEN(dev_priv) > 3) {
> - DRM_DEBUG_KMS("unsupported pixel format: %s\n",
> -   drm_get_format_name(mode_cmd-
> >pixel_format, _name));
> - goto err;
> - }
> - break;
> - case DRM_FORMAT_ABGR:
> - if (!IS_VALLEYVIEW(dev_priv) &&
> !IS_CHERRYVIEW(dev_priv) &&
> - INTEL_GEN(dev_priv) < 9) {
> - DRM_DEBUG_KMS("unsupported pixel format: %s\n",
> -   drm_get_format_name(mode_cmd-
> >pixel_format, _name));
> - goto err;
> - }
> - break;
> - case DRM_FORM

Re: [Intel-gfx] [PATCH v3 2/4] drm/i915: Eliminate the horrendous format check code

2018-10-26 Thread Dhinakaran Pandiyan
On Fri, 2018-03-09 at 17:14 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Replace the messy framebuffer format/modifier validation code
> with a single call to drm_any_plane_has_format(). The code was
> extremely annoying to maintain as you had to have a lot of platform
> checks for different formats. The new code requires zero maintenance.
> 
> v2: Nuke the modifier checks as well since the core does that too now
> v3: Call drm_any_plane_has_format() from the driver code
> 
> Signed-off-by: Ville Syrjälä 

Patch looks good to me, but does not apply cleanly now.


> ---
>  drivers/gpu/drm/i915/intel_display.c | 90 
> 
>  1 file changed, 8 insertions(+), 82 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 2933ad38094f..7f06fa83d894 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13989,7 +13989,6 @@ static int intel_framebuffer_init(struct
> intel_framebuffer *intel_fb,
>  {
>   struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
>   struct drm_framebuffer *fb = _fb->base;
> - struct drm_format_name_buf format_name;
>   u32 pitch_limit;
>   unsigned int tiling, stride;
>   int ret = -EINVAL;
> @@ -14020,33 +14019,14 @@ static int intel_framebuffer_init(struct
> intel_framebuffer *intel_fb,
>   }
>   }
>  
> - /* Passed in modifier sanity checking. */
> - switch (mode_cmd->modifier[0]) {
> - case I915_FORMAT_MOD_Y_TILED_CCS:
> - case I915_FORMAT_MOD_Yf_TILED_CCS:
> - switch (mode_cmd->pixel_format) {
> - case DRM_FORMAT_XBGR:
> - case DRM_FORMAT_ABGR:
> - case DRM_FORMAT_XRGB:
> - case DRM_FORMAT_ARGB:
> - break;
> - default:
> - DRM_DEBUG_KMS("RC supported only with RGB
> formats\n");
> - goto err;
> - }
> - /* fall through */
> - case I915_FORMAT_MOD_Y_TILED:
> - case I915_FORMAT_MOD_Yf_TILED:
> - if (INTEL_GEN(dev_priv) < 9) {
> - DRM_DEBUG_KMS("Unsupported tiling 0x%llx!\n",
> -   mode_cmd->modifier[0]);
> - goto err;
> - }
> - case DRM_FORMAT_MOD_LINEAR:
> - case I915_FORMAT_MOD_X_TILED:
> - break;
> - default:
> - DRM_DEBUG_KMS("Unsupported fb modifier 0x%llx!\n",
> + if (!drm_any_plane_has_format(_priv->drm,
> +   mode_cmd->pixel_format,
> +   mode_cmd->modifier[0])) {
> + struct drm_format_name_buf format_name;
> +
> + DRM_DEBUG_KMS("unsupported pixel format %s / modifier
> 0x%llx\n",
> +   drm_get_format_name(mode_cmd-
> >pixel_format,
> +   _name),
> mode_cmd->modifier[0]);
>   goto err;
>   }
> @@ -14081,60 +14061,6 @@ static int intel_framebuffer_init(struct
> intel_framebuffer *intel_fb,
>   goto err;
>   }
>  
> - /* Reject formats not supported by any plane early. */
> - switch (mode_cmd->pixel_format) {
> - case DRM_FORMAT_C8:
> - case DRM_FORMAT_RGB565:
> - case DRM_FORMAT_XRGB:
> - case DRM_FORMAT_ARGB:
> - break;
> - case DRM_FORMAT_XRGB1555:
> - if (INTEL_GEN(dev_priv) > 3) {
> - DRM_DEBUG_KMS("unsupported pixel format: %s\n",
> -   drm_get_format_name(mode_cmd-
> >pixel_format, _name));
> - goto err;
> - }
> - break;
> - case DRM_FORMAT_ABGR:
> - if (!IS_VALLEYVIEW(dev_priv) &&
> !IS_CHERRYVIEW(dev_priv) &&
> - INTEL_GEN(dev_priv) < 9) {
> - DRM_DEBUG_KMS("unsupported pixel format: %s\n",
> -   drm_get_format_name(mode_cmd-
> >pixel_format, _name));
> - goto err;
> - }
> - break;
> - case DRM_FORMAT_XBGR:
> - case DRM_FORMAT_XRGB2101010:
> - case DRM_FORMAT_XBGR2101010:
> - if (INTEL_GEN(dev_priv) < 4) {
> - DRM_DEBUG_KMS("unsupported pixel format: %s\n",
> -   drm_get_format_name(mode_cmd-
> >pixel_format, _name));
> - goto err;
> - }
> - break;
> - case DRM_FORMAT_ABGR2101010:
> - if (!IS_VALLEYVIEW(dev_priv) &&
> !IS_CHERRYVIEW(dev_priv)) {
> - DRM_DEBUG_KMS("unsupported pixel format: %s\n",
> -   drm_get_format_name(mode_cmd-
> >pixel_format, _name));
> - goto err;
> - }
> - break;
> - case DRM_FORMAT_YUYV:
> -  

Re: [Intel-gfx] [PATCH v3 1/4] drm: Add drm_any_plane_has_format()

2018-10-26 Thread Dhinakaran Pandiyan
On Fri, 2018-03-09 at 17:14 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Add a function to check whether there is at least one plane that
> supports a specific format and modifier combination. Drivers can
> use this to reject unsupported formats/modifiers in .fb_create().
> 
> v2: Accept anyformat if the driver doesn't do planes (Eric)
> s/planes_have_format/any_plane_has_format/ (Eric)
> Check the modifier as well since we already have a function
> that does both
> v3: Don't do the check in the core since we may not know the
> modifier yet, instead export the function and let drivers
> call it themselves
> 
> Cc: Eric Anholt 
> Signed-off-by: Ville Syrjälä 

I ended up writing a similar patch for i915. Having this in the core
seems better and patch still applies cleanly.

Reviewed-by: Dhinakaran Pandiyan 

> ---
>  drivers/gpu/drm/drm_plane.c   | 23 +++
>  include/drm/drm_mode_config.h |  6 ++
>  include/drm/drm_plane.h   |  2 ++
>  3 files changed, 31 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_plane.c
> b/drivers/gpu/drm/drm_plane.c
> index a5d1fc7e8a37..3b2d6f8d889d 100644
> --- a/drivers/gpu/drm/drm_plane.c
> +++ b/drivers/gpu/drm/drm_plane.c
> @@ -578,6 +578,29 @@ int drm_plane_check_pixel_format(struct
> drm_plane *plane,
>   return 0;
>  }
>  
> +/**
> + * drm_any_plane_has_format - Check whether any plane supports this
> format and modifier combination
> + * @dev: DRM device
> + * @format: pixel format (DRM_FORMAT_*)
> + * @modifier: data layout modifier
> + *
> + * Returns:
> + * Whether at least one plane supports the specified format and
> modifier combination.
> + */
> +bool drm_any_plane_has_format(struct drm_device *dev,
> +   u32 format, u64 modifier)
> +{
> + struct drm_plane *plane;
> +
> + drm_for_each_plane(plane, dev) {
> + if (drm_plane_check_pixel_format(plane, format,
> modifier) == 0)
> + return true;
> + }
> +
> + return false;
> +}
> +EXPORT_SYMBOL(drm_any_plane_has_format);
> +
>  /*
>   * __setplane_internal - setplane handler for internal callers
>   *
> diff --git a/include/drm/drm_mode_config.h
> b/include/drm/drm_mode_config.h
> index 7569f22ffef6..9b894de9a75d 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -52,6 +52,12 @@ struct drm_mode_config_funcs {
>* requested metadata, but most of that is left to the driver.
> See
>*  drm_mode_fb_cmd2 for details.
>*
> +  * To validate the pixel format and modifier drivers can use
> +  * drm_any_plane_has_format() to make sure at least one plane
> supports
> +  * the requested values. Note that the driver must first
> determine the
> +  * actual modifier used if the request doesn't have it
> specified,
> +  * ie. when (@mode_cmd->flags & DRM_MODE_FB_MODIFIERS) == 0.
> +  *
>* If the parameters are deemed valid and the backing storage
> objects in
>* the underlying memory manager all exist, then the driver
> allocates
>* a new _framebuffer structure, subclassed to contain
> diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
> index f7bf4a48b1c3..930e8fdd90f8 100644
> --- a/include/drm/drm_plane.h
> +++ b/include/drm/drm_plane.h
> @@ -683,5 +683,7 @@ static inline struct drm_plane
> *drm_plane_find(struct drm_device *dev,
>  #define drm_for_each_plane(plane, dev) \
>   list_for_each_entry(plane, &(dev)->mode_config.plane_list,
> head)
>  
> +bool drm_any_plane_has_format(struct drm_device *dev,
> +   u32 format, u64 modifier);
>  
>  #endif

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


[PATCH 1/2] drm/plane: Export drm_plane_check_pixel_format()

2018-10-25 Thread Dhinakaran Pandiyan
i915 will make use of this to fail early during framebuffer creation.

Suggested-by: Ville Syrjälä 
Cc: dri-devel@lists.freedesktop.org
Cc: Ville Syrjälä 
Signed-off-by: Dhinakaran Pandiyan 
---
 drivers/gpu/drm/drm_plane.c |  1 +
 include/drm/drm_plane.h | 11 +++
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 1fa98bd12003..e834788619d1 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -589,6 +589,7 @@ int drm_plane_check_pixel_format(struct drm_plane *plane,
 
return 0;
 }
+EXPORT_SYMBOL(drm_plane_check_pixel_format);
 
 static int __setplane_check(struct drm_plane *plane,
struct drm_crtc *crtc,
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 0a0834bef8bd..8637b5239eb3 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -763,6 +763,17 @@ static inline struct drm_plane *drm_plane_find(struct 
drm_device *dev,
return mo ? obj_to_plane(mo) : NULL;
 }
 
+/**
+ * drm_plane_check_pixel_format - check format and modifier support.
+ * @plane: plane to check support against.
+ * @format: pixel format to check support for.
+ * @modifier: format modifier to check support for.
+ *
+ * Returns 0 on success or negative error code on failure.
+ */
+int drm_plane_check_pixel_format(struct drm_plane *plane,
+u32 format, u64 modifier);
+
 /**
  * drm_for_each_plane_mask - iterate over planes specified by bitmask
  * @plane: the loop cursor
-- 
2.14.1

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


Re: [PATCH 3/3] drm: add LG eDP panel to quirk database

2018-09-11 Thread Dhinakaran Pandiyan
On Mon, 2018-09-10 at 14:43 +0300, Jani Nikula wrote:
> On Mon, 10 Sep 2018, "Lee, Shawn C"  wrote:
> > The N value was computed by kernel driver that based on synchronous
> > clock
> > mode. But only specific N value (0x8000) would be acceptable for
> > LG LP140WF6-SPM1 eDP panel which is running at asynchronous clock
> > mode.
> > With the other N value, Tcon will enter BITS mode and display black
> > screen.
> > Add this panel into quirk database and give particular N value when
> > calculate M/N divider.
> > 
> > Cc: Jani Nikula 
> > Cc: Cooper Chiou 
> > Cc: Matt Atwood 
> > Cc: Maarten Lankhorst 
> > Cc: Dhinakaran Pandiyan 
> > Cc: Clint Taylor 
> > Signed-off-by: Lee, Shawn C 
> 
> No access to the panel or its details, so instead of review,
> 
> Acked-by: Jani Nikula 
> 
> > ---
> >  drivers/gpu/drm/drm_dp_helper.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_dp_helper.c
> > b/drivers/gpu/drm/drm_dp_helper.c
> > index d0c1250975ab..0ef7c43a9025 100644
> > --- a/drivers/gpu/drm/drm_dp_helper.c
> > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > @@ -1270,6 +1270,8 @@ struct dpcd_quirk {
> >  static const struct dpcd_quirk dpcd_quirk_list[] = {
> > /* Analogix 7737 needs reduced M and N at HBR2 link rates
> > */
> > { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true, 

Wonder if DEVICE_ID_ANY still the accurate criteria for these dongles
now that we can check against device IDs. I guess, since the quirk
fixes multiple dongles we probably can't check against a single device
ID.


> > BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> > +   /* LG LP140WF6-SPM1 eDP panel */

If you are resending the patches, it might be worth updating the
comment to
/* LG LP140WF6-SPM1 eDP panel needs N value of 0x8000 */

> > +   { OUI(0x00, 0x22, 0xb9), DEVICE_ID('s', 'i', 'v', 'a',
> > 'r', 'T'), false, BIT(DP_DPCD_QUIRK_CONSTANT_N) },
> >  };
> >  
> >  #undef OUI
> 
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 1/3] drm: Add support for device_id based detection.

2018-09-11 Thread Dhinakaran Pandiyan
On Mon, 2018-09-10 at 08:26 -0700, Lee, Shawn C wrote:
> DP quirk list just compare sink or branch device's OUI so far.
> That means particular vendor's products will be applied specific
> change. This change would confirm device_id the same or not.
> Then driver can implement some changes for branch/sink device
> that really need additional WA.
> 
> Cc: Jani Nikula 
> Cc: Cooper Chiou 
> Cc: Matt Atwood 
> Cc: Maarten Lankhorst 
> Cc: Dhinakaran Pandiyan 
> Cc: Clint Taylor 
> Signed-off-by: Lee, Shawn C 
> ---
>  drivers/gpu/drm/drm_dp_helper.c | 15 ++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_dp_helper.c
> b/drivers/gpu/drm/drm_dp_helper.c
> index 0cccbcb2d03e..0362c645d96e 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -1256,15 +1256,20 @@ EXPORT_SYMBOL(drm_dp_stop_crc);
>  
>  struct dpcd_quirk {
>   u8 oui[3];
> + u8 device_id[6];
>   bool is_branch;

With device id included, do we still need is_branch? 

>   u32 quirks;
>  };
>  
>  #define OUI(first, second, third) { (first), (second), (third) }
> +#define DEVICE_ID(first, second, third, fourth, fifth, sixth) \
> + { (first), (second), (third), (fourth), (fifth), (sixth) }
> +
> +#define DEVICE_ID_ANYDEVICE_ID(0, 0, 0, 0, 0, 0)
>  
>  static const struct dpcd_quirk dpcd_quirk_list[] = {
>   /* Analogix 7737 needs reduced M and N at HBR2 link rates */
> - { OUI(0x00, 0x22, 0xb9), true,
> BIT(DP_DPCD_QUIRK_LIMITED_M_N) },
> + { OUI(0x00, 0x22, 0xb9), DEVICE_ID_ANY, true,
> BIT(DP_DPCD_QUIRK_LIMITED_M_N) },
>  };
>  
>  #undef OUI
> @@ -1283,6 +1288,7 @@ drm_dp_get_quirks(const struct
> drm_dp_dpcd_ident *ident, bool is_branch)
>   const struct dpcd_quirk *quirk;
>   u32 quirks = 0;
>   int i;
> + u8 any_device[] = DEVICE_ID_ANY;
>  
>   for (i = 0; i < ARRAY_SIZE(dpcd_quirk_list); i++) {
>   quirk = _quirk_list[i];
> @@ -1293,12 +1299,19 @@ drm_dp_get_quirks(const struct
> drm_dp_dpcd_ident *ident, bool is_branch)

Update documentation that currently says -  
 "* For now, only the OUI (first three bytes) is used, but this may be
extended
 * to device identification string ..."

>   if (memcmp(quirk->oui, ident->oui, sizeof(ident-
> >oui)) != 0)
>   continue;
>  
> + if (memcmp(quirk->device_id, any_device,
> sizeof(any_device)) != 0 &&
> + memcmp(quirk->device_id, ident->device_id,
> sizeof(ident->device_id)) != 0)
> + continue;
> +
>   quirks |= quirk->quirks;
>   }
>  
>   return quirks;
>  }
>  
> +#undef DEVICE_ID_ANY
> +#undef DEVICE_ID
> +
>  /**
>   * drm_dp_read_desc - read sink/branch descriptor from DPCD
>   * @aux: DisplayPort AUX channel
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH v7 2/2] drm/i915: Adding YUV444 packed format(DRM_FORMAT_XYUV) support.

2018-08-30 Thread Dhinakaran Pandiyan
On Thu, 2018-08-30 at 13:57 +0100, Lisovskiy, Stanislav wrote:
> On Wed, 2018-08-29 at 12:16 -0700, Dhinakaran Pandiyan wrote:
> > 
> > On Wed, 2018-08-29 at 21:10 +0300, Ville Syrjälä wrote:
> > > On Wed, Aug 29, 2018 at 02:28:47PM +0300, Stanislav Lisovskiy
> > > wrote:
> > > > PLANE_CTL_FORMAT_AYUV is already supported, according to
> > > > hardware
> > > > specification.
> > > > 
> > > > v2: Edited commit message, removed redundant whitespaces.
> > > > 
> > > > v3: Fixed fallthrough logic for the format switch cases.
> > > > 
> > > > v4: Yet again fixed fallthrough logic, to reuse code from other
> > > > case
> > > > labels.
> > > > 
> > > > v5: Started to use XYUV instead of AYUV, as we don't use alpha.
Curious what the reason is. Is it because the hardware does not support
alpha with this format?

> > > > 
> > > > v6: Removed unneeded initializer for new XYUV format.
> > > > 
> > > > v7: Added scaling support for DRM_FORMAT_XYUV
> > 
> > I don't see yuv formats in skl_format_to_fourcc(), any idea why?
> 
> Good point. I guess would be nice idea to add at least XYUV there
> now.
> I can add rest of the formats with a separate patch afterwards.
Wonder if the expectation is BIOS not use yuv formats. Ville?

> 
> > 
> > Also, shouldn't plane_color_ctl_alpha() be updated?
> 
> I guess not, as we don't support alpha in that case.

Right, the default case should take care of setting
PLANE_CTL_ALPHA_DISABLE. I misread it.

> 
> > 
> > > > 
> > > > Signed-off-by: Stanislav Lisovskiy  > > > om
> > > > > 
> > > > 
> > > > ---
> > > >  drivers/gpu/drm/i915/intel_display.c | 8 
> > > >  drivers/gpu/drm/i915/intel_sprite.c  | 1 +
> > > >  2 files changed, 9 insertions(+)
> > > > 
> > > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > > b/drivers/gpu/drm/i915/intel_display.c
> > > > index 30fdfd1a3037..3c96fa3a2b61 100644
> > > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > > @@ -86,6 +86,7 @@ static const uint32_t skl_primary_formats[] =
> > > > {
> > > > DRM_FORMAT_YVYU,
> > > > DRM_FORMAT_UYVY,
> > > > DRM_FORMAT_VYUY,
> > > > +   DRM_FORMAT_XYUV,
> > > >  };
> > > >  
> > > >  static const uint32_t skl_pri_planar_formats[] = {
> > > > @@ -102,6 +103,7 @@ static const uint32_t
> > > > skl_pri_planar_formats[]
> > > > = {
> > > > DRM_FORMAT_UYVY,
> > > > DRM_FORMAT_VYUY,
> > > > DRM_FORMAT_NV12,
> > > > +   DRM_FORMAT_XYUV,
> > > 
> > > I would keep the NV12 at the end so that the arrays are easier to
> > > compare visually.
> > > 
> > > >  };
> > > >  
> > > >  static const uint64_t skl_format_modifiers_noccs[] = {
> > > > @@ -3501,6 +3503,8 @@ static u32 skl_plane_ctl_format(uint32_t
> > > > pixel_format)
> > > > return PLANE_CTL_FORMAT_XRGB_2101010;
> > > > case DRM_FORMAT_XBGR2101010:
> > > > return PLANE_CTL_ORDER_RGBX |
> > > > PLANE_CTL_FORMAT_XRGB_2101010;
> > > > +   case DRM_FORMAT_XYUV:
> > > > +   return PLANE_CTL_FORMAT_AYUV;
> > > 
> > > We should probably rename that define to XYUV as well since it
> > > doesn't
> > > support per-pixel alpha.
> > > 
> > > Since you've only implemented this for skl+ you chould mention
> > > that
> > > in the commit msg. IVB+ support should be equally trivial to
> > > implement (wink wink).
> > > 
> > > > case DRM_FORMAT_YUYV:
> > > > return PLANE_CTL_FORMAT_YUV422 |
> > > > PLANE_CTL_YUV422_YUYV;
> > > > case DRM_FORMAT_YVYU:
> > > > @@ -4959,6 +4963,7 @@ static int skl_update_scaler_plane(struct
> > > > intel_crtc_state *crtc_state,
> > > > case DRM_FORMAT_UYVY:
> > > > case DRM_FORMAT_VYUY:
> > > > case DRM_FORMAT_NV12:
> > > > +   case DRM_FORMAT_XYUV:
> > > > break;
> > > > default:
> > > > DRM_DEBUG_KMS(&

Re: [Intel-gfx] [PATCH v7 2/2] drm/i915: Adding YUV444 packed format(DRM_FORMAT_XYUV) support.

2018-08-29 Thread Dhinakaran Pandiyan


On Wed, 2018-08-29 at 21:10 +0300, Ville Syrjälä wrote:
> On Wed, Aug 29, 2018 at 02:28:47PM +0300, Stanislav Lisovskiy wrote:
> > PLANE_CTL_FORMAT_AYUV is already supported, according to hardware
> > specification.
> > 
> > v2: Edited commit message, removed redundant whitespaces.
> > 
> > v3: Fixed fallthrough logic for the format switch cases.
> > 
> > v4: Yet again fixed fallthrough logic, to reuse code from other
> > case
> > labels.
> > 
> > v5: Started to use XYUV instead of AYUV, as we don't use alpha.
> > 
> > v6: Removed unneeded initializer for new XYUV format.
> > 
> > v7: Added scaling support for DRM_FORMAT_XYUV

I don't see yuv formats in skl_format_to_fourcc(), any idea why?

Also, shouldn't plane_color_ctl_alpha() be updated?

> > 
> > Signed-off-by: Stanislav Lisovskiy 
> > ---
> >  drivers/gpu/drm/i915/intel_display.c | 8 
> >  drivers/gpu/drm/i915/intel_sprite.c  | 1 +
> >  2 files changed, 9 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 30fdfd1a3037..3c96fa3a2b61 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -86,6 +86,7 @@ static const uint32_t skl_primary_formats[] = {
> > DRM_FORMAT_YVYU,
> > DRM_FORMAT_UYVY,
> > DRM_FORMAT_VYUY,
> > +   DRM_FORMAT_XYUV,
> >  };
> >  
> >  static const uint32_t skl_pri_planar_formats[] = {
> > @@ -102,6 +103,7 @@ static const uint32_t skl_pri_planar_formats[]
> > = {
> > DRM_FORMAT_UYVY,
> > DRM_FORMAT_VYUY,
> > DRM_FORMAT_NV12,
> > +   DRM_FORMAT_XYUV,
> 
> I would keep the NV12 at the end so that the arrays are easier to
> compare visually.
> 
> >  };
> >  
> >  static const uint64_t skl_format_modifiers_noccs[] = {
> > @@ -3501,6 +3503,8 @@ static u32 skl_plane_ctl_format(uint32_t
> > pixel_format)
> > return PLANE_CTL_FORMAT_XRGB_2101010;
> > case DRM_FORMAT_XBGR2101010:
> > return PLANE_CTL_ORDER_RGBX |
> > PLANE_CTL_FORMAT_XRGB_2101010;
> > +   case DRM_FORMAT_XYUV:
> > +   return PLANE_CTL_FORMAT_AYUV;
> 
> We should probably rename that define to XYUV as well since it
> doesn't
> support per-pixel alpha.
> 
> Since you've only implemented this for skl+ you chould mention that
> in the commit msg. IVB+ support should be equally trivial to
> implement (wink wink).
> 
> > case DRM_FORMAT_YUYV:
> > return PLANE_CTL_FORMAT_YUV422 |
> > PLANE_CTL_YUV422_YUYV;
> > case DRM_FORMAT_YVYU:
> > @@ -4959,6 +4963,7 @@ static int skl_update_scaler_plane(struct
> > intel_crtc_state *crtc_state,
> > case DRM_FORMAT_UYVY:
> > case DRM_FORMAT_VYUY:
> > case DRM_FORMAT_NV12:
> > +   case DRM_FORMAT_XYUV:
> > break;
> > default:
> > DRM_DEBUG_KMS("[PLANE:%d:%s] FB:%d unsupported
> > scaling format 0x%x\n",
> > @@ -13399,6 +13404,7 @@ static bool
> > skl_plane_format_mod_supported(struct drm_plane *_plane,
> > }
> >  
> > switch (format) {
> > +
> 
> Bogus whitespace.
> 
> > case DRM_FORMAT_XRGB:
> > case DRM_FORMAT_XBGR:
> > case DRM_FORMAT_ARGB:
> > @@ -13414,6 +13420,7 @@ static bool
> > skl_plane_format_mod_supported(struct drm_plane *_plane,
> > case DRM_FORMAT_UYVY:
> > case DRM_FORMAT_VYUY:
> > case DRM_FORMAT_NV12:
> > +   case DRM_FORMAT_XYUV:
> > if (modifier == I915_FORMAT_MOD_Yf_TILED)
> > return true;
> > /* fall through */
> > @@ -14540,6 +14547,7 @@ static int intel_framebuffer_init(struct
> > intel_framebuffer *intel_fb,
> > goto err;
> > }
> > break;
> > +   case DRM_FORMAT_XYUV:
> 
> That's not the right spot if we want the platform checks to match
> your
> choice of skl+.
> 
> > case DRM_FORMAT_YUYV:
> > case DRM_FORMAT_UYVY:
> > case DRM_FORMAT_YVYU:
> > diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> > b/drivers/gpu/drm/i915/intel_sprite.c
> > index c286dda625e4..2ac9471974c2 100644
> > --- a/drivers/gpu/drm/i915/intel_sprite.c
> > +++ b/drivers/gpu/drm/i915/intel_sprite.c
> > @@ -1420,6 +1420,7 @@ static bool
> > skl_plane_format_mod_supported(struct drm_plane *_plane,
> > case DRM_FORMAT_UYVY:
> > case DRM_FORMAT_VYUY:
> > case DRM_FORMAT_NV12:
> > +   case DRM_FORMAT_XYUV:
> > if (modifier == I915_FORMAT_MOD_Yf_TILED)
> > return true;
> > /* fall through */
> > -- 
> > 2.17.0
> > 
> > ___
> > Intel-gfx mailing list
> > intel-...@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 2/2] drm/i915: implement EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT

2018-07-17 Thread Dhinakaran Pandiyan
On Tue, 2018-07-17 at 15:34 -0700, Dhinakaran Pandiyan wrote:
> On Tue, 2018-07-17 at 14:49 -0700, matthew.s.atw...@intel.com wrote:
> > 
> > From: Matt Atwood 
> > 
> > According to DP spec (2.9.3.1 of DP 1.4) if
> > EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT is set the addresses in
> > DPCD
> > 02200h through 0220Fh shall contain the DPRX's true capability.
> > These
> > values will match 0h through Fh, except for DPCD_REV,
> > MAX_LINK_RATE, DOWN_STREAM_PORT_PRESENT.
> > 
> > Read from DPCD once for all 3 values as this is an expensive
> > operation.
> > Spec mentions that all of address space 02200h through 0220Fh
> > should
> > contain the right information however currently only 3 values can
> > differ.
> > 
> > There is no address space in the intel_dp->dpcd struct for
> > addresses
> > 02200h through 0220Fh, and since so much of the data is a
> > identical,
> > simply overwrite the values stored in 0h through Fh with
> > the
> > values that can be overwritten from addresses 02200h through
> > 0220Fh.
> > 
> > This patch helps with backward compatibility for devices pre DP1.3.
> > 
> > v2: read only dpcd values which can be affected,
> I still see 6 bytes read and 3 copied.
Ignore this, the original patch was reading 16B. Thanks for clarifying
Matt.

> 
> > 
> >  remove incorrect check,
> > split into drm include changes into separate patch, commit message,
> > verbose debugging statements during overwrite.
> > 
> > Signed-off-by: Matt Atwood 
> > ---
> >  drivers/gpu/drm/i915/intel_dp.c | 37
> > +
> >  1 file changed, 37 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index dde92e4af5d3..364cf41a8b89 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -3738,6 +3738,43 @@ intel_dp_read_dpcd(struct intel_dp
> > *intel_dp)
> >      sizeof(intel_dp->dpcd)) < 0)
> >     return false; /* aux transfer failed */
> >  
> > +   if (intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> > +   DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT) {
> > +   uint8_t dpcd_ext[6];
> > +
> > +   DRM_DEBUG_KMS("DPCD: Extended Receiver Capability
> > Field Present, accessing 02200h through 022FFh\n");
> > +
> > +   if (drm_dp_dpcd_read(_dp->aux,
> > DP_DP13_DPCD_REV,
> > +   _ext, sizeof(dpcd_ext)) < 0)
> > +   return false; /* aux transfer failed */
> > +
> > +   if (memcmp(_dp->dpcd[DP_DPCD_REV],
> > _ext[DP_DPCD_REV],
> > +      sizeof(u8))) 
> Why use memcmp and memcmpy if it's just one byte? You could just use
> "=="
> 

I believe this is what Jani suggested.
if (memcmp(old_dpcd, new_dpcd, sizeof(new_dpcd)) {
DRM_DEBUG_KMS();
memcpy(old_dpcd, new_dpcd, sizeof(new_dpcd);
}

We lose the information about which specific fields in the 6 bytes
changed, but that's okay IMO.

> > 
> > {
> > +   DRM_DEBUG_KMS("DPCD: new value for DPCD
> > Revision previous value %2x new value %2x\n",
> > +     intel_dp->dpcd[DP_DPCD_REV],
> > +     dpcd_ext[DP_DPCD_REV]);
> > +   memcpy(_dp->dpcd[DP_DPCD_REV],
> > +      _ext[DP_DPCD_REV],
> > +      sizeof(u8));
> > +   }
> > +   if (memcmp(_dp->dpcd[DP_MAX_LINK_RATE],
> > +      _ext[DP_MAX_LINK_RATE],
> > sizeof(u8)))
> > {
> > +   DRM_DEBUG_KMS("DPCD: new value for DPCD
> > Max
> > Link Rate previous value %2x new value %2x\n",
> > +     intel_dp-
> > > 
> > > dpcd[DP_MAX_LINK_RATE],
> > +     dpcd_ext[DP_MAX_LINK_RATE]);
> > +   memcpy(_dp->dpcd[DP_MAX_LINK_RATE],
> > +      _ext[DP_MAX_LINK_RATE],
> > sizeof(u8));
> > +   }
> > +   if (memcmp(_dp-
> > > 
> > > dpcd[DP_DOWNSTREAMPORT_PRESENT],
> > +      _ext[DP_DOWNSTREAMPORT_PRESENT],
> > sizeof(u8))) {
> > +   DRM_DEBUG_KMS("DPCD: new value for DPCD
> > Downstream Port Present  previous value %2x new value %2x\n",
> > +     intel_dp-
> > > 
> > > dpcd[DP_DOWNSTREAMPORT_PRESENT],
> > +     dpcd_ext[DP_DOWNSTREAMPORT_P
> > RE
> > SENT]);
> > +   memcpy(_dp-
> > > 
> > > dpcd[DP_DOWNSTREAMPORT_PRESENT],
> > +      _ext[DP_DOWNSTREAMPORT_PRESENT
> > ],
> > +      sizeof(u8));
> > +   }
> > +   }
> >     DRM_DEBUG_KMS("DPCD: %*ph\n", (int) sizeof(intel_dp-
> > >dpcd),
> > intel_dp->dpcd);
> >  
> >     return intel_dp->dpcd[DP_DPCD_REV] != 0;
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 2/2] drm/i915: implement EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT

2018-07-17 Thread Dhinakaran Pandiyan
On Tue, 2018-07-17 at 14:49 -0700, matthew.s.atw...@intel.com wrote:
> From: Matt Atwood 
> 
> According to DP spec (2.9.3.1 of DP 1.4) if
> EXTENDED_RECEIVER_CAPABILITY_FIELD_PRESENT is set the addresses in
> DPCD
> 02200h through 0220Fh shall contain the DPRX's true capability. These
> values will match 0h through Fh, except for DPCD_REV,
> MAX_LINK_RATE, DOWN_STREAM_PORT_PRESENT.
> 
> Read from DPCD once for all 3 values as this is an expensive
> operation.
> Spec mentions that all of address space 02200h through 0220Fh should
> contain the right information however currently only 3 values can
> differ.
> 
> There is no address space in the intel_dp->dpcd struct for addresses
> 02200h through 0220Fh, and since so much of the data is a identical,
> simply overwrite the values stored in 0h through Fh with the
> values that can be overwritten from addresses 02200h through 0220Fh.
> 
> This patch helps with backward compatibility for devices pre DP1.3.
> 
> v2: read only dpcd values which can be affected,

I still see 6 bytes read and 3 copied.

>  remove incorrect check,
> split into drm include changes into separate patch, commit message,
> verbose debugging statements during overwrite.
> 
> Signed-off-by: Matt Atwood 
> ---
>  drivers/gpu/drm/i915/intel_dp.c | 37
> +
>  1 file changed, 37 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c
> b/drivers/gpu/drm/i915/intel_dp.c
> index dde92e4af5d3..364cf41a8b89 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -3738,6 +3738,43 @@ intel_dp_read_dpcd(struct intel_dp *intel_dp)
>    sizeof(intel_dp->dpcd)) < 0)
>   return false; /* aux transfer failed */
>  
> + if (intel_dp->dpcd[DP_TRAINING_AUX_RD_INTERVAL] &
> + DP_EXTENDED_RECEIVER_CAP_FIELD_PRESENT) {
> + uint8_t dpcd_ext[6];
> +
> + DRM_DEBUG_KMS("DPCD: Extended Receiver Capability
> Field Present, accessing 02200h through 022FFh\n");
> +
> + if (drm_dp_dpcd_read(_dp->aux,
> DP_DP13_DPCD_REV,
> + _ext, sizeof(dpcd_ext)) < 0)
> + return false; /* aux transfer failed */
> +
> + if (memcmp(_dp->dpcd[DP_DPCD_REV],
> _ext[DP_DPCD_REV],
> +    sizeof(u8))) 

Why use memcmp and memcmpy if it's just one byte? You could just use
"=="

> {
> + DRM_DEBUG_KMS("DPCD: new value for DPCD
> Revision previous value %2x new value %2x\n",
> +   intel_dp->dpcd[DP_DPCD_REV],
> +   dpcd_ext[DP_DPCD_REV]);
> + memcpy(_dp->dpcd[DP_DPCD_REV],
> +    _ext[DP_DPCD_REV],
> +    sizeof(u8));
> + }
> + if (memcmp(_dp->dpcd[DP_MAX_LINK_RATE],
> +    _ext[DP_MAX_LINK_RATE], sizeof(u8)))
> {
> + DRM_DEBUG_KMS("DPCD: new value for DPCD Max
> Link Rate previous value %2x new value %2x\n",
> +   intel_dp-
> >dpcd[DP_MAX_LINK_RATE],
> +   dpcd_ext[DP_MAX_LINK_RATE]);
> + memcpy(_dp->dpcd[DP_MAX_LINK_RATE],
> +    _ext[DP_MAX_LINK_RATE],
> sizeof(u8));
> + }
> + if (memcmp(_dp-
> >dpcd[DP_DOWNSTREAMPORT_PRESENT],
> +    _ext[DP_DOWNSTREAMPORT_PRESENT],
> sizeof(u8))) {
> + DRM_DEBUG_KMS("DPCD: new value for DPCD
> Downstream Port Present  previous value %2x new value %2x\n",
> +   intel_dp-
> >dpcd[DP_DOWNSTREAMPORT_PRESENT],
> +   dpcd_ext[DP_DOWNSTREAMPORT_PRE
> SENT]);
> + memcpy(_dp-
> >dpcd[DP_DOWNSTREAMPORT_PRESENT],
> +    _ext[DP_DOWNSTREAMPORT_PRESENT],
> +    sizeof(u8));
> + }
> + }
>   DRM_DEBUG_KMS("DPCD: %*ph\n", (int) sizeof(intel_dp->dpcd),
> intel_dp->dpcd);
>  
>   return intel_dp->dpcd[DP_DPCD_REV] != 0;
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 10/14] drm/i915: Populate possible_crtcs correctly

2018-06-25 Thread Dhinakaran Pandiyan
On Mon, 2018-06-25 at 14:10 +0300, Ville Syrjälä wrote:
> On Thu, Jun 21, 2018 at 06:26:04PM -0700, Dhinakaran Pandiyan wrote:
> > 
> > On Fri, 2018-06-15 at 19:49 +0300, Ville Syrjala wrote:
> > > 
> > > From: Ville Syrjälä 
> > > 
> > > Don't advertize non-exisiting crtcs in the encoder possible_crtcs
> > > bitmask.
> > > 
> > How do we end up advertising non-existing CRTCs? encoder->crtc_mask
> > seems to be populated in the encoder init functions based on
> > possible
> > pipes. Do you mean pipe and crtc->index can potentially differ?
> No. Just that we may sometimes set BIT(PIPE_C) in crtc_mask when
> there are only two pipes on the device.
> 
Got it, thanks.
Since crtc_mask seems to be initialized based on the platform, we
should probably warn if we find out a bit is set incorrectly.

With or without that, this patch is
Reviewed-by: Dhinakaran Pandiyan 



> > 
> > 
> > 
> > > 
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/intel_display.c | 17 -
> > >  1 file changed, 16 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > > b/drivers/gpu/drm/i915/intel_display.c
> > > index b095899d68a9..3fa9da714403 100644
> > > --- a/drivers/gpu/drm/i915/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/intel_display.c
> > > @@ -13959,6 +13959,20 @@ static int intel_encoder_clones(struct
> > > intel_encoder *encoder)
> > >   return index_mask;
> > >  }
> > >  
> > > +static int intel_encoder_crtcs(struct intel_encoder *encoder)
> > > +{
> > > + struct drm_device *dev = encoder->base.dev;
> > > + struct intel_crtc *crtc;
> > > + int index_mask = 0;
> > > +
> > > + for_each_intel_crtc(dev, crtc) {
> > > + if (encoder->crtc_mask & BIT(crtc->pipe))
> > > + index_mask |= drm_crtc_mask(
> > > >base);
> > > + }
> > > +
> > > + return index_mask;
> > > +}
> > > +
> > >  static bool has_edp_a(struct drm_i915_private *dev_priv)
> > >  {
> > >   if (!IS_MOBILE(dev_priv))
> > > @@ -14211,7 +14225,8 @@ static void intel_setup_outputs(struct
> > > drm_i915_private *dev_priv)
> > >   intel_psr_init(dev_priv);
> > >  
> > >   for_each_intel_encoder(_priv->drm, encoder) {
> > > - encoder->base.possible_crtcs = encoder-
> > > >crtc_mask;
> > > + encoder->base.possible_crtcs =
> > > + intel_encoder_crtcs(encoder);
> > >   encoder->base.possible_clones =
> > >   intel_encoder_clones(encoder);
> > >   }
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 10/14] drm/i915: Populate possible_crtcs correctly

2018-06-21 Thread Dhinakaran Pandiyan
On Fri, 2018-06-15 at 19:49 +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Don't advertize non-exisiting crtcs in the encoder possible_crtcs
> bitmask.
> 
How do we end up advertising non-existing CRTCs? encoder->crtc_mask
seems to be populated in the encoder init functions based on possible
pipes. Do you mean pipe and crtc->index can potentially differ?


> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_display.c | 17 -
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index b095899d68a9..3fa9da714403 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -13959,6 +13959,20 @@ static int intel_encoder_clones(struct
> intel_encoder *encoder)
>   return index_mask;
>  }
>  
> +static int intel_encoder_crtcs(struct intel_encoder *encoder)
> +{
> + struct drm_device *dev = encoder->base.dev;
> + struct intel_crtc *crtc;
> + int index_mask = 0;
> +
> + for_each_intel_crtc(dev, crtc) {
> + if (encoder->crtc_mask & BIT(crtc->pipe))
> + index_mask |= drm_crtc_mask(>base);
> + }
> +
> + return index_mask;
> +}
> +
>  static bool has_edp_a(struct drm_i915_private *dev_priv)
>  {
>   if (!IS_MOBILE(dev_priv))
> @@ -14211,7 +14225,8 @@ static void intel_setup_outputs(struct
> drm_i915_private *dev_priv)
>   intel_psr_init(dev_priv);
>  
>   for_each_intel_encoder(_priv->drm, encoder) {
> - encoder->base.possible_crtcs = encoder->crtc_mask;
> + encoder->base.possible_crtcs =
> + intel_encoder_crtcs(encoder);
>   encoder->base.possible_clones =
>   intel_encoder_clones(encoder);
>   }
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH 11/14] drm/i915: Fix DP-MST crtc_mask

2018-06-21 Thread Dhinakaran Pandiyan
On Fri, 2018-06-15 at 21:43 +0300, Ville Syrjälä wrote:
> On Fri, Jun 15, 2018 at 11:33:01AM -0700, Dhinakaran Pandiyan wrote:
> > 
> > On Fri, 2018-06-15 at 19:49 +0300, Ville Syrjala wrote:
> > > 
> > > From: Ville Syrjälä 
> > > 
> > > Each fake MST encoder is tied to a specific pipe. Fix the
> > > encoder's
> > > crtc_mask to reflect that fact.
> > > 
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/intel_dp_mst.c | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c
> > > b/drivers/gpu/drm/i915/intel_dp_mst.c
> > > index 5890500a3a8b..8e30765402b4 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> > > @@ -565,7 +565,7 @@ intel_dp_create_fake_mst_encoder(struct
> > > intel_digital_port *intel_dig_port, enum
> > >   intel_encoder->type = INTEL_OUTPUT_DP_MST;
> > >   intel_encoder->power_domain = intel_dig_port-
> > > > 
> > > > base.power_domain;
> > >   intel_encoder->port = intel_dig_port->base.port;
> > > - intel_encoder->crtc_mask = 0x7;
> > > + intel_encoder->crtc_mask = BIT(pipe);
> > How did this not cause any problems? Does this mean this field
> > was/is
> > unused?
> This is a hint to userspace. So userspace would pick the connector
> and crtc based on the hints, and then the kernel gets to pick the
> actual encoder. In this case the bogus hint was good enough to tell
> userspace that it can pick any crtc for any MST connector.
> 
> Hmm. Why on earth do we have .atomic_best_encoder() and
> .best_encoder()
> for MST? The fb_helper appears to want to use the non-atomic one for
> some reason... On boy, I guess I'll need to do something about that.
> As is this patch would probably break it :(
> 
So we end up picking crtc-0 for all MST connectors with the same
primary.

Since this patch does the right thing and assuming
https://patchwork.freedesktop.org/patch/229905/ gets merged before this

Reviewed-by: Dhinakaran Pandiyan 



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


Re: [Intel-gfx] [PATCH 11/14] drm/i915: Fix DP-MST crtc_mask

2018-06-15 Thread Dhinakaran Pandiyan
On Fri, 2018-06-15 at 19:49 +0300, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Each fake MST encoder is tied to a specific pipe. Fix the encoder's
> crtc_mask to reflect that fact.
> 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_dp_mst.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c
> b/drivers/gpu/drm/i915/intel_dp_mst.c
> index 5890500a3a8b..8e30765402b4 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -565,7 +565,7 @@ intel_dp_create_fake_mst_encoder(struct
> intel_digital_port *intel_dig_port, enum
>   intel_encoder->type = INTEL_OUTPUT_DP_MST;
>   intel_encoder->power_domain = intel_dig_port-
> >base.power_domain;
>   intel_encoder->port = intel_dig_port->base.port;
> - intel_encoder->crtc_mask = 0x7;
> + intel_encoder->crtc_mask = BIT(pipe);

How did this not cause any problems? Does this mean this field was/is
unused?
Disclaimer: I didn't look at the whole series.

>   intel_encoder->cloneable = 0;
>  
>   intel_encoder->compute_config = intel_dp_mst_compute_config;
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 3/6] drm/psr: Fix missed entry in PSR setup time table.

2018-05-11 Thread Dhinakaran Pandiyan
Entry corresponding to 220 us setup time was missing. I am not aware of
any specific bug this fixes, but this could potentially result in enabling
PSR on a panel with a higher setup time requirement than supported by the
hardware.

I verified the value is present in eDP spec versions 1.3, 1.4 and 1.4a.

Fixes: 6608804b3d7f ("drm/dp: Add drm_dp_psr_setup_time()")
Cc: sta...@vger.kernel.org
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Jose Roberto de Souza <jose.so...@intel.com>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 36c7609a4bd5..a7ba602a43a8 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -1159,6 +1159,7 @@ int drm_dp_psr_setup_time(const u8 
psr_cap[EDP_PSR_RECEIVER_CAP_SIZE])
static const u16 psr_setup_time_us[] = {
PSR_SETUP_TIME(330),
PSR_SETUP_TIME(275),
+   PSR_SETUP_TIME(220),
PSR_SETUP_TIME(165),
PSR_SETUP_TIME(110),
PSR_SETUP_TIME(55),
-- 
2.14.1

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


Re: [PATCH] drm/psr: Fix missed entry in PSR setup time table.

2018-05-11 Thread Dhinakaran Pandiyan
On Fri, 2018-05-11 at 18:03 +, Souza, Jose wrote:
> On Thu, 2018-05-10 at 17:54 -0700, Dhinakaran Pandiyan wrote:
> > 
> > Entry corresponding to 220 us setup time was missing. I am not
> > aware
> > of
> > any specific bug this fixes, but this could potentially result in
> > enabling
> > PSR on a panel with a higher setup time requirement than supported
> > by
> > the
> > hardware.
> It should be 'a lower setup time'.
> Sink sets 2h requesting 220us but source will only wait 165us.

By hardware, I meant source :) We'll end up enabling PSR on a sink with
a higher setup time requirement (220us) than supported by the source
hardware (let's say 200 us) because we read the sink requirement as 165
us.


> 
> Other than that looks good:
> Reviewed-by: José Roberto de Souza <jose.so...@intel.com>
> 
Thanks!

I'll resend this along the other PSR patch you reviewed.

> > 
> > 
> > I verified the value is present in eDP spec versions 1.3, 1.4 and
> > 1.4a.
> > 
> > Fixes: 6608804b3d7f ("drm/dp: Add drm_dp_psr_setup_time()")
> > Cc: sta...@vger.kernel.org
> > Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> > Cc: Jose Roberto de Souza <jose.so...@intel.com>
> > Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
> > ---
> >  drivers/gpu/drm/drm_dp_helper.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_dp_helper.c
> > b/drivers/gpu/drm/drm_dp_helper.c
> > index 36c7609a4bd5..a7ba602a43a8 100644
> > --- a/drivers/gpu/drm/drm_dp_helper.c
> > +++ b/drivers/gpu/drm/drm_dp_helper.c
> > @@ -1159,6 +1159,7 @@ int drm_dp_psr_setup_time(const u8
> > psr_cap[EDP_PSR_RECEIVER_CAP_SIZE])
> >     static const u16 psr_setup_time_us[] = {
> >     PSR_SETUP_TIME(330),
> >     PSR_SETUP_TIME(275),
> > +   PSR_SETUP_TIME(220),
> >     PSR_SETUP_TIME(165),
> >     PSR_SETUP_TIME(110),
> >     PSR_SETUP_TIME(55),
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [Intel-gfx] [PATCH v7 02/10] drm/i915: Move DP modeset retry work into intel_dp

2018-04-24 Thread Dhinakaran Pandiyan



On Wed, 2018-04-11 at 18:54 -0400, Lyude Paul wrote:
> While having the modeset_retry_work in intel_connector makes sense with
> SST, this paradigm doesn't make a whole ton of sense when it comes to
> MST since we have to deal with multiple connectors. In most cases, it's
> more useful to just use the intel_dp struct since it indicates whether
> or not we're dealing with an MST device, along with being able to easily
> trace the intel_dp struct back to it's respective connector (if there is
> any). So, move the modeset_retry_work function out of the
> intel_connector struct and into intel_dp.
> 
> Signed-off-by: Lyude Paul 
> Reviewed-by: Manasi Navare 
> Cc: Manasi Navare 
> Cc: Ville Syrjälä 
> 
> V2:
>  - Remove accidental duplicate modeset_retry_work in intel_connector
> V3:
>  - Also check against eDP in intel_hpd_poll_fini() - mdnavare

contradicts with 

commit c0cfb10d9e1de490e36d3b9d4228c0ea0ca30677
Author: Manasi Navare 
Date:   Thu Oct 12 12:13:38 2017 -0700

drm/i915/edp: Do not do link training fallback or prune modes on EDP

In case of eDP because the panel has a fixed mode, the link rate
and lane count at which it is trained corresponds to the link BW
required to support the native resolution of the panel. In case of
panles with lower resolutions where fewer lanes are hooked up
internally,
that number is reflected in the MAX_LANE_COUNT DPCD register of the
panel.
So it is pointless to fallback to lower link rate/lane count in case
of link training failure on eDP connector since the lower link BW
will not support the native resolution of the panel and we cannot
prune the preferred mode on the eDP connector.




> V4:
>  - Don't bother looping over connectors for canceling modeset rety work,
>just encoders.
> V7:
>  - Fix CHECKPATCH errors
> Signed-off-by: Lyude Paul 
> ---
>  drivers/gpu/drm/i915/intel_display.c  | 14 +++---
>  drivers/gpu/drm/i915/intel_dp.c   | 10 --
>  drivers/gpu/drm/i915/intel_dp_link_training.c |  2 +-
>  drivers/gpu/drm/i915/intel_drv.h  |  6 +++---
>  4 files changed, 19 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c 
> b/drivers/gpu/drm/i915/intel_display.c
> index e04050ea3e28..18edb9628a54 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -15471,20 +15471,28 @@ void intel_connector_unregister(struct 
> drm_connector *connector)
>  
>  static void intel_hpd_poll_fini(struct drm_device *dev)
>  {
> - struct intel_connector *connector;
>   struct drm_connector_list_iter conn_iter;
> + struct intel_connector *connector;
> + struct intel_encoder *encoder;
> + struct intel_dp *intel_dp;
>  
>   /* Kill all the work that may have been queued by hpd. */
>   drm_connector_list_iter_begin(dev, _iter);
>   for_each_intel_connector_iter(connector, _iter) {
> - if (connector->modeset_retry_work.func)
> - cancel_work_sync(>modeset_retry_work);
>   if (connector->hdcp_shim) {
>   cancel_delayed_work_sync(>hdcp_check_work);
>   cancel_work_sync(>hdcp_prop_work);
>   }
>   }
>   drm_connector_list_iter_end(_iter);
> +
> + for_each_intel_encoder(dev, encoder) {
> + if (encoder->type == INTEL_OUTPUT_DP ||

commit 7e732cacb1ae27b2eb6902cabd93e9da086c54f0
Author: Ville Syrjälä 
Date:   Fri Oct 27 22:31:24 2017 +0300

drm/i915: Stop frobbing with DDI encoder->type

Currently the DDI encoder->type will change at runtime depending on
what kind of hotplugs we've processed. That's quite bad since we
can't
really trust that that current value of encoder->type actually
matches
the type of signal we're trying to drive through it.

Let's eliminate that problem by declaring that non-eDP DDI port will
always have the encoder type as INTEL_OUTPUT_DDI. This means the
code
can no longer try to distinguish DP vs. HDMI based on encoder->type.
We'll leave eDP as INTEL_OUTPUT_EDP, since it'll never change and
there's a bunch of code that relies on that value to identify eDP
encoders.



> + encoder->type == INTEL_OUTPUT_EDP) {
> + intel_dp = enc_to_intel_dp(>base);
> + cancel_work_sync(_dp->modeset_retry_work);
> + }
> + }
>  }
>  
>  void intel_modeset_cleanup(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 62f82c4298ac..fbb467bc227d 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -6249,12 +6249,10 @@ static bool intel_edp_init_connector(struct intel_dp 
> *intel_dp,
>  
>  

Re: [Intel-gfx] [PATCH v8 01/10] drm/atomic: Print debug message on atomic check failure

2018-04-24 Thread Dhinakaran Pandiyan



On Wed, 2018-04-11 at 19:42 -0400, Lyude Paul wrote:
> Does what it says on the label, it's a little confusing debugging atomic
> check failures otherwise.
> 
> Cc: Manasi Navare <manasi.d.nav...@intel.com>
> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> Signed-off-by: Lyude Paul <ly...@redhat.com>
> ---
>  drivers/gpu/drm/drm_atomic.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 7d25c42f22db..972a7e9634ab 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -1705,8 +1705,11 @@ int drm_atomic_check_only(struct drm_atomic_state 
> *state)
>   if (config->funcs->atomic_check)
>   ret = config->funcs->atomic_check(state->dev, state);
>  
> - if (ret)
> + if (ret) {
> + DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n",
> +  state, ret);
>   return ret;
> + }
>  

nit: Would have slightly looked better if the 'ret' check was moved
inside the branch for funcs->atomic_check.

Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>



>   if (!state->allow_modeset) {
>   for_each_new_crtc_in_state(state, crtc, crtc_state, i) {

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


Re: [PATCH v4] drm/i915/dp: Send DPCD ON for MST before phy_up

2018-04-06 Thread Dhinakaran Pandiyan



On Fri, 2018-04-06 at 14:52 -0400, Lyude Paul wrote:
> When doing a modeset where the sink is transitioning from D3 to D0 , it
> would sometimes be possible for the initial power_up_phy() to start
> timing out. This would only be observed in the last action before the
> sink went into D3 mode was intel_dp_sink_dpms(DRM_MODE_DPMS_OFF). We
> originally thought this might be an issue with us accidentally shutting
> off the aux block when putting the sink into D3, but since the DP spec
> mandates that sinks must wake up within 1ms while we have 100ms to
> respond to an ESI irq, this didn't really add up. Turns out that the
> problem is more subtle then that:
> 
> It turns out that the timeout is from us not enabling DPMS on the MST
> hub before actually trying to initiate sideband communications. This
> would cause the first sideband communication (power_up_phy()), to start
> timing out because the sink wasn't ready to respond. Afterwards, we
> would call intel_dp_sink_dpms(DRM_MODE_DPMS_ON) in
> intel_ddi_pre_enable_dp(), which would actually result in waking up the
> sink so that sideband requests would work again.
> 
> Since DPMS is what lets us actually bring the hub up into a state where
> sideband communications become functional again, we just need to make
> sure to enable DPMS on the display before attempting to perform sideband
> communications.
> 

Matches my understanding of the problem

Reviewed-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>

It's better to get an ack from Ville considering I was okay with the
D3_AUX_ON solution too.


> Changes since v1:
> - Remove comment above if (!intel_dp->is_mst) - vsryjala
> - Move intel_dp_sink_dpms() for MST into intel_dp_post_disable_mst() to
>   keep enable/disable paths symmetrical
> - Improve commit message - dhnkrn
> Changes since v2:
> - Only send DPMS off when we're disabling the last sink, and only send
>   DPMS on when we're enabling the first sink - dhnkrn
> Changes since v3:
> - Check against is_mst, not intel_dp->is_mst - dhnkrn/vsyrjala
> 
> Signed-off-by: Lyude Paul <ly...@redhat.com>
> Cc: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> Cc: Laura Abbott <labb...@redhat.com>
> Cc: sta...@vger.kernel.org
> Fixes: ad260ab32a4d9 ("drm/i915/dp: Write to SET_POWER dpcd to enable MST 
> hub.")
> ---
>  drivers/gpu/drm/i915/intel_ddi.c| 8 ++--
>  drivers/gpu/drm/i915/intel_dp_mst.c | 8 +++-
>  2 files changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index a6672a9abd85..92cb26b18a9b 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2324,7 +2324,8 @@ static void intel_ddi_pre_enable_dp(struct 
> intel_encoder *encoder,
>   intel_prepare_dp_ddi_buffers(encoder, crtc_state);
>  
>   intel_ddi_init_dp_buf_reg(encoder);
> - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> + if (!is_mst)
> + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
>   intel_dp_start_link_train(intel_dp);
>   if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
>   intel_dp_stop_link_train(intel_dp);
> @@ -2422,12 +2423,15 @@ static void intel_ddi_post_disable_dp(struct 
> intel_encoder *encoder,
>   struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
>   struct intel_digital_port *dig_port = enc_to_dig_port(>base);
>   struct intel_dp *intel_dp = _port->dp;
> + bool is_mst = intel_crtc_has_type(old_crtc_state,
> +   INTEL_OUTPUT_DP_MST);
>  
>   /*
>* Power down sink before disabling the port, otherwise we end
>* up getting interrupts from the sink on detecting link loss.
>*/
> - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
> + if (!is_mst)
> + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>  
>   intel_disable_ddi_buf(encoder);
>  
> diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
> b/drivers/gpu/drm/i915/intel_dp_mst.c
> index c3de0918ee13..9e6956c08688 100644
> --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> @@ -180,9 +180,11 @@ static void intel_mst_post_disable_dp(struct 
> intel_encoder *encoder,
>   intel_dp->active_mst_links--;
>  
>   intel_mst->connector = NULL;
> - if (intel_dp->active_mst_links == 0)
> + if (intel_dp->active_mst_links == 0) {
> + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
>   intel_dig_port->base.post_disable(_dig_port->base,

Re: [Intel-gfx] [PATCH v3] drm/i915/dp: Send DPCD ON for MST before phy_up

2018-04-05 Thread Dhinakaran Pandiyan



On Thu, 2018-04-05 at 17:19 -0400, Lyude Paul wrote:
> When doing a modeset where the sink is transitioning from D3 to D0 , it
> would sometimes be possible for the initial power_up_phy() to start
> timing out. This would only be observed in the last action before the
> sink went into D3 mode was intel_dp_sink_dpms(DRM_MODE_DPMS_OFF). We
> originally thought this might be an issue with us accidentally shutting
> off the aux block when putting the sink into D3, but since the DP spec
> mandates that sinks must wake up within 1ms while we have 100ms to
> respond to an ESI irq, this didn't really add up. Turns out that the
> problem is more subtle then that:
> 
> It turns out that the timeout is from us not enabling DPMS on the MST
> hub before actually trying to initiate sideband communications. This
> would cause the first sideband communication (power_up_phy()), to start
> timing out because the sink wasn't ready to respond. Afterwards, we
> would call intel_dp_sink_dpms(DRM_MODE_DPMS_ON) in
> intel_ddi_pre_enable_dp(), which would actually result in waking up the
> sink so that sideband requests would work again.
> 
> Since DPMS is what lets us actually bring the hub up into a state where
> sideband communications become functional again, we just need to make
> sure to enable DPMS on the display before attempting to perform sideband
> communications.
> 
> Changes since v1:
> - Remove comment above if (!intel_dp->is_mst) - vsryjala
> - Move intel_dp_sink_dpms() for MST into intel_dp_post_disable_mst() to
>   keep enable/disable paths symmetrical
> - Improve commit message - dhnkrn
> Changes since v2:
> - Only send DPMS off when we're disabling the last sink, and only send
>   DPMS on when we're enabling the first sink - dhnkrn
> 
> Signed-off-by: Lyude Paul <ly...@redhat.com>
> Cc: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
> Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> Cc: Laura Abbott <labb...@redhat.com>
> Cc: sta...@vger.kernel.org
> Fixes: ad260ab32a4d9 ("drm/i915/dp: Write to SET_POWER dpcd to enable MST 
> hub.")
> ---
>  drivers/gpu/drm/i915/intel_ddi.c| 6 --
>  drivers/gpu/drm/i915/intel_dp_mst.c | 8 +++-
>  2 files changed, 11 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> b/drivers/gpu/drm/i915/intel_ddi.c
> index a6672a9abd85..c0bf7419e1c1 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -2324,7 +2324,8 @@ static void intel_ddi_pre_enable_dp(struct 
> intel_encoder *encoder,
>   intel_prepare_dp_ddi_buffers(encoder, crtc_state);
>  
>   intel_ddi_init_dp_buf_reg(encoder);
> - intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> + if (!intel_dp->is_mst)
> + intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);



I believe Ville recommended to check for
is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST)
here. The question is, are there cases where 
intel_dp->is_mst != is_mst? A disconnect in the middle of a modeset
would cause intel_dp->is_mst to be false, wouldn't it?







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


Re: [Intel-gfx] [PATCH] drm/i915/dp: Send DPCD ON for MST before phy_up

2018-04-05 Thread Dhinakaran Pandiyan



On Thu, 2018-04-05 at 19:38 +0300, Ville Syrjälä wrote:
> On Wed, Apr 04, 2018 at 07:27:21PM -0400, Lyude Paul wrote:
> > As it turns out, the aux block being off was not the real problem here,
> > as transition from D3 to D0 is mandated by the DP spec to take a maximum
> > of 1ms, whereas we're allowed a 100ms timeframe to respond to ESI irqs.
> > The real problem here is a bit more subtle.
> > 
> > When doing a modeset where the problem of the sink timing out to our
> > sideband requests when transitioning from D3 to D0 occurs, the timeout
> > is from the aux block not coming on. However, nothing else times out
> > other than the initial phy_up message because the DPCD on call in
> > intel_ddi_enable_dp() ends up waking up the AUX block on the hub, not
> > the phy_up sideband message. 


This is the case only when intel_dp_sink_dpms(DRM_MODE_DPMS_OFF) was the
last action. With power_down_phy in post_disable() and power_up_phy in
pre_enable(), we weren't seeing this issue.




> This means that the real fix we need is to
> > use the DPMS on before sending a phy_up to ensure that the hub is ready
> > to accept sideband messages.
> > 
> > Signed-off-by: Lyude Paul <ly...@redhat.com>
> > Cc: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
> > Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
> > Cc: Laura Abbott <labb...@redhat.com>
> > Cc: sta...@vger.kernel.org
> > Fixes: ad260ab32a4d9 ("drm/i915/dp: Write to SET_POWER dpcd to enable MST 
> > hub.")
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c| 6 +-
> >  drivers/gpu/drm/i915/intel_dp_mst.c | 1 +
> >  2 files changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c 
> > b/drivers/gpu/drm/i915/intel_ddi.c
> > index a6672a9abd85..9bd675f73f7b 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -2324,7 +2324,11 @@ static void intel_ddi_pre_enable_dp(struct 
> > intel_encoder *encoder,
> > intel_prepare_dp_ddi_buffers(encoder, crtc_state);
> >  
> > intel_ddi_init_dp_buf_reg(encoder);
> > -   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > +   /* for MST, we do DPMS_ON outside of here so that DPMS_ON can happen
> > +* before drm_dp_send_power_updown_phy()
> > +*/
> > +   if (!intel_dp->is_mst)
> 
> Just 'is_mst' should do here.
> 
> And in general I'd like to see the enable and disable paths remain
> symmetric. Ie. also move out the dpms call in the disable path (or
> maybe move the phy_power_up/down in?).
> 
> > +   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > intel_dp_start_link_train(intel_dp);
> > if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
> > intel_dp_stop_link_train(intel_dp);
> > diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
> > b/drivers/gpu/drm/i915/intel_dp_mst.c
> > index c3de0918ee13..eff9a4eae1f0 100644
> > --- a/drivers/gpu/drm/i915/intel_dp_mst.c
> > +++ b/drivers/gpu/drm/i915/intel_dp_mst.c
> > @@ -223,6 +223,7 @@ static void intel_mst_pre_enable_dp(struct 
> > intel_encoder *encoder,
> >  
> > DRM_DEBUG_KMS("active links %d\n", intel_dp->active_mst_links);
> >  
> > +   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
> > drm_dp_send_power_updown_phy(_dp->mst_mgr, connector->port, true);
> 
> This could use a comment to remind people that the order does matter.
> 
> > if (intel_dp->active_mst_links == 0)
> > intel_dig_port->base.pre_enable(_dig_port->base,
> > -- 
> > 2.14.3
> 

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


[PATCH] drm/doc: Fix documentation for _vblank_restore().

2018-02-21 Thread Dhinakaran Pandiyan
No code changes, fixes doc build warnings and polish some doc text.

Reported-by: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 22 ++
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index c781cb426bf1..51041eec0047 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1238,12 +1238,15 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
 EXPORT_SYMBOL(drm_crtc_vblank_on);
 
 /**
- * drm_vblank_restore - estimated vblanks using timestamps and update it.
+ * drm_vblank_restore - estimate missed vblanks and update vblank count.
+ * @dev: DRM device
+ * @pipe: CRTC index
  *
  * Power manamement features can cause frame counter resets between vblank
- * disable and enable. Drivers can then use this function in their
- * _crtc_funcs.enable_vblank implementation to estimate the vblanks since
- * the last _crtc_funcs.disable_vblank.
+ * disable and enable. Drivers can use this function in their
+ * _crtc_funcs.enable_vblank implementation to estimate missed vblanks 
since
+ * the last _crtc_funcs.disable_vblank using timestamps and update the
+ * vblank counter.
  *
  * This function is the legacy version of drm_crtc_vblank_restore().
  */
@@ -1284,11 +1287,14 @@ void drm_vblank_restore(struct drm_device *dev, 
unsigned int pipe)
 EXPORT_SYMBOL(drm_vblank_restore);
 
 /**
- * drm_crtc_vblank_restore - estimate vblanks using timestamps and update it.
+ * drm_crtc_vblank_restore - estimate missed vblanks and update vblank count.
+ * @crtc: CRTC in question
+ *
  * Power manamement features can cause frame counter resets between vblank
- * disable and enable. Drivers can then use this function in their
- * _crtc_funcs.enable_vblank implementation to estimate the vblanks since
- * the last _crtc_funcs.disable_vblank.
+ * disable and enable. Drivers can use this function in their
+ * _crtc_funcs.enable_vblank implementation to estimate missed vblanks 
since
+ * the last _crtc_funcs.disable_vblank using timestamps and update the
+ * vblank counter.
  */
 void drm_crtc_vblank_restore(struct drm_crtc *crtc)
 {
-- 
2.14.1

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


[PATCH 07/10] drm/atomic: Handle 64-bit return from drm_crtc_vblank_count()

2018-02-02 Thread Dhinakaran Pandiyan
570e86963a51 ("drm: Widen vblank count to 64-bits [v3]") changed the
return type for drm_crtc_vblank_count() to u64.

The flip ioctl receives a 32-bit target sequence from user space and is
compared against the current sequence from drm_crtc_vblank_count(). So,
typecast return from drm_crtc_vblank_count() explicitly to add clarity.

__drm_crtcs_state.last_vblank_count however only ever stores the value from
drm_crtc_vblank_count() and can be upgraded to u64.

Cc: Keith Packard <kei...@keithp.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_plane.c | 2 +-
 include/drm/drm_atomic.h| 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c
index 22b54663b6e7..09de6ecb3968 100644
--- a/drivers/gpu/drm/drm_plane.c
+++ b/drivers/gpu/drm/drm_plane.c
@@ -948,7 +948,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev,
if (r)
return r;
 
-   current_vblank = drm_crtc_vblank_count(crtc);
+   current_vblank = (u32)drm_crtc_vblank_count(crtc);
 
switch (page_flip->flags & DRM_MODE_PAGE_FLIP_TARGET) {
case DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE:
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index cf13842a6dbd..2c711a24c80c 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -154,7 +154,7 @@ struct __drm_crtcs_state {
struct drm_crtc *ptr;
struct drm_crtc_state *state, *old_state, *new_state;
s32 __user *out_fence_ptr;
-   unsigned last_vblank_count;
+   u64 last_vblank_count;
 };
 
 struct __drm_connnectors_state {
-- 
2.14.1

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


[PATCH 09/10] drm/vblank: Restoring vblank counts after device PM events.

2018-02-02 Thread Dhinakaran Pandiyan
From: "Pandiyan, Dhinakaran" <dhinakaran.pandi...@intel.com>

The HW frame counter can get reset if device enters a low power state after
vblank interrupts were disabled. This messes up any following vblank count
update as a negative diff (huge unsigned diff) is calculated from the HW
frame counter change. We cannot ignore negative diffs altogther as there
could be legitimate wrap arounds. So, allow drivers to update vblank->count
with missed vblanks for the time interrupts were disabled. This is similar
to _crtc_vblank_on() except that vblanks interrupts are not enabled at the
end as this function is expected to be called from the driver
_enable_vblank() vfunc.

v2: drm_crtc_vblank_restore should take crtc as arg. (Chris)
Add docs and sprinkle some asserts.

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Michel Dänzer <mic...@daenzer.net>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.v...@intel.com>
Acked-by: Daniel Vetter <daniel.vet...@ffwll.ch>
---
 drivers/gpu/drm/drm_vblank.c | 59 
 include/drm/drm_vblank.h |  2 ++
 2 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 913954765d9e..c781cb426bf1 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1237,6 +1237,65 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_vblank_on);
 
+/**
+ * drm_vblank_restore - estimated vblanks using timestamps and update it.
+ *
+ * Power manamement features can cause frame counter resets between vblank
+ * disable and enable. Drivers can then use this function in their
+ * _crtc_funcs.enable_vblank implementation to estimate the vblanks since
+ * the last _crtc_funcs.disable_vblank.
+ *
+ * This function is the legacy version of drm_crtc_vblank_restore().
+ */
+void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
+{
+   ktime_t t_vblank;
+   struct drm_vblank_crtc *vblank;
+   int framedur_ns;
+   u64 diff_ns;
+   u32 cur_vblank, diff = 1;
+   int count = DRM_TIMESTAMP_MAXRETRIES;
+
+   if (WARN_ON(pipe >= dev->num_crtcs))
+   return;
+
+   assert_spin_locked(>vbl_lock);
+   assert_spin_locked(>vblank_time_lock);
+
+   vblank = >vblank[pipe];
+   WARN_ONCE((drm_debug & DRM_UT_VBL) && !vblank->framedur_ns,
+ "Cannot compute missed vblanks without frame duration\n");
+   framedur_ns = vblank->framedur_ns;
+
+   do {
+   cur_vblank = __get_vblank_counter(dev, pipe);
+   drm_get_last_vbltimestamp(dev, pipe, _vblank, false);
+   } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+
+   diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
+   if (framedur_ns)
+   diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
+
+
+   DRM_DEBUG_VBL("missed %d vblanks in %lld ns, frame duration=%d ns, 
hw_diff=%d\n",
+ diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
+   store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
+}
+EXPORT_SYMBOL(drm_vblank_restore);
+
+/**
+ * drm_crtc_vblank_restore - estimate vblanks using timestamps and update it.
+ * Power manamement features can cause frame counter resets between vblank
+ * disable and enable. Drivers can then use this function in their
+ * _crtc_funcs.enable_vblank implementation to estimate the vblanks since
+ * the last _crtc_funcs.disable_vblank.
+ */
+void drm_crtc_vblank_restore(struct drm_crtc *crtc)
+{
+   drm_vblank_restore(crtc->dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_restore);
+
 static void drm_legacy_vblank_pre_modeset(struct drm_device *dev,
  unsigned int pipe)
 {
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index a4c3b0a0a197..16d46e2a6854 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -180,6 +180,8 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc);
 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 void drm_crtc_vblank_on(struct drm_crtc *crtc);
 u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+void drm_vblank_restore(struct drm_device *dev, unsigned int pipe);
+void drm_crtc_vblank_restore(struct drm_crtc *crtc);
 
 bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
   unsigned int pipe, int *max_error,
-- 
2.14.1

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


[PATCH 08/10] drm/vblank: Do not update vblank count if interrupts are already disabled.

2018-02-02 Thread Dhinakaran Pandiyan
From: "Pandiyan, Dhinakaran" <dhinakaran.pandi...@intel.com>

Updating vblank counts requires register reads and these reads may not
return meaningful values if the device was in a low power state after
vblank interrupts were last disabled. So, update the count only if vblank
interrupts are enabled. Secondly, this means the registers should be read
before disabling vblank interrupts.

v2: Don't check vblank->enabled outside it's lock (Chris)

Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Michel Dänzer <mic...@daenzer.net>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.v...@intel.com>
Acked-by: Daniel Vetter <daniel.vet...@ffwll.ch>
---
 drivers/gpu/drm/drm_vblank.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index f0d3ed5f2528..913954765d9e 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -347,23 +347,25 @@ void drm_vblank_disable_and_save(struct drm_device *dev, 
unsigned int pipe)
spin_lock_irqsave(>vblank_time_lock, irqflags);
 
/*
-* Only disable vblank interrupts if they're enabled. This avoids
-* calling the ->disable_vblank() operation in atomic context with the
-* hardware potentially runtime suspended.
+* Update vblank count and disable vblank interrupts only if the
+* interrupts were enabled. This avoids calling the ->disable_vblank()
+* operation in atomic context with the hardware potentially runtime
+* suspended.
 */
-   if (vblank->enabled) {
-   __disable_vblank(dev, pipe);
-   vblank->enabled = false;
-   }
+   if (!vblank->enabled)
+   goto out;
 
/*
-* Always update the count and timestamp to maintain the
+* Update the count and timestamp to maintain the
 * appearance that the counter has been ticking all along until
 * this time. This makes the count account for the entire time
 * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
 */
drm_update_vblank_count(dev, pipe, false);
+   __disable_vblank(dev, pipe);
+   vblank->enabled = false;
 
+out:
spin_unlock_irqrestore(>vblank_time_lock, irqflags);
 }
 
-- 
2.14.1

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


[PATCH 06/10] drm/tegra: Handle 64-bit return from drm_crtc_vblank_count()

2018-02-02 Thread Dhinakaran Pandiyan
570e86963a51 ("drm: Widen vblank count to 64-bits [v3]") changed the
return type for drm_crtc_vblank_count() to u64. This could cause
potential problems if the return value is used in arithmetic operations
with a 32-bit reference HW vblank count. Explicitly typecasting this
down to u32 either fixes a potential problem or serves to add clarity in
case the implicit typecasting was already correct.

Cc: Keith Packard <kei...@keithp.com>
Cc: Thierry Reding <tred...@nvidia.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/tegra/dc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index b8403ed48285..49df2db2ad46 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1359,7 +1359,7 @@ static u32 tegra_dc_get_vblank_counter(struct drm_crtc 
*crtc)
return host1x_syncpt_read(dc->syncpt);
 
/* fallback to software emulated VBLANK counter */
-   return drm_crtc_vblank_count(>base);
+   return (u32)drm_crtc_vblank_count(>base);
 }
 
 static int tegra_dc_enable_vblank(struct drm_crtc *crtc)
-- 
2.14.1

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


[PATCH 02/10] drm/i915/vblank: Make the vblank counter u64 -> u32 typecast explicit

2018-02-02 Thread Dhinakaran Pandiyan
Core returns a u64 vblank count and intel_crtc_get_vblank_counter()
expects a 32-bit value. Make the typecast explicit to add clarity.

Cc: Keith Packard <kei...@keithp.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index ad8d9c6c40e4..f6b450de653c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -12075,7 +12075,7 @@ u32 intel_crtc_get_vblank_counter(struct intel_crtc 
*crtc)
struct drm_device *dev = crtc->base.dev;
 
if (!dev->max_vblank_count)
-   return drm_crtc_accurate_vblank_count(>base);
+   return (u32)drm_crtc_accurate_vblank_count(>base);
 
return dev->driver->get_vblank_counter(dev, crtc->pipe);
 }
-- 
2.14.1

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


[PATCH 05/10] drm/radeon: Handle 64-bit return from drm_crtc_vblank_count()

2018-02-02 Thread Dhinakaran Pandiyan
570e86963a51 ("drm: Widen vblank count to 64-bits [v3]") changed the
return type for drm_crtc_vblank_count() to u64. This could cause
potential problems if the return value is used in arithmetic operations
with a 32-bit reference HW vblank count. Explicitly typecasting this down
to u32 either fixes a potential problem or serves to add clarity in case
the implicit typecasting was already correct.

Cc: Keith Packard <kei...@keithp.com>
Cc: Alex Deucher <alexander.deuc...@amd.com>
Cc: Harry Wentland <harry.wentl...@amd.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/radeon/radeon_display.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/radeon_display.c 
b/drivers/gpu/drm/radeon/radeon_display.c
index dfda5e0ed166..26129b2b082d 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -570,7 +570,7 @@ static int radeon_crtc_page_flip_target(struct drm_crtc 
*crtc,
base &= ~7;
}
work->base = base;
-   work->target_vblank = target - drm_crtc_vblank_count(crtc) +
+   work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
dev->driver->get_vblank_counter(dev, work->crtc_id);
 
/* We borrow the event spin lock for protecting flip_work */
-- 
2.14.1

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


[PATCH 10/10] drm/i915: Estimate and update missed vblanks.

2018-02-02 Thread Dhinakaran Pandiyan
From: "Pandiyan, Dhinakaran" <dhinakaran.pandi...@intel.com>

The frame counter may have got reset between disabling and enabling vblank
interrupts due to DMC putting the hardware to DC5/6 states if PSR was
active. The frame counter could also have stalled if PSR was active in case
there was no DMC. The frame counter resetting has a user visible impact
of screen freezes.

Make use of drm_vblank_restore() to compute missed vblanks for the duration
in which vblank interrupts were disabled and update the vblank counter with
this value as diff. There's no need to check if PSR was actually active in
the interrupt disabled duration, so simplify the check to a feature check.

Enabling vblank interrupts wakes up the hardware from DC5/6 and prevents it
from going back again as long as the there are pending interrupts. So, we
don't have to explicity disallow DC5/6 after enabling vblank interrupts to
keep the counter running.

This change is not applicable to CHV, as enabling interrupts does not
prevent the hardware from activating PSR.

v2: Added comments(Rodrigo) and rewrote commit message.

Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.v...@intel.com>
Acked-by: Daniel Vetter <daniel.vet...@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_irq.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 252feff2892d..e86c645b6b07 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2968,6 +2968,12 @@ static int ironlake_enable_vblank(struct drm_device 
*dev, unsigned int pipe)
ilk_enable_display_irq(dev_priv, bit);
spin_unlock_irqrestore(_priv->irq_lock, irqflags);
 
+   /* Even though there is no DMC, frame counter can get stuck when
+* PSR is active as no frames are generated.
+*/
+   if (HAS_PSR(dev_priv))
+   drm_vblank_restore(dev, pipe);
+
return 0;
 }
 
@@ -2980,6 +2986,12 @@ static int gen8_enable_vblank(struct drm_device *dev, 
unsigned int pipe)
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(_priv->irq_lock, irqflags);
 
+   /* Even if there is no DMC, frame counter can get stuck when
+* PSR is active as no frames are generated, so check only for PSR.
+*/
+   if (HAS_PSR(dev_priv))
+   drm_vblank_restore(dev, pipe);
+
return 0;
 }
 
-- 
2.14.1

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


[PATCH 04/10] drm/amdgpu: Handle 64-bit return from drm_crtc_vblank_count()

2018-02-02 Thread Dhinakaran Pandiyan
570e86963a51 ("drm: Widen vblank count to 64-bits [v3]") changed the
return type for drm_crtc_vblank_count() to u64. This could cause
potential problems if the return value is used in arithmetic operations
with a 32-bit reference HW vblank count. Explicitly typecasting this down
to u32 either fixes a potential problem or serves to add clarity in case
the typecasting was implicitly done.

Cc: Keith Packard <kei...@keithp.com>
Cc: Alex Deucher <alexander.deuc...@amd.com>
Cc: Harry Wentland <harry.wentl...@amd.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c   | 2 +-
 drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 38d47559f098..c2fa5d55f04e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -207,7 +207,7 @@ int amdgpu_crtc_page_flip_target(struct drm_crtc *crtc,
amdgpu_bo_unreserve(new_abo);
 
work->base = base;
-   work->target_vblank = target - drm_crtc_vblank_count(crtc) +
+   work->target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
amdgpu_get_vblank_counter_kms(dev, work->crtc_id);
 
/* we borrow the event spin lock for protecting flip_wrok */
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1ce4c98385e3..b7254a29b34a 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3836,7 +3836,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
 
 
/* Prepare wait for target vblank early - before the fence-waits */
-   target_vblank = target - drm_crtc_vblank_count(crtc) +
+   target_vblank = target - (uint32_t)drm_crtc_vblank_count(crtc) +
amdgpu_get_vblank_counter_kms(crtc->dev, 
acrtc->crtc_id);
 
/* TODO This might fail and hence better not used, wait
@@ -3982,7 +3982,7 @@ static void amdgpu_dm_commit_planes(struct 
drm_atomic_state *state,
amdgpu_dm_do_flip(
crtc,
fb,
-   drm_crtc_vblank_count(crtc) + *wait_for_vblank,
+   (uint32_t)drm_crtc_vblank_count(crtc) + 
*wait_for_vblank,
dm_state->context);
}
 
-- 
2.14.1

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


[PATCH 01/10] drm/vblank: Data type fixes for 64-bit vblank sequences.

2018-02-02 Thread Dhinakaran Pandiyan
From: "Pandiyan, Dhinakaran" <dhinakaran.pandi...@intel.com>

drm_vblank_count() has an u32 type returning what is a 64-bit vblank count.
The effect of this is when drm_wait_vblank_ioctl() tries to widen the user
space requested vblank sequence using this clipped 32-bit count(when the
value is >= 2^32) as reference, the requested sequence remains a 32-bit
value and gets queued like that. However, the code that checks if the
requested sequence has passed compares this against the 64-bit vblank
count.

With drm_vblank_count() returning all bits of the vblank count, update
drm_crtc_accurate_vblank_count() so that drm_crtc_arm_vblank_event() queues
the correct sequence. Otherwise, this leads to prolonged waits for a vblank
sequence when the current count is >=2^32.

Finally, fix drm_wait_one_vblank() too.

v2: Commit message fix (Keith)
Squash commits (Rodrigo)

Fixes: 570e86963a51 ("drm: Widen vblank count to 64-bits [v3]")
Cc: Keith Packard <kei...@keithp.com>
Cc: Michel Dänzer <mic...@daenzer.net>
Cc: Daniel Vetter <dan...@ffwll.ch>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
Acked-by: Daniel Vetter <daniel.vet...@ffwll.ch>
---
 drivers/gpu/drm/drm_vblank.c | 8 
 include/drm/drm_vblank.h | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 32d9bcf5be7f..f0d3ed5f2528 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -271,7 +271,7 @@ static void drm_update_vblank_count(struct drm_device *dev, 
unsigned int pipe,
store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
 }
 
-static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
+static u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
 {
struct drm_vblank_crtc *vblank = >vblank[pipe];
 
@@ -292,11 +292,11 @@ static u32 drm_vblank_count(struct drm_device *dev, 
unsigned int pipe)
  * This is mostly useful for hardware that can obtain the scanout position, but
  * doesn't have a hardware frame counter.
  */
-u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
+u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
unsigned int pipe = drm_crtc_index(crtc);
-   u32 vblank;
+   u64 vblank;
unsigned long flags;
 
WARN_ONCE(drm_debug & DRM_UT_VBL && !dev->driver->get_vblank_timestamp,
@@ -1055,7 +1055,7 @@ void drm_wait_one_vblank(struct drm_device *dev, unsigned 
int pipe)
 {
struct drm_vblank_crtc *vblank = >vblank[pipe];
int ret;
-   u32 last;
+   u64 last;
 
if (WARN_ON(pipe >= dev->num_crtcs))
return;
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 848b463a0af5..a4c3b0a0a197 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -179,7 +179,7 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
 void drm_crtc_vblank_off(struct drm_crtc *crtc);
 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 void drm_crtc_vblank_on(struct drm_crtc *crtc);
-u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
 
 bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
   unsigned int pipe, int *max_error,
-- 
2.14.1

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


[PATCH 03/10] drm/i915: Handle 64-bit return from drm_crtc_vblank_count()

2018-02-02 Thread Dhinakaran Pandiyan
570e86963a51 ("drm: Widen vblank count to 64-bits [v3]") changed the
return type for drm_crtc_vblank_count() to u64, store all the bits
without truncating. There is no need to type cast this value down to
32-bits.

Cc: Keith Packard <kei...@keithp.com>
Cc: Paulo Zanoni <paulo.r.zan...@intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 2 +-
 drivers/gpu/drm/i915/i915_drv.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 3849ded354e3..4b9da04c1d4a 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -1599,7 +1599,7 @@ static int i915_fbc_status(struct seq_file *m, void 
*unused)
seq_printf(m, "FBC disabled: %s\n", fbc->no_fbc_reason);
 
if (fbc->work.scheduled)
-   seq_printf(m, "FBC worker scheduled on vblank %u, now %llu\n",
+   seq_printf(m, "FBC worker scheduled on vblank %llu, now %llu\n",
   fbc->work.scheduled_vblank,
   drm_crtc_vblank_count(>crtc->base));
 
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c676269ed843..d22677494499 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -717,7 +717,7 @@ struct intel_fbc {
 
struct intel_fbc_work {
bool scheduled;
-   u32 scheduled_vblank;
+   u64 scheduled_vblank;
struct work_struct work;
} work;
 
-- 
2.14.1

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


[PATCH 8/9] drm/dp: Export AUX_RETRY_INTERVAL

2018-01-26 Thread Dhinakaran Pandiyan
Drivers can use this in their retry loops too.

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_dp_helper.c | 12 +---
 include/drm/drm_dp_helper.h |  2 ++
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index ffe14ec3e7f2..0a7c8d6e7d8c 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -169,8 +169,6 @@ int drm_dp_bw_code_to_link_rate(u8 link_bw)
 }
 EXPORT_SYMBOL(drm_dp_bw_code_to_link_rate);
 
-#define AUX_RETRY_INTERVAL 500 /* us */
-
 /**
  * DOC: dp helpers
  *
@@ -206,8 +204,8 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 
request,
 */
for (retry = 0; retry < 32; retry++) {
if (ret != 0 && ret != -ETIMEDOUT) {
-   usleep_range(AUX_RETRY_INTERVAL,
-AUX_RETRY_INTERVAL + 100);
+   usleep_range(DP_AUX_RETRY_INTERVAL,
+DP_AUX_RETRY_INTERVAL + 100);
}
 
ret = aux->transfer(aux, );
@@ -718,7 +716,7 @@ static int drm_dp_i2c_retry_count(const struct 
drm_dp_aux_msg *msg,
drm_dp_aux_reply_duration(msg);
int i2c_time_us = drm_dp_i2c_msg_duration(msg, i2c_speed_khz);
 
-   return DIV_ROUND_UP(i2c_time_us, aux_time_us + AUX_RETRY_INTERVAL);
+   return DIV_ROUND_UP(i2c_time_us, aux_time_us + DP_AUX_RETRY_INTERVAL);
 }
 
 /*
@@ -795,7 +793,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct 
drm_dp_aux_msg *msg)
 * For now just defer for long enough to hopefully be
 * safe for all use-cases.
 */
-   usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 
100);
+   usleep_range(DP_AUX_RETRY_INTERVAL, 
DP_AUX_RETRY_INTERVAL + 100);
continue;
 
default:
@@ -827,7 +825,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct 
drm_dp_aux_msg *msg)
aux->i2c_defer_count++;
if (defer_i2c < 7)
defer_i2c++;
-   usleep_range(AUX_RETRY_INTERVAL, AUX_RETRY_INTERVAL + 
100);
+   usleep_range(DP_AUX_RETRY_INTERVAL, 
DP_AUX_RETRY_INTERVAL + 100);
drm_dp_i2c_msg_write_status_update(msg);
 
continue;
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index c239e6e24a10..2eae1aed2d26 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -61,6 +61,8 @@
 #define DP_AUX_I2C_REPLY_DEFER (0x2 << 2)
 #define DP_AUX_I2C_REPLY_MASK  (0x3 << 2)
 
+#define DP_AUX_RETRY_INTERVAL  500 /* us */
+
 /* AUX CH addresses */
 /* DPCD */
 #define DP_DPCD_REV 0x000
-- 
2.14.1

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


[PATCH 1/5] drm/vblank: Fix return type for drm_vblank_count()

2018-01-12 Thread Dhinakaran Pandiyan
drm_vblank_count() has a u32 type returning what is a 64-bit vblank count.
The effect of this is when drm_wait_vblank_ioctl() tries to widen the user
space requested vblank sequence using this clipped 32-bit count(when the
value is >= 2^32) as reference, the requested sequence remains a 32-bit
value and gets queued like that. However, the code that checks if the
requested sequence has passed compares this against the 64-bit vblank
count.

Cc: Keith Packard <kei...@keithp.com>
Cc: Michel Dänzer <mic...@daenzer.net>
Cc: Daniel Vetter <dan...@ffwll.ch>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 32d9bcf5be7f..768a8e44d99b 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -271,7 +271,7 @@ static void drm_update_vblank_count(struct drm_device *dev, 
unsigned int pipe,
store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
 }
 
-static u32 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
+static u64 drm_vblank_count(struct drm_device *dev, unsigned int pipe)
 {
struct drm_vblank_crtc *vblank = >vblank[pipe];
 
-- 
2.11.0

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


[PATCH 3/5] drm/vblank: Do not update vblank count if interrupts are already disabled.

2018-01-12 Thread Dhinakaran Pandiyan
Updating vblank counts requires register reads and these reads may not
return meaningful values if the device was in a low power state after
vblank interrupts were last disabled. So, update the count only if vblank
interrupts are enabled. Secondly, this means the registers should be read
before disabling vblank interrupts.

v2: Don't check vblank->enabled outside it's lock (Chris)

Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Michel Dänzer <mic...@daenzer.net>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index f2bf1f5dbaa5..2559d2d7b907 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -347,23 +347,25 @@ void drm_vblank_disable_and_save(struct drm_device *dev, 
unsigned int pipe)
spin_lock_irqsave(>vblank_time_lock, irqflags);
 
/*
-* Only disable vblank interrupts if they're enabled. This avoids
-* calling the ->disable_vblank() operation in atomic context with the
-* hardware potentially runtime suspended.
+* Update vblank count and disable vblank interrupts only if the
+* interrupts were enabled. This avoids calling the ->disable_vblank()
+* operation in atomic context with the hardware potentially runtime
+* suspended.
 */
-   if (vblank->enabled) {
-   __disable_vblank(dev, pipe);
-   vblank->enabled = false;
-   }
+   if (!vblank->enabled)
+   goto out;
 
/*
-* Always update the count and timestamp to maintain the
+* Update the count and timestamp to maintain the
 * appearance that the counter has been ticking all along until
 * this time. This makes the count account for the entire time
 * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
 */
drm_update_vblank_count(dev, pipe, false);
+   __disable_vblank(dev, pipe);
+   vblank->enabled = false;
 
+out:
spin_unlock_irqrestore(>vblank_time_lock, irqflags);
 }
 
-- 
2.11.0

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


[PATCH 5/5] drm/i915: Estimate and update missed vblanks.

2018-01-12 Thread Dhinakaran Pandiyan
The frame counter may have got reset between disabling and enabling vblank
interrupts due to DMC putting the hardware to DC5/6 state if PSR was
active. The frame counter also could have stalled if PSR is active in cases
where there is no DMC. The frame counter resetting as a user visible impact
of screen freezes. Use drm_vblank_restore() to compute missed vblanks
in the duration for which vblank interrupts are disabled. There's no need
particularly check if PSR was active in the interrupt disabled duration.

Enabling vblank interrupts wakes up the hardware from DC5/6 and prevents it
from going back again as long as the there are pending interrupts. So, we
don't have to explicity disallow DC5/6 after enabling vblank interrupts
to keep the counter running.

Let's not apply this to CHV for now, as enabling interrupts does not
prevent the hardware from activating PSR and thereby stalling the counter.

Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 3517c6548e2c..db3466ec6faa 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2956,6 +2956,9 @@ static int ironlake_enable_vblank(struct drm_device *dev, 
unsigned int pipe)
ilk_enable_display_irq(dev_priv, bit);
spin_unlock_irqrestore(_priv->irq_lock, irqflags);
 
+   if (HAS_PSR(dev_priv))
+   drm_vblank_restore(dev, pipe);
+
return 0;
 }
 
@@ -2968,6 +2971,9 @@ static int gen8_enable_vblank(struct drm_device *dev, 
unsigned int pipe)
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(_priv->irq_lock, irqflags);
 
+   if (HAS_PSR(dev_priv))
+   drm_vblank_restore(dev, pipe);
+
return 0;
 }
 
-- 
2.11.0

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


[PATCH 4/5] drm/vblank: Restoring vblank counts after device PM events.

2018-01-12 Thread Dhinakaran Pandiyan
The HW frame counter can get reset if device enters a low power state after
vblank interrupts were disabled. This messes up any following vblank count
update as a negative diff (huge unsigned diff) is calculated from the HW
frame counter change. We cannot ignore negative diffs altogther as there
could be legitimate wrap arounds. So, allow drivers to update vblank->count
with missed vblanks for the time interrupts were disabled. This is similar
to _crtc_vblank_on() except that vblanks interrupts are not enabled at the
end as this function is expected to be called from the driver
_enable_vblank() vfunc.

v2: drm_crtc_vblank_restore should take crtc as arg. (Chris)
Add docs and sprinkle some asserts.

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Michel Dänzer <mic...@daenzer.net>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 59 
 include/drm/drm_vblank.h |  2 ++
 2 files changed, 61 insertions(+)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 2559d2d7b907..2690966694f0 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1237,6 +1237,65 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_vblank_on);
 
+/**
+ * drm_vblank_restore - estimated vblanks using timestamps and update it.
+ *
+ * Power manamement features can cause frame counter resets between vblank
+ * disable and enable. Drivers can then use this function in their
+ * _crtc_funcs.enable_vblank implementation to estimate the vblanks since
+ * the last _crtc_funcs.disable_vblank.
+ *
+ * This function is the legacy version of drm_crtc_vblank_restore().
+ */
+void drm_vblank_restore(struct drm_device *dev, unsigned int pipe)
+{
+   ktime_t t_vblank;
+   struct drm_vblank_crtc *vblank;
+   int framedur_ns;
+   u64 diff_ns;
+   u32 cur_vblank, diff = 1;
+   int count = DRM_TIMESTAMP_MAXRETRIES;
+
+   if (WARN_ON(pipe >= dev->num_crtcs))
+   return;
+
+   assert_spin_locked(>vbl_lock);
+   assert_spin_locked(>vblank_time_lock);
+
+   vblank = >vblank[pipe];
+   WARN_ONCE((drm_debug & DRM_UT_VBL) && !vblank->framedur_ns,
+ "Cannot compute missed vblanks without frame duration\n");
+   framedur_ns = vblank->framedur_ns;
+
+   do {
+   cur_vblank = __get_vblank_counter(dev, pipe);
+   drm_get_last_vbltimestamp(dev, pipe, _vblank, false);
+   } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+
+   diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
+   if (framedur_ns)
+   diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
+
+
+   DRM_DEBUG_VBL("missed %d vblanks in %lld ns, frame duration=%d ns, 
hw_diff=%d\n",
+ diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
+   store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
+}
+EXPORT_SYMBOL(drm_vblank_restore);
+
+/**
+ * drm_crtc_vblank_restore - estimate vblanks using timestamps and update it.
+ * Power manamement features can cause frame counter resets between vblank
+ * disable and enable. Drivers can then use this function in their
+ * _crtc_funcs.enable_vblank implementation to estimate the vblanks since
+ * the last _crtc_funcs.disable_vblank.
+ */
+void drm_crtc_vblank_restore(struct drm_crtc *crtc)
+{
+   drm_vblank_restore(crtc->dev, drm_crtc_index(crtc));
+}
+EXPORT_SYMBOL(drm_crtc_vblank_restore);
+
 static void drm_legacy_vblank_pre_modeset(struct drm_device *dev,
  unsigned int pipe)
 {
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index a4c3b0a0a197..16d46e2a6854 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -180,6 +180,8 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc);
 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 void drm_crtc_vblank_on(struct drm_crtc *crtc);
 u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+void drm_vblank_restore(struct drm_device *dev, unsigned int pipe);
+void drm_crtc_vblank_restore(struct drm_crtc *crtc);
 
 bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
   unsigned int pipe, int *max_error,
-- 
2.11.0

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


[PATCH 2/5] drm/vblank: Fix data type width for drm_crtc_arm_vblank_event()

2018-01-12 Thread Dhinakaran Pandiyan
Now that drm_vblank_count() returns all bits of the vblank count, update
drm_crtc_arm_vblank_event() so that it queues the correct sequence.
Otherwise, this leads to prolonged waits for a vblank sequence when the
current count is >=2^32.

Cc: Keith Packard <kei...@keithp.com>
Cc: Michel Dänzer <mic...@daenzer.net>
Cc: Daniel Vetter <dan...@ffwll.ch>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 4 ++--
 include/drm/drm_vblank.h | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 768a8e44d99b..f2bf1f5dbaa5 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -292,11 +292,11 @@ static u64 drm_vblank_count(struct drm_device *dev, 
unsigned int pipe)
  * This is mostly useful for hardware that can obtain the scanout position, but
  * doesn't have a hardware frame counter.
  */
-u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
+u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
unsigned int pipe = drm_crtc_index(crtc);
-   u32 vblank;
+   u64 vblank;
unsigned long flags;
 
WARN_ONCE(drm_debug & DRM_UT_VBL && !dev->driver->get_vblank_timestamp,
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 848b463a0af5..a4c3b0a0a197 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -179,7 +179,7 @@ void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
 void drm_crtc_vblank_off(struct drm_crtc *crtc);
 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 void drm_crtc_vblank_on(struct drm_crtc *crtc);
-u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+u64 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
 
 bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
   unsigned int pipe, int *max_error,
-- 
2.11.0

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


[PATCH] drm/dp: Power cycle display if LINK_ADDRESS fails.

2017-12-20 Thread Dhinakaran Pandiyan
Occasionally there are LINK_ADDRESS sideband messages timing out with the
Lenovo MST dock + Dell MST monitor(w/ in-built branch) setup I have. These
failures lead to the display not coming up on boot. Power cycling the port
corresponding to the MST monitor's branch device and resending the message
fixes the issue. I am not entirely sure if this is specific to my setup.
However, as the power state is toggled conditionally on LINK_ADDRESS
timeouts, this should not affect the working cases.

Cc: Lyude <ly...@redhat.com>
Cc: Dave Airlie <airl...@redhat.com>
Cc: Jani Nikula <jani.nik...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 70dcfa58d3c2..e06defcdcf18 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -1596,8 +1596,9 @@ static void drm_dp_send_link_address(struct 
drm_dp_mst_topology_mgr *mgr,
int len;
struct drm_dp_sideband_msg_tx *txmsg;
int ret;
+   int attempts = 5;
 
-   txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+retry: txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
if (!txmsg)
return;
 
@@ -1635,9 +1636,17 @@ static void drm_dp_send_link_address(struct 
drm_dp_mst_topology_mgr *mgr,
}
(*mgr->cbs->hotplug)(mgr);
}
+   } else if (attempts--) {
+   kfree(txmsg);
+   drm_dp_send_power_updown_phy(mstb->mgr, mstb->port_parent,
+false);
+   drm_dp_send_power_updown_phy(mstb->mgr, mstb->port_parent,
+true);
+   DRM_DEBUG_KMS("link address failed %d, retrying\n", ret);
+   goto retry;
} else {
mstb->link_address_sent = false;
-   DRM_DEBUG_KMS("link address failed %d\n", ret);
+   DRM_DEBUG_KMS("link address failed %d, giving up\n", ret);
}
 
kfree(txmsg);
-- 
2.11.0

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


[PATCH v2 7/8] drm/i915: Introduce a non-blocking power domain for vblank interrupts

2017-12-18 Thread Dhinakaran Pandiyan
When DC states are enabled and PSR is active, the hardware enters DC5/DC6
states resulting in frame counter resets. The frame counter resets mess
up the vblank counting logic. In order to disable DC states when
vblank interrupts are required and to disallow DC states when vblanks
interrupts are already enabled, introduce a new VBLANK power domain.
Since this power domain reference needs to be acquired and released in
atomic context, _vblank_get() and _vblank_put() methods skip the
power_domain mutex.

v2: Fix deadlock by switching irqsave spinlock.
Implement atomic version of get_if_enabled.
Modify power_domain_verify_state to check power well use count and
enabled status atomically.
Rewrite of intel_power_well_{get,put}

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |  18 
 drivers/gpu/drm/i915/intel_drv.h|   3 +
 drivers/gpu/drm/i915/intel_runtime_pm.c | 184 +---
 3 files changed, 192 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index ddadeb9eaf49..db597c5ebaed 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -397,6 +397,7 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_C,
POWER_DOMAIN_AUX_D,
POWER_DOMAIN_GMBUS,
+   POWER_DOMAIN_VBLANK,
POWER_DOMAIN_MODESET,
POWER_DOMAIN_GT_IRQ,
POWER_DOMAIN_INIT,
@@ -1476,6 +1477,23 @@ struct i915_power_well {
bool has_fuses:1;
} hsw;
};
+
+   /* Lock to serialize access to count, hw_enabled and ops, used for
+* power wells that have supports_atomix_ctx set to True.
+*/
+   spinlock_t lock;
+
+   /* Indicates that the get/put methods for this power well can be called
+* in atomic contexts, requires .ops to not sleep. This is valid
+* only for the DC_OFF power well currently.
+*/
+   bool supports_atomic_ctx;
+
+   /* DC_OFF power well was disabled since the last time vblanks were
+* disabled.
+*/
+   bool dc_off_disabled;
+
const struct i915_power_well_ops *ops;
 };
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 48676e99316e..6822118f3c4d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1798,6 +1798,9 @@ bool intel_display_power_get_if_enabled(struct 
drm_i915_private *dev_priv,
enum intel_display_power_domain domain);
 void intel_display_power_put(struct drm_i915_private *dev_priv,
 enum intel_display_power_domain domain);
+void intel_display_power_vblank_get(struct drm_i915_private *dev_priv,
+   bool *needs_restore);
+void intel_display_power_vblank_put(struct drm_i915_private *dev_priv);
 
 static inline void
 assert_rpm_device_not_suspended(struct drm_i915_private *dev_priv)
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 992caec1fbc4..fc6812ed6137 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -56,6 +56,19 @@ static struct i915_power_well *
 lookup_power_well(struct drm_i915_private *dev_priv,
  enum i915_power_well_id power_well_id);
 
+/* Optimize for the case when this is called from atomic contexts,
+ * although the case is unlikely.
+ */
+#define power_well_lock(power_well, flags) do {\
+   if (likely(power_well->supports_atomic_ctx))\
+   spin_lock_irqsave(_well->lock, flags);\
+   } while (0)
+
+#define power_well_unlock(power_well, flags) do {  \
+   if (likely(power_well->supports_atomic_ctx))\
+   spin_unlock_irqrestore(_well->lock, flags);   \
+   } while (0)
+
 const char *
 intel_display_power_domain_str(enum intel_display_power_domain domain)
 {
@@ -126,6 +139,8 @@ intel_display_power_domain_str(enum 
intel_display_power_domain domain)
return "AUX_D";
case POWER_DOMAIN_GMBUS:
return "GMBUS";
+   case POWER_DOMAIN_VBLANK:
+   return "VBLANK";
case POWER_DOMAIN_INIT:
return "INIT";
case POWER_DOMAIN_MODESET:
@@ -141,6 +156,9 @@ intel_display_power_domain_str(enum 
intel_display_power_domain domain)
 static void intel_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well)
 {
+   if (power_well->supports_atomic_ctx)
+   assert_spin

[PATCH v2 6/8] drm/i915: Use an atomic_t array to track power domain use count.

2017-12-18 Thread Dhinakaran Pandiyan
Convert the power_domains->domain_use_count array that tracks per-domain
use count to atomic_t type. This is needed to be able to read/write the use
counts outside of the power domain mutex.

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.h |  2 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 11 +--
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 1a7b28f62570..1f1d9162f2c2 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2764,7 +2764,7 @@ static int i915_power_domain_info(struct seq_file *m, 
void *unused)
for_each_power_domain(power_domain, power_well->domains)
seq_printf(m, "  %-23s %d\n",
 intel_display_power_domain_str(power_domain),
-power_domains->domain_use_count[power_domain]);
+
atomic_read(_domains->domain_use_count[power_domain]));
}
 
mutex_unlock(_domains->lock);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1e4e613e7b41..ddadeb9eaf49 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1489,7 +1489,7 @@ struct i915_power_domains {
int power_well_count;
 
struct mutex lock;
-   int domain_use_count[POWER_DOMAIN_NUM];
+   atomic_t domain_use_count[POWER_DOMAIN_NUM];
struct i915_power_well *power_wells;
 };
 
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 96ab74f3d101..992caec1fbc4 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1453,7 +1453,7 @@ __intel_display_power_get_domain(struct drm_i915_private 
*dev_priv,
for_each_power_domain_well(dev_priv, power_well, BIT_ULL(domain))
intel_power_well_get(dev_priv, power_well);
 
-   power_domains->domain_use_count[domain]++;
+   atomic_inc(_domains->domain_use_count[domain]);
 }
 
 /**
@@ -1539,10 +1539,9 @@ void intel_display_power_put(struct drm_i915_private 
*dev_priv,
 
mutex_lock(_domains->lock);
 
-   WARN(!power_domains->domain_use_count[domain],
-"Use count on domain %s is already zero\n",
+   WARN(atomic_dec_return(_domains->domain_use_count[domain]) < 0,
+"Use count on domain %s was already zero\n",
 intel_display_power_domain_str(domain));
-   power_domains->domain_use_count[domain]--;
 
for_each_power_domain_well_rev(dev_priv, power_well, BIT_ULL(domain))
intel_power_well_put(dev_priv, power_well);
@@ -3049,7 +3048,7 @@ static void intel_power_domains_dump_info(struct 
drm_i915_private *dev_priv)
for_each_power_domain(domain, power_well->domains)
DRM_DEBUG_DRIVER("  %-23s %d\n",
 intel_display_power_domain_str(domain),
-
power_domains->domain_use_count[domain]);
+
atomic_read(_domains->domain_use_count[domain]));
}
 }
 
@@ -3092,7 +3091,7 @@ void intel_power_domains_verify_state(struct 
drm_i915_private *dev_priv)
 
domains_count = 0;
for_each_power_domain(domain, power_well->domains)
-   domains_count += 
power_domains->domain_use_count[domain];
+   domains_count += 
atomic_read(_domains->domain_use_count[domain]);
 
if (power_well->count != domains_count) {
DRM_ERROR("power well %s refcount/domain refcount 
mismatch "
-- 
2.11.0

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


[PATCH v2 3/8] drm/i915/psr: Avoid initializing PSR if there is no sink support.

2017-12-18 Thread Dhinakaran Pandiyan
DPCD read for the eDP is complete by the time intel_psr_init() is
called, which means we can avoid initializing PSR structures and state
if there is no sink support.

Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 7 ++-
 drivers/gpu/drm/i915/intel_psr.c| 9 +
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 64e5a263458c..1a7b28f62570 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2532,14 +2532,19 @@ static int i915_edp_psr_status(struct seq_file *m, void 
*data)
u32 stat[3];
enum pipe pipe;
bool enabled = false;
+   bool sink_support;
 
if (!HAS_PSR(dev_priv))
return -ENODEV;
 
+   sink_support = dev_priv->psr.sink_support;
+   seq_printf(m, "Sink_Support: %s\n", yesno(sink_support));
+   if (!sink_support)
+   return 0;
+
intel_runtime_pm_get(dev_priv);
 
mutex_lock(_priv->psr.lock);
-   seq_printf(m, "Sink_Support: %s\n", yesno(dev_priv->psr.sink_support));
seq_printf(m, "Enabled: %s\n", yesno((bool)dev_priv->psr.enabled));
seq_printf(m, "Active: %s\n", yesno(dev_priv->psr.active));
seq_printf(m, "Busy frontbuffer bits: 0x%03x\n",
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 76339cf387cb..095e0a5a8574 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -503,6 +503,9 @@ void intel_psr_enable(struct intel_dp *intel_dp,
if (!crtc_state->has_psr)
return;
 
+   if (WARN_ON(!CAN_PSR(dev_priv)))
+   return;
+
WARN_ON(dev_priv->drrs.dp);
mutex_lock(_priv->psr.lock);
if (dev_priv->psr.enabled) {
@@ -633,6 +636,9 @@ void intel_psr_disable(struct intel_dp *intel_dp,
if (!old_crtc_state->has_psr)
return;
 
+   if (WARN_ON(!CAN_PSR(dev_priv)))
+   return;
+
mutex_lock(_priv->psr.lock);
if (!dev_priv->psr.enabled) {
mutex_unlock(_priv->psr.lock);
@@ -913,6 +919,9 @@ void intel_psr_init(struct drm_i915_private *dev_priv)
dev_priv->psr_mmio_base = IS_HASWELL(dev_priv) ?
HSW_EDP_PSR_BASE : BDW_EDP_PSR_BASE;
 
+   if (!dev_priv->psr.sink_support)
+   return;
+
/* Per platform default: all disabled. */
if (i915_modparams.enable_psr == -1)
i915_modparams.enable_psr = 0;
-- 
2.11.0

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


[PATCH v2 8/8] drm/i915: Use the vblank power domain disallow or disable DC states.

2017-12-18 Thread Dhinakaran Pandiyan
Disable DC states before enabling vblank interrupts and conversely
enable DC states after disabling. Since the frame counter may have got
reset between disabling and enabling, use drm_crtc_vblank_restore() to
compute the missed vblanks.

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 3517c6548e2c..88b4ceac55d0 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2963,6 +2963,11 @@ static int gen8_enable_vblank(struct drm_device *dev, 
unsigned int pipe)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
unsigned long irqflags;
+   bool needs_restore = false;
+
+   intel_display_power_vblank_get(dev_priv, _restore);
+   if (needs_restore)
+   drm_crtc_vblank_restore(dev, pipe);
 
spin_lock_irqsave(_priv->irq_lock, irqflags);
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
@@ -3015,6 +3020,7 @@ static void gen8_disable_vblank(struct drm_device *dev, 
unsigned int pipe)
spin_lock_irqsave(_priv->irq_lock, irqflags);
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(_priv->irq_lock, irqflags);
+   intel_display_power_vblank_put(dev_priv);
 }
 
 static void ibx_irq_reset(struct drm_i915_private *dev_priv)
-- 
2.11.0

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


[PATCH v2 1/8] drm/i915/psr: Kill psr.source_ok flag.

2017-12-18 Thread Dhinakaran Pandiyan
This flag has become redundant since
commit 4d90f2d507ab ("drm/i915: Start tracking PSR state in crtc state")
It is set at the same place as psr.enabled, which is also exposed via
debugfs.

Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 1 -
 drivers/gpu/drm/i915/i915_drv.h | 1 -
 drivers/gpu/drm/i915/intel_psr.c| 2 --
 3 files changed, 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 0ddce72552bf..64e5a263458c 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2540,7 +2540,6 @@ static int i915_edp_psr_status(struct seq_file *m, void 
*data)
 
mutex_lock(_priv->psr.lock);
seq_printf(m, "Sink_Support: %s\n", yesno(dev_priv->psr.sink_support));
-   seq_printf(m, "Source_OK: %s\n", yesno(dev_priv->psr.source_ok));
seq_printf(m, "Enabled: %s\n", yesno((bool)dev_priv->psr.enabled));
seq_printf(m, "Active: %s\n", yesno(dev_priv->psr.active));
seq_printf(m, "Busy frontbuffer bits: 0x%03x\n",
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 1aba5657f5f0..1e4e613e7b41 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1199,7 +1199,6 @@ struct i915_drrs {
 struct i915_psr {
struct mutex lock;
bool sink_support;
-   bool source_ok;
struct intel_dp *enabled;
bool active;
struct delayed_work work;
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index a1ad85fa5c1a..c4d75e82a1df 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -522,8 +522,6 @@ void intel_psr_enable(struct intel_dp *intel_dp,
}
 
dev_priv->psr.psr2_support = crtc_state->has_psr2;
-   dev_priv->psr.source_ok = true;
-
dev_priv->psr.busy_frontbuffer_bits = 0;
 
dev_priv->psr.setup_vsc(intel_dp, crtc_state);
-- 
2.11.0

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


[PATCH v2 0/8] Fix PSR-vblank-DMC interaction

2017-12-18 Thread Dhinakaran Pandiyan
The first 3 patches are minor PSR improvements. The last 5 introduce a new
power domain to disable DC states when vblanks are required. The tricky
part is to enable and disable the DC_OFF power well in atomic context. I
have addressed the locking issues that CI caught in the last revision.

Dhinakaran Pandiyan (8):
  drm/i915/psr: Kill psr.source_ok flag.
  drm/i915/psr: CAN_PSR() macro to check for PSR source and sink
support.
  drm/i915/psr: Avoid initializing PSR if there is no sink support.
  drm/vblank: Do not update vblank counts if vblanks are already
disabled.
  drm/vblank: Restoring vblank counts after device runtime PM events.
  drm/i915: Use an atomic_t array to track power domain use count.
  drm/i915: Introduce a non-blocking power domain for vblank interrupts
  drm/i915: Use the vblank power domain disallow or disable DC states.

 drivers/gpu/drm/drm_vblank.c|  56 ++---
 drivers/gpu/drm/i915/i915_debugfs.c |  10 +-
 drivers/gpu/drm/i915/i915_drv.h |  21 +++-
 drivers/gpu/drm/i915/i915_irq.c |   6 +
 drivers/gpu/drm/i915/intel_drv.h|   4 +
 drivers/gpu/drm/i915/intel_psr.c|  30 +++--
 drivers/gpu/drm/i915/intel_runtime_pm.c | 195 
 include/drm/drm_vblank.h|   1 +
 8 files changed, 268 insertions(+), 55 deletions(-)

-- 
2.11.0

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


[PATCH v2 5/8] drm/vblank: Restoring vblank counts after device runtime PM events.

2017-12-18 Thread Dhinakaran Pandiyan
The HW frame counter can get reset when devices enters low power
states and this messes up any following vblank count updates. So, compute
the missed vblank interrupts for that low power state duration using time
stamps. This is similar to _crtc_vblank_on() except that it doesn't enable
vblank interrupts because this function is expected to be called from
the driver _enable_vblank() vfunc.

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 33 +
 include/drm/drm_vblank.h |  1 +
 2 files changed, 34 insertions(+)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 7eee82c06ed8..494e2cff6e55 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1230,6 +1230,39 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_vblank_on);
 
+void drm_crtc_vblank_restore(struct drm_device *dev, unsigned int pipe)
+{
+   ktime_t t_vblank;
+   struct drm_vblank_crtc *vblank;
+   int framedur_ns;
+   u64 diff_ns;
+   u32 cur_vblank, diff = 1;
+   int count = DRM_TIMESTAMP_MAXRETRIES;
+
+   if (WARN_ON(pipe >= dev->num_crtcs))
+   return;
+
+   vblank = >vblank[pipe];
+   WARN_ONCE((drm_debug & DRM_UT_VBL) && !vblank->framedur_ns,
+ "Cannot compute missed vblanks without frame duration\n");
+   framedur_ns = vblank->framedur_ns;
+
+   do {
+   cur_vblank = __get_vblank_counter(dev, pipe);
+   drm_get_last_vbltimestamp(dev, pipe, _vblank, false);
+   } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+
+   diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
+   if (framedur_ns)
+   diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
+
+
+   DRM_DEBUG_VBL("missed %d vblanks in %lld ns, frame duration=%d ns, 
hw_diff=%d\n",
+ diff, diff_ns, framedur_ns, cur_vblank - vblank->last);
+   store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_restore);
+
 static void drm_legacy_vblank_pre_modeset(struct drm_device *dev,
  unsigned int pipe)
 {
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 848b463a0af5..aafcbef91bd7 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -180,6 +180,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc);
 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 void drm_crtc_vblank_on(struct drm_crtc *crtc);
 u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+void drm_crtc_vblank_restore(struct drm_device *dev, unsigned int pipe);
 
 bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
   unsigned int pipe, int *max_error,
-- 
2.11.0

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


[PATCH v2 2/8] drm/i915/psr: CAN_PSR() macro to check for PSR source and sink support.

2017-12-18 Thread Dhinakaran Pandiyan
The global variable dev_priv->psr.sink_support is set if an eDP sink
supports PSR. Use this instead of redoing the check with is_edp_psr().
Combine source and sink support checks into a macro that can be used to
return early from psr_{invalidate, single_frame_update, flush}.

Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h |  1 +
 drivers/gpu/drm/i915/intel_psr.c | 19 ---
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 30f791f89d64..48676e99316e 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1760,6 +1760,7 @@ static inline void 
intel_backlight_device_unregister(struct intel_connector *con
 
 
 /* intel_psr.c */
+#define CAN_PSR(dev_priv) (HAS_PSR(dev_priv) && dev_priv->psr.sink_support)
 void intel_psr_enable(struct intel_dp *intel_dp,
  const struct intel_crtc_state *crtc_state);
 void intel_psr_disable(struct intel_dp *intel_dp,
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index c4d75e82a1df..76339cf387cb 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -56,14 +56,6 @@
 #include "intel_drv.h"
 #include "i915_drv.h"
 
-static bool is_edp_psr(struct intel_dp *intel_dp)
-{
-   if (!intel_dp_is_edp(intel_dp))
-   return false;
-
-   return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
-}
-
 static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
 {
struct drm_i915_private *dev_priv = to_i915(dev);
@@ -358,10 +350,7 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
_state->base.adjusted_mode;
int psr_setup_time;
 
-   if (!HAS_PSR(dev_priv))
-   return;
-
-   if (!is_edp_psr(intel_dp))
+   if (!CAN_PSR(dev_priv))
return;
 
if (!i915_modparams.enable_psr) {
@@ -794,7 +783,7 @@ void intel_psr_single_frame_update(struct drm_i915_private 
*dev_priv,
enum pipe pipe;
u32 val;
 
-   if (!HAS_PSR(dev_priv))
+   if (!CAN_PSR(dev_priv))
return;
 
/*
@@ -843,7 +832,7 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv,
struct drm_crtc *crtc;
enum pipe pipe;
 
-   if (!HAS_PSR(dev_priv))
+   if (!CAN_PSR(dev_priv))
return;
 
mutex_lock(_priv->psr.lock);
@@ -883,7 +872,7 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
struct drm_crtc *crtc;
enum pipe pipe;
 
-   if (!HAS_PSR(dev_priv))
+   if (!CAN_PSR(dev_priv))
return;
 
mutex_lock(_priv->psr.lock);
-- 
2.11.0

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


[PATCH 2/5] drm/vblank: Restoring vblank counts after device runtime PM events.

2017-12-06 Thread Dhinakaran Pandiyan
The HW frame counter can get reset when devices enters low power
states and this messes up any following vblank count updates. So, compute
the missed vblank interrupts for that low power state duration using time
stamps. This is similar to _crtc_vblank_on() except that it doesn't enable
vblank interrupts because this function is expected to be called from
the driver _enable_vblank() vfunc.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 30 ++
 include/drm/drm_vblank.h |  1 +
 2 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 7eee82c06ed8..69d537cea149 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -1230,6 +1230,36 @@ void drm_crtc_vblank_on(struct drm_crtc *crtc)
 }
 EXPORT_SYMBOL(drm_crtc_vblank_on);
 
+void drm_crtc_vblank_restore(struct drm_device *dev, unsigned int pipe)
+{
+   ktime_t t_vblank;
+   struct drm_vblank_crtc *vblank;
+   int framedur_ns;
+   u64 diff_ns;
+   u32 cur_vblank, diff = 1;
+   int count = DRM_TIMESTAMP_MAXRETRIES;
+
+   if (WARN_ON(pipe >= dev->num_crtcs))
+   return;
+
+   vblank = >vblank[pipe];
+   framedur_ns = vblank->framedur_ns;
+
+   do {
+   cur_vblank = __get_vblank_counter(dev, pipe);
+   drm_get_last_vbltimestamp(dev, pipe, _vblank, false);
+   } while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
+
+   diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
+   if (framedur_ns)
+   diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
+
+   DRM_DEBUG_VBL("computing missed vblanks %lld/%d=%d after HW counter 
reset hw_diff=%d\n",
+ diff_ns, framedur_ns, diff, cur_vblank - vblank->last);
+   store_vblank(dev, pipe, diff, t_vblank, cur_vblank);
+}
+EXPORT_SYMBOL(drm_crtc_vblank_restore);
+
 static void drm_legacy_vblank_pre_modeset(struct drm_device *dev,
  unsigned int pipe)
 {
diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
index 848b463a0af5..aafcbef91bd7 100644
--- a/include/drm/drm_vblank.h
+++ b/include/drm/drm_vblank.h
@@ -180,6 +180,7 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc);
 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
 void drm_crtc_vblank_on(struct drm_crtc *crtc);
 u32 drm_crtc_accurate_vblank_count(struct drm_crtc *crtc);
+void drm_crtc_vblank_restore(struct drm_device *dev, unsigned int pipe);
 
 bool drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
   unsigned int pipe, int *max_error,
-- 
2.11.0

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


[PATCH 5/5] drm/i915: Use the vblank power domain disallow or disable DC states.

2017-12-06 Thread Dhinakaran Pandiyan
Disable DC states before enabling vblank interrupts and conversely
enable DC states after disabling. Since the frame counter may have got
reset between disabling and enabling, use drm_crtc_vblank_restore() to
compute the missed vblanks.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 7cac07db89b9..c595b934e2dc 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2964,6 +2964,9 @@ static int gen8_enable_vblank(struct drm_device *dev, 
unsigned int pipe)
struct drm_i915_private *dev_priv = to_i915(dev);
unsigned long irqflags;
 
+   if (intel_display_power_vblank_get(dev_priv))
+   drm_crtc_vblank_restore(dev, pipe);
+
spin_lock_irqsave(_priv->irq_lock, irqflags);
bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(_priv->irq_lock, irqflags);
@@ -3015,6 +3018,7 @@ static void gen8_disable_vblank(struct drm_device *dev, 
unsigned int pipe)
spin_lock_irqsave(_priv->irq_lock, irqflags);
bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
spin_unlock_irqrestore(_priv->irq_lock, irqflags);
+   intel_display_power_vblank_put(dev_priv);
 }
 
 static void ibx_irq_reset(struct drm_i915_private *dev_priv)
-- 
2.11.0

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


[PATCH 1/5] drm/vblank: Do not update vblank counts if vblanks are already disabled.

2017-12-06 Thread Dhinakaran Pandiyan
Updating the vblank counts requires register reads and these reads may not
return meaningful values after the vblank interrupts are disabled as the
device may go to low power state. An additional change would be to allow
the driver to save the vblank counts before entering a low power state, but
that's for the future.

Also, disable vblanks after reading the HW counter in the case where
_crtc_vblank_off() is disabling vblanks.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 23 +--
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 32d9bcf5be7f..7eee82c06ed8 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -347,23 +347,14 @@ void drm_vblank_disable_and_save(struct drm_device *dev, 
unsigned int pipe)
spin_lock_irqsave(>vblank_time_lock, irqflags);
 
/*
-* Only disable vblank interrupts if they're enabled. This avoids
-* calling the ->disable_vblank() operation in atomic context with the
-* hardware potentially runtime suspended.
-*/
-   if (vblank->enabled) {
-   __disable_vblank(dev, pipe);
-   vblank->enabled = false;
-   }
-
-   /*
-* Always update the count and timestamp to maintain the
+* Update the count and timestamp to maintain the
 * appearance that the counter has been ticking all along until
 * this time. This makes the count account for the entire time
 * between drm_crtc_vblank_on() and drm_crtc_vblank_off().
 */
drm_update_vblank_count(dev, pipe, false);
-
+   __disable_vblank(dev, pipe);
+   vblank->enabled = false;
spin_unlock_irqrestore(>vblank_time_lock, irqflags);
 }
 
@@ -1122,8 +1113,12 @@ void drm_crtc_vblank_off(struct drm_crtc *crtc)
  pipe, vblank->enabled, vblank->inmodeset);
 
/* Avoid redundant vblank disables without previous
-* drm_crtc_vblank_on(). */
-   if (drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset)
+* drm_crtc_vblank_on() and only disable them if they're enabled. This
+* avoids calling the ->disable_vblank() operation in atomic context
+* with the hardware potentially runtime suspended.
+*/
+   if ((drm_core_check_feature(dev, DRIVER_ATOMIC) || !vblank->inmodeset) 
&&
+   vblank->enabled)
drm_vblank_disable_and_save(dev, pipe);
 
wake_up(>queue);
-- 
2.11.0

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


[PATCH 3/5] drm/i915: Use an atomic_t array to track power domain use count.

2017-12-06 Thread Dhinakaran Pandiyan
Convert the power_domains->domain_use_count array that tracks per-domain
use count to atomic_t type. This is needed to be able to read/write the use
counts outside of the power domain mutex.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c |  2 +-
 drivers/gpu/drm/i915/i915_drv.h |  2 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 11 +--
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c 
b/drivers/gpu/drm/i915/i915_debugfs.c
index 28294470ae31..2a4ed54688d7 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -2805,7 +2805,7 @@ static int i915_power_domain_info(struct seq_file *m, 
void *unused)
for_each_power_domain(power_domain, power_well->domains)
seq_printf(m, "  %-23s %d\n",
 intel_display_power_domain_str(power_domain),
-power_domains->domain_use_count[power_domain]);
+
atomic_read(_domains->domain_use_count[power_domain]));
}
 
mutex_unlock(_domains->lock);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 594fd14e66c5..18d42885205b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1489,7 +1489,7 @@ struct i915_power_domains {
int power_well_count;
 
struct mutex lock;
-   int domain_use_count[POWER_DOMAIN_NUM];
+   atomic_t domain_use_count[POWER_DOMAIN_NUM];
struct i915_power_well *power_wells;
 };
 
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 8315499452dc..f88f2c070c5f 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1451,7 +1451,7 @@ __intel_display_power_get_domain(struct drm_i915_private 
*dev_priv,
for_each_power_domain_well(dev_priv, power_well, BIT_ULL(domain))
intel_power_well_get(dev_priv, power_well);
 
-   power_domains->domain_use_count[domain]++;
+   atomic_inc(_domains->domain_use_count[domain]);
 }
 
 /**
@@ -1537,10 +1537,9 @@ void intel_display_power_put(struct drm_i915_private 
*dev_priv,
 
mutex_lock(_domains->lock);
 
-   WARN(!power_domains->domain_use_count[domain],
-"Use count on domain %s is already zero\n",
+   WARN(atomic_dec_return(_domains->domain_use_count[domain]) < 0,
+"Use count on domain %s was already zero\n",
 intel_display_power_domain_str(domain));
-   power_domains->domain_use_count[domain]--;
 
for_each_power_domain_well_rev(dev_priv, power_well, BIT_ULL(domain))
intel_power_well_put(dev_priv, power_well);
@@ -3044,7 +3043,7 @@ static void intel_power_domains_dump_info(struct 
drm_i915_private *dev_priv)
for_each_power_domain(domain, power_well->domains)
DRM_DEBUG_DRIVER("  %-23s %d\n",
 intel_display_power_domain_str(domain),
-
power_domains->domain_use_count[domain]);
+
atomic_read(_domains->domain_use_count[domain]));
}
 }
 
@@ -3087,7 +3086,7 @@ void intel_power_domains_verify_state(struct 
drm_i915_private *dev_priv)
 
domains_count = 0;
for_each_power_domain(domain, power_well->domains)
-   domains_count += 
power_domains->domain_use_count[domain];
+   domains_count += 
atomic_read(_domains->domain_use_count[domain]);
 
if (power_well->count != domains_count) {
DRM_ERROR("power well %s refcount/domain refcount 
mismatch "
-- 
2.11.0

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


[PATCH 4/5] drm/i915: Introduce a non-blocking power domain for vblank interrupts

2017-12-06 Thread Dhinakaran Pandiyan
When DC states are enabled and PSR is active, the hardware enters DC5/DC6
states resulting in frame counter resets. The frame counter resets mess
up the vblank counting logic. So in order to disable DC states when
vblank interrupts are required and to disallow DC states when vblanks
interrupts are already enabled, introduce a new power domain. Since this
power domain reference needs to be acquired and released in atomic context,
the corresponding _get() and _put() methods skip the power_domain mutex.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |   5 ++
 drivers/gpu/drm/i915/intel_drv.h|   3 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 125 +++-
 3 files changed, 128 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 18d42885205b..ba9107ec1ed1 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -397,6 +397,7 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_C,
POWER_DOMAIN_AUX_D,
POWER_DOMAIN_GMBUS,
+   POWER_DOMAIN_VBLANK,
POWER_DOMAIN_MODESET,
POWER_DOMAIN_INIT,
 
@@ -1475,6 +1476,10 @@ struct i915_power_well {
bool has_vga:1;
bool has_fuses:1;
} hsw;
+   struct {
+   spinlock_t lock;
+   bool was_disabled;
+   } dc_off;
};
const struct i915_power_well_ops *ops;
 };
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 30f791f89d64..93ca503f18bb 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1865,7 +1865,8 @@ void chv_phy_powergate_lanes(struct intel_encoder 
*encoder,
 bool override, unsigned int mask);
 bool chv_phy_powergate_ch(struct drm_i915_private *dev_priv, enum dpio_phy phy,
  enum dpio_channel ch, bool override);
-
+bool intel_display_power_vblank_get(struct drm_i915_private *dev_priv);
+void intel_display_power_vblank_put(struct drm_i915_private *dev_priv);
 
 /* intel_pm.c */
 void intel_init_clock_gating(struct drm_i915_private *dev_priv);
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c 
b/drivers/gpu/drm/i915/intel_runtime_pm.c
index f88f2c070c5f..f1807bd74242 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -126,6 +126,8 @@ intel_display_power_domain_str(enum 
intel_display_power_domain domain)
return "AUX_D";
case POWER_DOMAIN_GMBUS:
return "GMBUS";
+   case POWER_DOMAIN_VBLANK:
+   return "VBLANK";
case POWER_DOMAIN_INIT:
return "INIT";
case POWER_DOMAIN_MODESET:
@@ -196,10 +198,17 @@ bool __intel_display_power_is_enabled(struct 
drm_i915_private *dev_priv,
if (power_well->always_on)
continue;
 
-   if (!power_well->hw_enabled) {
+   if (power_well->id == SKL_DISP_PW_DC_OFF)
+   spin_lock(_well->dc_off.lock);
+
+   if (!power_well->hw_enabled)
is_enabled = false;
+
+   if (power_well->id == SKL_DISP_PW_DC_OFF)
+   spin_unlock(_well->dc_off.lock);
+
+   if (!is_enabled)
break;
-   }
}
 
return is_enabled;
@@ -724,6 +733,7 @@ static void gen9_dc_off_power_well_disable(struct 
drm_i915_private *dev_priv,
skl_enable_dc6(dev_priv);
else if (dev_priv->csr.allowed_dc_mask & DC_STATE_EN_UPTO_DC5)
gen9_enable_dc5(dev_priv);
+   power_well->dc_off.was_disabled = true;
 }
 
 static void i9xx_power_well_sync_hw_noop(struct drm_i915_private *dev_priv,
@@ -1441,6 +1451,77 @@ static void chv_pipe_power_well_disable(struct 
drm_i915_private *dev_priv,
chv_set_pipe_power_well(dev_priv, power_well, false);
 }
 
+/**
+ * intel_display_power_vblank_get - acquire a VBLANK power domain reference 
atomically
+ * @dev_priv: i915 device instance
+ *
+ * This function gets a POWER_DOMAIN_VBLANK reference without blocking and
+ * returns true if the DC_OFF power well was disabled since this function was
+ * called the last time.
+ */
+bool intel_display_power_vblank_get(struct drm_i915_private *dev_priv)
+{
+   struct i915_power_domains *power_domains = _priv->power_domains;
+   struct i915_power_well *power_well;
+   bool needs_restore = false;
+
+   if (!HAS_CSR(dev_priv) || !dev_priv->psr.source_ok)
+   return false;
+
+   /* The corresponding CRTC should be active by the time driver turns on
+* vblank interrupts, which in turn means the enabl

[RFC PATCH] drm/vblanks: Deal with HW vblank counter resets.

2017-11-06 Thread Dhinakaran Pandiyan
Some HW vblank counters reset due to power management events, which messes
up the vblank counting logic. This leads to screen freezes with user space
waiting on vblank events that may not occur if the counter keeps resetting.

For e.g., After the HW vblank counter resets
[9.007359] [drm:drm_update_vblank_count [drm]] updating vblank count
on crtc 0: current=297, diff=4294965389, hw=5 hw_last=1912

So, fall back to the SW counter, computed using  vblank timestamps
and frame duration, when the HW counter value deviates by 50% of the SW
computed value.

I have tested this patch on my SKL laptop with i915.enable_psr=1 and it
*seems* to solve the screen freeze issue seen with PSR when DMC is loaded.

Known issues:
1) The 50% deviation margin is arbitrary.
2) "Redundant vblirq ignored" messages are more frequent.

I am sending this as an RFC to get feedback on whether the fall back
approach is sane and if it should be implemented in the core.

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Rodrigo Vivi <rodrigo.v...@intel.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_vblank.c | 26 --
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
index 57cc6e37c810..8000aae5f1f7 100644
--- a/drivers/gpu/drm/drm_vblank.c
+++ b/drivers/gpu/drm/drm_vblank.c
@@ -190,11 +190,12 @@ static void drm_update_vblank_count(struct drm_device 
*dev, unsigned int pipe,
bool in_vblank_irq)
 {
struct drm_vblank_crtc *vblank = >vblank[pipe];
-   u32 cur_vblank, diff;
+   u32 cur_vblank;
bool rc;
ktime_t t_vblank;
int count = DRM_TIMESTAMP_MAXRETRIES;
int framedur_ns = vblank->framedur_ns;
+   u32 diff = in_vblank_irq ? 1 : 0;
 
/*
 * Interrupts were disabled prior to this call, so deal with counter
@@ -213,26 +214,31 @@ static void drm_update_vblank_count(struct drm_device 
*dev, unsigned int pipe,
rc = drm_get_last_vbltimestamp(dev, pipe, _vblank, 
in_vblank_irq);
} while (cur_vblank != __get_vblank_counter(dev, pipe) && --count > 0);
 
-   if (dev->max_vblank_count != 0) {
-   /* trust the hw counter when it's around */
+   if (dev->max_vblank_count)
diff = (cur_vblank - vblank->last) & dev->max_vblank_count;
-   } else if (rc && framedur_ns) {
+
+   if (rc && framedur_ns) {
u64 diff_ns = ktime_to_ns(ktime_sub(t_vblank, vblank->time));
+   u32 sw_diff;
 
/*
 * Figure out how many vblanks we've missed based
 * on the difference in the timestamps and the
 * frame/field duration.
 */
-   diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
-
-   if (diff == 0 && in_vblank_irq)
+   sw_diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
+   if (sw_diff == 0 && in_vblank_irq)
DRM_DEBUG_VBL("crtc %u: Redundant vblirq ignored."
  " diff_ns = %lld, framedur_ns = %d)\n",
  pipe, (long long) diff_ns, framedur_ns);
-   } else {
-   /* some kind of default for drivers w/o accurate vbl 
timestamping */
-   diff = in_vblank_irq ? 1 : 0;
+
+   if (!dev->max_vblank_count)
+   diff = sw_diff;
+   else if (sw_diff && abs(diff - sw_diff) > 
DIV_ROUND_CLOSEST(sw_diff, 2)) {
+   DRM_DEBUG_VBL("hw vblank counter(%u) deviates from sw 
(%u)\n",
+ diff, sw_diff);
+   diff = sw_diff;
+   }
}
 
/*
-- 
2.11.0

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


[PATCH] drm/dp: Update SET_POWER_MASK to include the D3 Aux-On state too.

2017-10-30 Thread Dhinakaran Pandiyan
Updating the mask is needed to clear all the three power state bits before
setting the required power state. Also add a comment documenting that
D3 Aux-On state has been available DPCD v1.2 onwards. Thanks to Ville for
pointing this out.

Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Jani Nikula <jani.nik...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 include/drm/drm_dp_helper.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 9049ef133d69..aea10f85dd4c 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -617,8 +617,8 @@
 #define DP_SET_POWER0x600
 # define DP_SET_POWER_D00x1
 # define DP_SET_POWER_D30x2
-# define DP_SET_POWER_MASK  0x3
-# define DP_SET_POWER_D3_AUX_ON 0x5
+# define DP_SET_POWER_D3_AUX_ON 0x5  /* DPCD >= 1.2 */
+# define DP_SET_POWER_MASK  0x7
 
 #define DP_EDP_DPCD_REV0x700/* eDP 1.2 */
 # define DP_EDP_11 0x00
-- 
2.11.0

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


[PATCH v2] drm/dp: DPCD register defines for link status within ESI field

2017-09-14 Thread Dhinakaran Pandiyan
Link status is available in the ESI field on devices with DPCD r1.2 or
higher. DP spec also says "An MST upstream device shall use this field
instead of the Link/Sink Device Status field registers, starting from DPCD
Address 00200h."

v2: Prefixed DP_ (Jani)
Rewrote commment to stay within 80 cols.
Cc: Jani Nikula <jani.nik...@intel.com>
Reviewed-by: Jani Nikula <jani.nik...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 include/drm/drm_dp_helper.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 2c412a15cfa1..11c39f15f1b3 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -738,6 +738,11 @@
 #define DP_RECEIVER_ALPM_STATUS0x200b  /* eDP 1.4 */
 # define DP_ALPM_LOCK_TIMEOUT_ERROR(1 << 0)
 
+#define DP_LANE0_1_STATUS_ESI  0x200c /* status same as 0x202 
*/
+#define DP_LANE2_3_STATUS_ESI  0x200d /* status same as 0x203 
*/
+#define DP_LANE_ALIGN_STATUS_UPDATED_ESI   0x200e /* status same as 0x204 
*/
+#define DP_SINK_STATUS_ESI 0x200f /* status same as 0x205 
*/
+
 #define DP_DPRX_FEATURE_ENUMERATION_LIST0x2210  /* DP 1.3 */
 # define DP_GTC_CAP(1 << 0)  /* DP 1.3 */
 # define DP_SST_SPLIT_SDP_CAP  (1 << 1)  /* DP 1.4 */
-- 
2.11.0

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


[PATCH] drm/dp: DPCD register defines for link status within ESI field

2017-09-13 Thread Dhinakaran Pandiyan
Link status is available in the ESI field on devices with DPCD r1.2 or
higher. DP spec also says "An MST upstream device shall use this field
instead of the Link/Sink Device Status field registers, starting from DPCD
Address 00200h."

Cc: Jani Nikula <jani.nik...@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 include/drm/drm_dp_helper.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index 2c412a15cfa1..0bf15525cdd0 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -738,6 +738,11 @@
 #define DP_RECEIVER_ALPM_STATUS0x200b  /* eDP 1.4 */
 # define DP_ALPM_LOCK_TIMEOUT_ERROR(1 << 0)
 
+#define LANE0_1_STATUS_ESI  0x200c /* Same as status in 0x202 
*/
+#define LANE2_3_STATUS_ESI  0x200d /* Same as status in 0x203 
*/
+#define LANE_ALIGN_STATUS_UPDATED_ESI   0x200e /* Same as status in 0x204 
*/
+#define SINK_STATUS_ESI 0x200f /* Same as status in 0x205 
*/
+
 #define DP_DPRX_FEATURE_ENUMERATION_LIST0x2210  /* DP 1.3 */
 # define DP_GTC_CAP(1 << 0)  /* DP 1.3 */
 # define DP_SST_SPLIT_SDP_CAP  (1 << 1)  /* DP 1.4 */
-- 
2.11.0

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


[PATCH v2] drm/dp/mst: Sideband message transaction to power up/down nodes

2017-09-06 Thread Dhinakaran Pandiyan
The POWER_DOWN_PHY and POWER_UP_PHY sideband message transactions allow
the source to reqest any node in a mst path or a whole path to be
powered down or up. This allows drivers to target a specific sink in the
MST topology, an improvement over just power managing the imediate
downstream device. Secondly, since the request-reply protocol waits for an
ACK, we can be sure that a downstream sink has enough time to respond to a
power up/down request.

v2: Fix memory leak (Lyude)
Cc: Lyude <ly...@redhat.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Harry Wentland <harry.wentl...@amd.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 75 +++
 include/drm/drm_dp_mst_helper.h   |  2 +
 2 files changed, 77 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 41b492f99955..9bc5049e7e59 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -294,6 +294,12 @@ static void drm_dp_encode_sideband_req(struct 
drm_dp_sideband_msg_req_body *req,
memcpy([idx], req->u.i2c_write.bytes, 
req->u.i2c_write.num_bytes);
idx += req->u.i2c_write.num_bytes;
break;
+
+   case DP_POWER_DOWN_PHY:
+   case DP_POWER_UP_PHY:
+   buf[idx] = (req->u.port_num.port_number & 0xf) << 4;
+   idx++;
+   break;
}
raw->cur_len = idx;
 }
@@ -538,6 +544,22 @@ static bool drm_dp_sideband_parse_query_payload_ack(struct 
drm_dp_sideband_msg_r
return false;
 }
 
+
+static bool drm_dp_sideband_parse_power_updown_phy_ack(struct 
drm_dp_sideband_msg_rx *raw,
+  struct 
drm_dp_sideband_msg_reply_body *repmsg)
+{
+   int idx = 1;
+
+   repmsg->u.port_number.port_number = (raw->msg[idx] >> 4) & 0xf;
+   idx++;
+   if (idx > raw->curlen) {
+   DRM_DEBUG_KMS("power up/down phy parse length fail %d %d\n",
+ idx, raw->curlen);
+   return false;
+   }
+   return true;
+}
+
 static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
struct drm_dp_sideband_msg_reply_body 
*msg)
 {
@@ -567,6 +589,9 @@ static bool drm_dp_sideband_parse_reply(struct 
drm_dp_sideband_msg_rx *raw,
return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg);
case DP_ALLOCATE_PAYLOAD:
return drm_dp_sideband_parse_allocate_payload_ack(raw, msg);
+   case DP_POWER_DOWN_PHY:
+   case DP_POWER_UP_PHY:
+   return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
default:
DRM_ERROR("Got unknown reply 0x%02x\n", msg->req_type);
return false;
@@ -693,6 +718,22 @@ static int build_allocate_payload(struct 
drm_dp_sideband_msg_tx *msg, int port_n
return 0;
 }
 
+static int build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
+ int port_num, bool power_up)
+{
+   struct drm_dp_sideband_msg_req_body req;
+
+   if (power_up)
+   req.req_type = DP_POWER_UP_PHY;
+   else
+   req.req_type = DP_POWER_DOWN_PHY;
+
+   req.u.port_num.port_number = port_num;
+   drm_dp_encode_sideband_req(, msg);
+   msg->path_msg = true;
+   return 0;
+}
+
 static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_vcpi *vcpi)
 {
@@ -1724,6 +1765,40 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
return ret;
 }
 
+int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
+struct drm_dp_mst_port *port, bool power_up)
+{
+   struct drm_dp_sideband_msg_tx *txmsg;
+   int len, ret;
+
+   port = drm_dp_get_validated_port_ref(mgr, port);
+   if (!port)
+   return -EINVAL;
+
+   txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+   if (!txmsg) {
+   drm_dp_put_port(port);
+   return -ENOMEM;
+   }
+
+   txmsg->dst = port->parent;
+   len = build_power_updown_phy(txmsg, port->port_num, power_up);
+   drm_dp_queue_down_tx(mgr, txmsg);
+
+   ret = drm_dp_mst_wait_tx_reply(port->parent, txmsg);
+   if (ret > 0) {
+   if (txmsg->reply.reply_type == 1)
+   ret = -EINVAL;
+   else
+   ret = 0;
+   }
+   kfree(txmsg);
+   drm_dp_put_port(port);
+
+   return ret;
+}
+EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
+
 static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,

[PATCH 2/2] drm/i915/mst: Use MST sideband message transaction for dpms

2017-09-05 Thread Dhinakaran Pandiyan
Use the POWER_DOWN_PHY and POWER_UP_PHY sideband message trasactions to
set power states for downstream sinks. Apart from giving us the ability
to set power state for individual sinks, this fixes the below test for
me

$ xrandr --display :0 --output DP-2-2-8 --off
$ xrandr --display :0 --output DP-2-2-1 --off
$ xrandr --display :0 --output DP-2-2-8 --auto #Black screen
$ xrandr --display :0 --output DP-2-2-1 --auto

Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Lyude <ly...@redhat.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c| 6 --
 drivers/gpu/drm/i915/intel_dp_mst.c | 8 
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 1da3bb2cc4b4..8aebacc0aa31 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -2161,7 +2161,8 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder 
*encoder,
intel_prepare_dp_ddi_buffers(encoder);
 
intel_ddi_init_dp_buf_reg(encoder);
-   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
+   if (!link_mst)
+   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
intel_dp_start_link_train(intel_dp);
if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
intel_dp_stop_link_train(intel_dp);
@@ -2240,7 +2241,8 @@ static void intel_ddi_post_disable(struct intel_encoder 
*intel_encoder,
if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
-   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
+   if (old_crtc_state && old_conn_state)
+   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
}
 
val = I915_READ(DDI_BUF_CTL(port));
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c 
b/drivers/gpu/drm/i915/intel_dp_mst.c
index 8e3aad0ea60b..81e63724e24b 100644
--- a/drivers/gpu/drm/i915/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/intel_dp_mst.c
@@ -167,12 +167,11 @@ static void intel_mst_post_disable_dp(struct 
intel_encoder *encoder,
intel_dp->active_mst_links--;
 
intel_mst->connector = NULL;
-   if (intel_dp->active_mst_links == 0) {
+   if (intel_dp->active_mst_links == 0)
intel_dig_port->base.post_disable(_dig_port->base,
  NULL, NULL);
-
-   intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
-   }
+   drm_dp_send_power_updown_phy(_dp->mst_mgr, connector->port,
+false);
 }
 
 static void intel_mst_pre_enable_dp(struct intel_encoder *encoder,
@@ -197,6 +196,7 @@ static void intel_mst_pre_enable_dp(struct intel_encoder 
*encoder,
 
DRM_DEBUG_KMS("%d\n", intel_dp->active_mst_links);
 
+   drm_dp_send_power_updown_phy(_dp->mst_mgr, connector->port, true);
if (intel_dp->active_mst_links == 0)
intel_dig_port->base.pre_enable(_dig_port->base,
pipe_config, NULL);
-- 
2.11.0

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


[PATCH 1/2] drm/dp/mst: Sideband message transaction to power up/down nodes

2017-09-05 Thread Dhinakaran Pandiyan
The POWER_DOWN_PHY and POWER_UP_PHY sideband message transactions allow
the source to reqest any node in a mst path or a whole path to be
powered down or up. This allows drivers to target a specific sink in the
MST topology, an improvement over just power managing the imediate
downstream device. Secondly, since the request-reply protocol waits for an
ACK, we can be sure that a downstream sink has enough time to respond to a
power up/down request.

Cc: Lyude <ly...@redhat.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Harry Wentland <harry.wentl...@amd.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 73 +++
 include/drm/drm_dp_mst_helper.h   |  2 +
 2 files changed, 75 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index 41b492f99955..a9f12708a046 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -294,6 +294,12 @@ static void drm_dp_encode_sideband_req(struct 
drm_dp_sideband_msg_req_body *req,
memcpy([idx], req->u.i2c_write.bytes, 
req->u.i2c_write.num_bytes);
idx += req->u.i2c_write.num_bytes;
break;
+
+   case DP_POWER_DOWN_PHY:
+   case DP_POWER_UP_PHY:
+   buf[idx] = (req->u.port_num.port_number & 0xf) << 4;
+   idx++;
+   break;
}
raw->cur_len = idx;
 }
@@ -538,6 +544,22 @@ static bool drm_dp_sideband_parse_query_payload_ack(struct 
drm_dp_sideband_msg_r
return false;
 }
 
+
+static bool drm_dp_sideband_parse_power_updown_phy_ack(struct 
drm_dp_sideband_msg_rx *raw,
+  struct 
drm_dp_sideband_msg_reply_body *repmsg)
+{
+   int idx = 1;
+
+   repmsg->u.port_number.port_number = (raw->msg[idx] >> 4) & 0xf;
+   idx++;
+   if (idx > raw->curlen) {
+   DRM_DEBUG_KMS("power up/down phy parse length fail %d %d\n",
+ idx, raw->curlen);
+   return false;
+   }
+   return true;
+}
+
 static bool drm_dp_sideband_parse_reply(struct drm_dp_sideband_msg_rx *raw,
struct drm_dp_sideband_msg_reply_body 
*msg)
 {
@@ -567,6 +589,9 @@ static bool drm_dp_sideband_parse_reply(struct 
drm_dp_sideband_msg_rx *raw,
return drm_dp_sideband_parse_enum_path_resources_ack(raw, msg);
case DP_ALLOCATE_PAYLOAD:
return drm_dp_sideband_parse_allocate_payload_ack(raw, msg);
+   case DP_POWER_DOWN_PHY:
+   case DP_POWER_UP_PHY:
+   return drm_dp_sideband_parse_power_updown_phy_ack(raw, msg);
default:
DRM_ERROR("Got unknown reply 0x%02x\n", msg->req_type);
return false;
@@ -693,6 +718,22 @@ static int build_allocate_payload(struct 
drm_dp_sideband_msg_tx *msg, int port_n
return 0;
 }
 
+static int build_power_updown_phy(struct drm_dp_sideband_msg_tx *msg,
+ int port_num, bool power_up)
+{
+   struct drm_dp_sideband_msg_req_body req;
+
+   if (power_up)
+   req.req_type = DP_POWER_UP_PHY;
+   else
+   req.req_type = DP_POWER_DOWN_PHY;
+
+   req.u.port_num.port_number = port_num;
+   drm_dp_encode_sideband_req(, msg);
+   msg->path_msg = true;
+   return 0;
+}
+
 static int drm_dp_mst_assign_payload_id(struct drm_dp_mst_topology_mgr *mgr,
struct drm_dp_vcpi *vcpi)
 {
@@ -1724,6 +1765,38 @@ static int drm_dp_payload_send_msg(struct 
drm_dp_mst_topology_mgr *mgr,
return ret;
 }
 
+int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr,
+struct drm_dp_mst_port *port, bool power_up)
+{
+   struct drm_dp_sideband_msg_tx *txmsg;
+   int len, ret;
+
+   txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL);
+   if (!txmsg)
+   return -ENOMEM;
+
+   port = drm_dp_get_validated_port_ref(mgr, port);
+   if (!port)
+   return -EINVAL;
+
+   txmsg->dst = port->parent;
+   len = build_power_updown_phy(txmsg, port->port_num, power_up);
+   drm_dp_queue_down_tx(mgr, txmsg);
+
+   ret = drm_dp_mst_wait_tx_reply(port->parent, txmsg);
+   if (ret > 0) {
+   if (txmsg->reply.reply_type == 1)
+   ret = -EINVAL;
+   else
+   ret = 0;
+   }
+   kfree(txmsg);
+   drm_dp_put_port(port);
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_dp_send_power_updown_phy);
+
 static int drm_dp_create_payload_step1(struct drm_dp_mst_topology_mgr *mgr,
   int id,
   struct drm_

[PATCH v2 1/2] drm/dp: Bit definition for D3 power state that keeps AUX fully powered

2017-08-12 Thread Dhinakaran Pandiyan
DPCD 600h - SET_POWER & SET_DP_PWR_VOLTAGE defines power state

101 = Set Main-Link for local Sink device and all downstream Sink
devices to D3 (power-down mode), keep AUX block fully powered, ready to
reply within a Response Timeout period of 300us.

This state is useful in a MST dock + MST monitor configuration that
doesn't wake up from D3 state.

v2: Use spaces instead of tabs (Jani)

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 include/drm/drm_dp_helper.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index b17476a..47a6cdb 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -618,6 +618,7 @@
 # define DP_SET_POWER_D00x1
 # define DP_SET_POWER_D30x2
 # define DP_SET_POWER_MASK  0x3
+# define DP_SET_POWER_D3_AUX_ON 0x5
 
 #define DP_EDP_DPCD_REV0x700/* eDP 1.2 */
 # define DP_EDP_11 0x00
-- 
2.7.4

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


[PATCH 1/2] drm/dp: Bit definition for D3 power state that keeps AUX fully powered

2017-08-12 Thread Dhinakaran Pandiyan
DPCD 600h - SET_POWER & SET_DP_PWR_VOLTAGE defines power state

101 = Set Main-Link for local Sink device and all downstream Sink
devices to D3 (power-down mode), keep AUX block fully powered, ready to
reply within a Response Timeout period of 300us.

This state is useful in a MST dock + MST monitor configuration that
doesn't wake up from D3 state.

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 include/drm/drm_dp_helper.h | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index b17476a..d77e0f5 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -614,10 +614,11 @@
 #define DP_BRANCH_HW_REV0x509
 #define DP_BRANCH_SW_REV0x50A
 
-#define DP_SET_POWER0x600
-# define DP_SET_POWER_D00x1
-# define DP_SET_POWER_D30x2
-# define DP_SET_POWER_MASK  0x3
+#define DP_SET_POWER   0x600
+# define DP_SET_POWER_D0   0x1
+# define DP_SET_POWER_D3   0x2
+# define DP_SET_POWER_MASK 0x3
+# define DP_SET_POWER_D3_AUX_ON0x5
 
 #define DP_EDP_DPCD_REV0x700/* eDP 1.2 */
 # define DP_EDP_11 0x00
-- 
2.7.4

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


[RESEND FOR CI PATCH v8 0/4] Adding driver-private objects to atomic state

2017-05-01 Thread Dhinakaran Pandiyan
Resending for CI.

Pandiyan, Dhinakaran (4):
  drm: Add driver-private objects to atomic state
  drm/dp: Introduce MST topology state to track available link bandwidth
  drm/dp: Add DP MST helpers to atomically find and release vcpi slots
  drm/dp: Track MST link bandwidth

 drivers/gpu/drm/drm_atomic.c  |  65 +++
 drivers/gpu/drm/drm_atomic_helper.c   |   5 ++
 drivers/gpu/drm/drm_dp_mst_topology.c | 150 ++
 drivers/gpu/drm/i915/intel_dp_mst.c   |  48 +--
 include/drm/drm_atomic.h  |  95 +
 include/drm/drm_dp_mst_helper.h   |  26 ++
 6 files changed, 383 insertions(+), 6 deletions(-)

-- 
2.7.4

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


[RESEND FOR CI PATCH v8 2/4] drm/dp: Introduce MST topology state to track available link bandwidth

2017-05-01 Thread Dhinakaran Pandiyan
From: "Pandiyan, Dhinakaran" <dhinakaran.pandi...@intel.com>

Link bandwidth is shared between multiple display streams in DP MST
configurations. The DP MST topology manager structure maintains the
shared link bandwidth for a primary link directly connected to the GPU. For
atomic modesetting drivers, checking if there is sufficient link bandwidth
for a mode needs to be done during the atomic_check phase to avoid failed
modesets. Let's encapsulate the available link bw information in a
private state structure so that bw can be allocated and released atomically
for each of the ports sharing the primary link.

v3: WARN_ON() if connection_mutex is not held (Archit)
v2: Included kernel doc, moved state initialization and switched to
kmemdup() for allocation (Daniel)

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Maarten Lankhorst <maarten.lankho...@linux.intel.com>
Cc: Archit Taneja <arch...@codeaurora.org>
Cc: Chris Wilson <ch...@chris-wilson.co.uk>
Cc: Harry Wentland <harry.wentl...@amd.com>

Reviewed-by: Maarten Lankhorst <maarten.lankho...@linux.intel.com>
Reviewed-by: Harry Wentland <harry.wentl...@amd.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandi...@intel.com>
---
 drivers/gpu/drm/drm_dp_mst_topology.c | 75 +++
 include/drm/drm_dp_mst_helper.h   | 20 ++
 2 files changed, 95 insertions(+)

diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c 
b/drivers/gpu/drm/drm_dp_mst_topology.c
index d3fc7e4..0ad0baa 100644
--- a/drivers/gpu/drm/drm_dp_mst_topology.c
+++ b/drivers/gpu/drm/drm_dp_mst_topology.c
@@ -2936,6 +2936,69 @@ static void drm_dp_destroy_connector_work(struct 
work_struct *work)
(*mgr->cbs->hotplug)(mgr);
 }
 
+void *drm_dp_mst_duplicate_state(struct drm_atomic_state *state, void *obj)
+{
+   struct drm_dp_mst_topology_mgr *mgr = obj;
+   struct drm_dp_mst_topology_state *new_mst_state;
+
+   if (WARN_ON(!mgr->state))
+   return NULL;
+
+   new_mst_state = kmemdup(mgr->state, sizeof(*new_mst_state), GFP_KERNEL);
+   if (new_mst_state)
+   new_mst_state->state = state;
+   return new_mst_state;
+}
+
+void drm_dp_mst_swap_state(void *obj, void **obj_state_ptr)
+{
+   struct drm_dp_mst_topology_mgr *mgr = obj;
+   struct drm_dp_mst_topology_state **topology_state_ptr;
+
+   topology_state_ptr = (struct drm_dp_mst_topology_state **)obj_state_ptr;
+
+   mgr->state->state = (*topology_state_ptr)->state;
+   swap(*topology_state_ptr, mgr->state);
+   mgr->state->state = NULL;
+}
+
+void drm_dp_mst_destroy_state(void *obj_state)
+{
+   kfree(obj_state);
+}
+
+static const struct drm_private_state_funcs mst_state_funcs = {
+   .duplicate_state = drm_dp_mst_duplicate_state,
+   .swap_state = drm_dp_mst_swap_state,
+   .destroy_state = drm_dp_mst_destroy_state,
+};
+
+/**
+ * drm_atomic_get_mst_topology_state: get MST topology state
+ *
+ * @state: global atomic state
+ * @mgr: MST topology manager, also the private object in this case
+ *
+ * This function wraps drm_atomic_get_priv_obj_state() passing in the MST 
atomic
+ * state vtable so that the private object state returned is that of a MST
+ * topology object. Also, drm_atomic_get_private_obj_state() expects the caller
+ * to care of the locking, so warn if don't hold the connection_mutex.
+ *
+ * RETURNS:
+ *
+ * The MST topology state or error pointer.
+ */
+struct drm_dp_mst_topology_state *drm_atomic_get_mst_topology_state(struct 
drm_atomic_state *state,
+   struct 
drm_dp_mst_topology_mgr *mgr)
+{
+   struct drm_device *dev = mgr->dev;
+
+   WARN_ON(!drm_modeset_is_locked(>mode_config.connection_mutex));
+   return drm_atomic_get_private_obj_state(state, mgr,
+   _state_funcs);
+}
+EXPORT_SYMBOL(drm_atomic_get_mst_topology_state);
+
 /**
  * drm_dp_mst_topology_mgr_init - initialise a topology manager
  * @mgr: manager struct to initialise
@@ -2980,6 +3043,15 @@ int drm_dp_mst_topology_mgr_init(struct 
drm_dp_mst_topology_mgr *mgr,
if (test_calc_pbn_mode() < 0)
DRM_ERROR("MST PBN self-test failed\n");
 
+   mgr->state = kzalloc(sizeof(*mgr->state), GFP_KERNEL);
+   if (mgr->state == NULL)
+   return -ENOMEM;
+   mgr->state->mgr = mgr;
+
+   /* max. time slots - one slot for MTP header */
+   mgr->state->avail_slots = 63;
+   mgr->funcs = _state_funcs;
+
return 0;
 }
 EXPORT_SYMBOL(drm_dp_mst_topology_mgr_init);
@@ -3000,6 +3072,9 @@ void drm_dp_mst_topology_mgr_destroy(struct 
drm_dp_mst_topology_mgr *mgr)
mutex_unlock(>payload_lock);
mgr->dev = NULL;
mgr->aux = NULL;
+   kfree(mgr->state);
+   mgr->state = NULL;
+   

  1   2   >