Re: [Intel-gfx] [PATCH 12/16] drm/i915: Disable LP1+ watermarks while changing the number of active pipes

2014-06-09 Thread Ville Syrjälä
On Wed, Jun 04, 2014 at 03:24:13PM -0300, Paulo Zanoni wrote:
 2014-05-22 11:48 GMT-03:00  ville.syrj...@linux.intel.com:
  From: Ville Syrjälä ville.syrj...@linux.intel.com
 
  When we switch between one active pipe and multiple active pipes, the
  display FIFO gets repartitioned. Disable the LP1+ waterwarks while that
  is happening to make sure we don't get any glitches on other active
  pipes while doing a modeset on another other pipe.
 
  Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
  ---
   drivers/gpu/drm/i915/intel_display.c | 45 
  ++
   drivers/gpu/drm/i915/intel_drv.h |  2 ++
   drivers/gpu/drm/i915/intel_pm.c  | 47 
  
   3 files changed, 89 insertions(+), 5 deletions(-)
 
  diff --git a/drivers/gpu/drm/i915/intel_display.c 
  b/drivers/gpu/drm/i915/intel_display.c
  index bccf414..311c0f0 100644
  --- a/drivers/gpu/drm/i915/intel_display.c
  +++ b/drivers/gpu/drm/i915/intel_display.c
  @@ -3985,6 +3985,27 @@ static struct intel_crtc 
  *get_other_active_crtc(struct intel_crtc *crtc)
  return other_active_crtc;
   }
 
  +static void ilk_prepare_for_num_pipes_change(struct intel_crtc *crtc)
  +{
  +   struct drm_device *dev = crtc-base.dev;
  +   struct intel_crtc *other_active_crtc = get_other_active_crtc(crtc);
  +
  +   /*
  +* If we change between one pipe and multiple pipes,
  +* make sure the other active pipe is prepared
  +* for having its FIFO resized. We do that by making
  +* sure the pipe isn't using LP1+ watermarks when
  +* the second pipe gets enabled or disabled.
  +*/
  +   if (!other_active_crtc)
  +   return;
 
 But get_other_active_crtc() returns NULL in case 2 other CRTCs are
 already active. If we're the third pipe being enabled, we may still
 get an underrun.

The FIFO repartitioning happens only when going 1-2 pipes, so the
2-3 cases don't matter here.

 
  +
  +   ilk_wm_synchronize(other_active_crtc);
  +
  +   if (ilk_disable_lp_wm(dev))
  +   intel_wait_for_vblank(dev, other_active_crtc-pipe);
  +}
  +
   static void ironlake_crtc_enable(struct drm_crtc *crtc)
   {
  struct drm_device *dev = crtc-dev;
  @@ -4023,6 +4044,9 @@ static void ironlake_crtc_enable(struct drm_crtc 
  *crtc)
 
  intel_crtc-active = true;
 
  +   /* Make sure other pipes are prepared for FIFO resizing */
  +   ilk_prepare_for_num_pipes_change(intel_crtc);
  +
  intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
  intel_set_pch_fifo_underrun_reporting(dev, pipe, true);
 
  @@ -4123,6 +4147,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
  intel_crtc-active = true;
 
  +   /* Make sure other pipes are prepared for FIFO resizing */
  +   ilk_prepare_for_num_pipes_change(intel_crtc);
  +
  intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
  if (intel_crtc-config.has_pch_encoder)
  intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, 
  true);
  @@ -4192,6 +4219,9 @@ static void ironlake_crtc_disable(struct drm_crtc 
  *crtc)
 
  intel_crtc_disable_planes(crtc);
 
  +   /* Make sure other pipes are prepared for FIFO resizing */
  +   ilk_prepare_for_num_pipes_change(intel_crtc);
  +
  for_each_encoder_on_crtc(dev, crtc, encoder)
  encoder-disable(encoder);
 
  @@ -4235,6 +4265,12 @@ static void ironlake_crtc_disable(struct drm_crtc 
  *crtc)
 
  intel_crtc-active = false;
 
  +   /*
  +* Potentially let some other pipe use the
  +* full FIFO, and re-enable LP1+ watermarks.
  +*/
  +   ilk_wm_pipe_post_disable(intel_crtc);
  +
  mutex_lock(dev-struct_mutex);
  intel_update_fbc(dev);
  intel_edp_psr_update(dev);
  @@ -4255,6 +4291,9 @@ static void haswell_crtc_disable(struct drm_crtc 
  *crtc)
 
  intel_crtc_disable_planes(crtc);
 
  +   /* Make sure other pipes are prepared for FIFO resizing */
  +   ilk_prepare_for_num_pipes_change(intel_crtc);
  +
  for_each_encoder_on_crtc(dev, crtc, encoder) {
  intel_opregion_notify_encoder(encoder, false);
  encoder-disable(encoder);
  @@ -4282,6 +4321,12 @@ static void haswell_crtc_disable(struct drm_crtc 
  *crtc)
 
  intel_crtc-active = false;
 
  +   /*
  +* Potentially let some other pipe use the
  +* full FIFO, and re-enable LP1+ watermarks.
  +*/
  +   ilk_wm_pipe_post_disable(intel_crtc);
  +
  mutex_lock(dev-struct_mutex);
  intel_update_fbc(dev);
  intel_edp_psr_update(dev);
  diff --git a/drivers/gpu/drm/i915/intel_drv.h 
  b/drivers/gpu/drm/i915/intel_drv.h
  index 5ad7ad5..98f878f 100644
  --- a/drivers/gpu/drm/i915/intel_drv.h
  +++ b/drivers/gpu/drm/i915/intel_drv.h
  @@ -1022,6 +1022,8 @@ void 

Re: [Intel-gfx] [PATCH 12/16] drm/i915: Disable LP1+ watermarks while changing the number of active pipes

2014-06-04 Thread Paulo Zanoni
2014-05-22 11:48 GMT-03:00  ville.syrj...@linux.intel.com:
 From: Ville Syrjälä ville.syrj...@linux.intel.com

 When we switch between one active pipe and multiple active pipes, the
 display FIFO gets repartitioned. Disable the LP1+ waterwarks while that
 is happening to make sure we don't get any glitches on other active
 pipes while doing a modeset on another other pipe.

 Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
 ---
  drivers/gpu/drm/i915/intel_display.c | 45 ++
  drivers/gpu/drm/i915/intel_drv.h |  2 ++
  drivers/gpu/drm/i915/intel_pm.c  | 47 
 
  3 files changed, 89 insertions(+), 5 deletions(-)

 diff --git a/drivers/gpu/drm/i915/intel_display.c 
 b/drivers/gpu/drm/i915/intel_display.c
 index bccf414..311c0f0 100644
 --- a/drivers/gpu/drm/i915/intel_display.c
 +++ b/drivers/gpu/drm/i915/intel_display.c
 @@ -3985,6 +3985,27 @@ static struct intel_crtc *get_other_active_crtc(struct 
 intel_crtc *crtc)
 return other_active_crtc;
  }

 +static void ilk_prepare_for_num_pipes_change(struct intel_crtc *crtc)
 +{
 +   struct drm_device *dev = crtc-base.dev;
 +   struct intel_crtc *other_active_crtc = get_other_active_crtc(crtc);
 +
 +   /*
 +* If we change between one pipe and multiple pipes,
 +* make sure the other active pipe is prepared
 +* for having its FIFO resized. We do that by making
 +* sure the pipe isn't using LP1+ watermarks when
 +* the second pipe gets enabled or disabled.
 +*/
 +   if (!other_active_crtc)
 +   return;

But get_other_active_crtc() returns NULL in case 2 other CRTCs are
already active. If we're the third pipe being enabled, we may still
get an underrun.

 +
 +   ilk_wm_synchronize(other_active_crtc);
 +
 +   if (ilk_disable_lp_wm(dev))
 +   intel_wait_for_vblank(dev, other_active_crtc-pipe);
 +}
 +
  static void ironlake_crtc_enable(struct drm_crtc *crtc)
  {
 struct drm_device *dev = crtc-dev;
 @@ -4023,6 +4044,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)

 intel_crtc-active = true;

 +   /* Make sure other pipes are prepared for FIFO resizing */
 +   ilk_prepare_for_num_pipes_change(intel_crtc);
 +
 intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
 intel_set_pch_fifo_underrun_reporting(dev, pipe, true);

 @@ -4123,6 +4147,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)

 intel_crtc-active = true;

 +   /* Make sure other pipes are prepared for FIFO resizing */
 +   ilk_prepare_for_num_pipes_change(intel_crtc);
 +
 intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
 if (intel_crtc-config.has_pch_encoder)
 intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, 
 true);
 @@ -4192,6 +4219,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)

 intel_crtc_disable_planes(crtc);

 +   /* Make sure other pipes are prepared for FIFO resizing */
 +   ilk_prepare_for_num_pipes_change(intel_crtc);
 +
 for_each_encoder_on_crtc(dev, crtc, encoder)
 encoder-disable(encoder);

 @@ -4235,6 +4265,12 @@ static void ironlake_crtc_disable(struct drm_crtc 
 *crtc)

 intel_crtc-active = false;

 +   /*
 +* Potentially let some other pipe use the
 +* full FIFO, and re-enable LP1+ watermarks.
 +*/
 +   ilk_wm_pipe_post_disable(intel_crtc);
 +
 mutex_lock(dev-struct_mutex);
 intel_update_fbc(dev);
 intel_edp_psr_update(dev);
 @@ -4255,6 +4291,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)

 intel_crtc_disable_planes(crtc);

 +   /* Make sure other pipes are prepared for FIFO resizing */
 +   ilk_prepare_for_num_pipes_change(intel_crtc);
 +
 for_each_encoder_on_crtc(dev, crtc, encoder) {
 intel_opregion_notify_encoder(encoder, false);
 encoder-disable(encoder);
 @@ -4282,6 +4321,12 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)

 intel_crtc-active = false;

 +   /*
 +* Potentially let some other pipe use the
 +* full FIFO, and re-enable LP1+ watermarks.
 +*/
 +   ilk_wm_pipe_post_disable(intel_crtc);
 +
 mutex_lock(dev-struct_mutex);
 intel_update_fbc(dev);
 intel_edp_psr_update(dev);
 diff --git a/drivers/gpu/drm/i915/intel_drv.h 
 b/drivers/gpu/drm/i915/intel_drv.h
 index 5ad7ad5..98f878f 100644
 --- a/drivers/gpu/drm/i915/intel_drv.h
 +++ b/drivers/gpu/drm/i915/intel_drv.h
 @@ -1022,6 +1022,8 @@ void intel_program_watermarks_pre(struct intel_crtc 
 *crtc,
  void intel_program_watermarks_post(struct intel_crtc *crtc,
const struct intel_crtc_wm_config *config);
  void ilk_wm_synchronize(struct intel_crtc *crtc);
 +void ilk_wm_pipe_post_disable(struct intel_crtc *crtc);
 +bool 

[Intel-gfx] [PATCH 12/16] drm/i915: Disable LP1+ watermarks while changing the number of active pipes

2014-05-22 Thread ville . syrjala
From: Ville Syrjälä ville.syrj...@linux.intel.com

When we switch between one active pipe and multiple active pipes, the
display FIFO gets repartitioned. Disable the LP1+ waterwarks while that
is happening to make sure we don't get any glitches on other active
pipes while doing a modeset on another other pipe.

Signed-off-by: Ville Syrjälä ville.syrj...@linux.intel.com
---
 drivers/gpu/drm/i915/intel_display.c | 45 ++
 drivers/gpu/drm/i915/intel_drv.h |  2 ++
 drivers/gpu/drm/i915/intel_pm.c  | 47 
 3 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index bccf414..311c0f0 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3985,6 +3985,27 @@ static struct intel_crtc *get_other_active_crtc(struct 
intel_crtc *crtc)
return other_active_crtc;
 }
 
+static void ilk_prepare_for_num_pipes_change(struct intel_crtc *crtc)
+{
+   struct drm_device *dev = crtc-base.dev;
+   struct intel_crtc *other_active_crtc = get_other_active_crtc(crtc);
+
+   /*
+* If we change between one pipe and multiple pipes,
+* make sure the other active pipe is prepared
+* for having its FIFO resized. We do that by making
+* sure the pipe isn't using LP1+ watermarks when
+* the second pipe gets enabled or disabled.
+*/
+   if (!other_active_crtc)
+   return;
+
+   ilk_wm_synchronize(other_active_crtc);
+
+   if (ilk_disable_lp_wm(dev))
+   intel_wait_for_vblank(dev, other_active_crtc-pipe);
+}
+
 static void ironlake_crtc_enable(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc-dev;
@@ -4023,6 +4044,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
 
intel_crtc-active = true;
 
+   /* Make sure other pipes are prepared for FIFO resizing */
+   ilk_prepare_for_num_pipes_change(intel_crtc);
+
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
intel_set_pch_fifo_underrun_reporting(dev, pipe, true);
 
@@ -4123,6 +4147,9 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
 
intel_crtc-active = true;
 
+   /* Make sure other pipes are prepared for FIFO resizing */
+   ilk_prepare_for_num_pipes_change(intel_crtc);
+
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
if (intel_crtc-config.has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
@@ -4192,6 +4219,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 
intel_crtc_disable_planes(crtc);
 
+   /* Make sure other pipes are prepared for FIFO resizing */
+   ilk_prepare_for_num_pipes_change(intel_crtc);
+
for_each_encoder_on_crtc(dev, crtc, encoder)
encoder-disable(encoder);
 
@@ -4235,6 +4265,12 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
 
intel_crtc-active = false;
 
+   /*
+* Potentially let some other pipe use the
+* full FIFO, and re-enable LP1+ watermarks.
+*/
+   ilk_wm_pipe_post_disable(intel_crtc);
+
mutex_lock(dev-struct_mutex);
intel_update_fbc(dev);
intel_edp_psr_update(dev);
@@ -4255,6 +4291,9 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 
intel_crtc_disable_planes(crtc);
 
+   /* Make sure other pipes are prepared for FIFO resizing */
+   ilk_prepare_for_num_pipes_change(intel_crtc);
+
for_each_encoder_on_crtc(dev, crtc, encoder) {
intel_opregion_notify_encoder(encoder, false);
encoder-disable(encoder);
@@ -4282,6 +4321,12 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
 
intel_crtc-active = false;
 
+   /*
+* Potentially let some other pipe use the
+* full FIFO, and re-enable LP1+ watermarks.
+*/
+   ilk_wm_pipe_post_disable(intel_crtc);
+
mutex_lock(dev-struct_mutex);
intel_update_fbc(dev);
intel_edp_psr_update(dev);
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 5ad7ad5..98f878f 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1022,6 +1022,8 @@ void intel_program_watermarks_pre(struct intel_crtc *crtc,
 void intel_program_watermarks_post(struct intel_crtc *crtc,
   const struct intel_crtc_wm_config *config);
 void ilk_wm_synchronize(struct intel_crtc *crtc);
+void ilk_wm_pipe_post_disable(struct intel_crtc *crtc);
+bool ilk_disable_lp_wm(struct drm_device *dev);
 
 
 /* intel_sdvo.c */
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 1c072cd..18ea8b1 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -2765,7 +2765,7 @@ static void ilk_write_wm_values(struct