diff mbox

[3/8] drm/i915: extract set_pipe_timings from ironlake_crtc_mode_set

Message ID 1347455196-5167-4-git-send-email-przanoni@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Paulo Zanoni Sept. 12, 2012, 1:06 p.m. UTC
From: Paulo Zanoni <paulo.r.zanoni@intel.com>

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   82 +++++++++++++++++++---------------
 1 file changed, 46 insertions(+), 36 deletions(-)

Comments

Daniel Vetter Sept. 12, 2012, 2:11 p.m. UTC | #1
On Wed, Sep 12, 2012 at 10:06:31AM -0300, Paulo Zanoni wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> 
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>

Hm, I think we should extract the same code from i9xx_crtc_set_mode, too
and share it in a common intel_set_pipe_timings. Their almost identical
safe for:
- vsyncshift is only gen4+
- source position handling is a bit different, but I think it'd be
  semantically clearer if we leave that out of set_pipe_timings. Imo that
  belongs to the panel fitter settings, which are currently splattered all
  over. Meh.

Comments?
-Daniel
> ---
>  drivers/gpu/drm/i915/intel_display.c |   82 +++++++++++++++++++---------------
>  1 file changed, 46 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index cf1e628..5a4e363 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4690,6 +4690,51 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
>  	POSTING_READ(PIPECONF(pipe));
>  }
>  
> +static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
> +				      struct drm_display_mode *mode,
> +				      struct drm_display_mode *adjusted_mode)
> +{
> +	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
> +	enum pipe pipe = intel_crtc->pipe;
> +
> +	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
> +		/* the chip adds 2 halflines automatically */
> +		adjusted_mode->crtc_vtotal -= 1;
> +		adjusted_mode->crtc_vblank_end -= 1;
> +		I915_WRITE(VSYNCSHIFT(pipe),
> +			   adjusted_mode->crtc_hsync_start
> +			   - adjusted_mode->crtc_htotal/2);
> +	} else {
> +		I915_WRITE(VSYNCSHIFT(pipe), 0);
> +	}
> +
> +	I915_WRITE(HTOTAL(pipe),
> +		   (adjusted_mode->crtc_hdisplay - 1) |
> +		   ((adjusted_mode->crtc_htotal - 1) << 16));
> +	I915_WRITE(HBLANK(pipe),
> +		   (adjusted_mode->crtc_hblank_start - 1) |
> +		   ((adjusted_mode->crtc_hblank_end - 1) << 16));
> +	I915_WRITE(HSYNC(pipe),
> +		   (adjusted_mode->crtc_hsync_start - 1) |
> +		   ((adjusted_mode->crtc_hsync_end - 1) << 16));
> +
> +	I915_WRITE(VTOTAL(pipe),
> +		   (adjusted_mode->crtc_vdisplay - 1) |
> +		   ((adjusted_mode->crtc_vtotal - 1) << 16));
> +	I915_WRITE(VBLANK(pipe),
> +		   (adjusted_mode->crtc_vblank_start - 1) |
> +		   ((adjusted_mode->crtc_vblank_end - 1) << 16));
> +	I915_WRITE(VSYNC(pipe),
> +		   (adjusted_mode->crtc_vsync_start - 1) |
> +		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
> +
> +	/* pipesrc controls the size that is scaled from, which should
> +	 * always be the user's requested size.
> +	 */
> +	I915_WRITE(PIPESRC(pipe),
> +		   ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
> +}
> +
>  static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>  				  struct drm_display_mode *mode,
>  				  struct drm_display_mode *adjusted_mode,
> @@ -4970,42 +5015,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>  		}
>  	}
>  
> -	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
> -		/* the chip adds 2 halflines automatically */
> -		adjusted_mode->crtc_vtotal -= 1;
> -		adjusted_mode->crtc_vblank_end -= 1;
> -		I915_WRITE(VSYNCSHIFT(pipe),
> -			   adjusted_mode->crtc_hsync_start
> -			   - adjusted_mode->crtc_htotal/2);
> -	} else {
> -		I915_WRITE(VSYNCSHIFT(pipe), 0);
> -	}
> -
> -	I915_WRITE(HTOTAL(pipe),
> -		   (adjusted_mode->crtc_hdisplay - 1) |
> -		   ((adjusted_mode->crtc_htotal - 1) << 16));
> -	I915_WRITE(HBLANK(pipe),
> -		   (adjusted_mode->crtc_hblank_start - 1) |
> -		   ((adjusted_mode->crtc_hblank_end - 1) << 16));
> -	I915_WRITE(HSYNC(pipe),
> -		   (adjusted_mode->crtc_hsync_start - 1) |
> -		   ((adjusted_mode->crtc_hsync_end - 1) << 16));
> -
> -	I915_WRITE(VTOTAL(pipe),
> -		   (adjusted_mode->crtc_vdisplay - 1) |
> -		   ((adjusted_mode->crtc_vtotal - 1) << 16));
> -	I915_WRITE(VBLANK(pipe),
> -		   (adjusted_mode->crtc_vblank_start - 1) |
> -		   ((adjusted_mode->crtc_vblank_end - 1) << 16));
> -	I915_WRITE(VSYNC(pipe),
> -		   (adjusted_mode->crtc_vsync_start - 1) |
> -		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
> -
> -	/* pipesrc controls the size that is scaled from, which should
> -	 * always be the user's requested size.
> -	 */
> -	I915_WRITE(PIPESRC(pipe),
> -		   ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
> +	ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
>  
>  	I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
>  	I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Paulo Zanoni Sept. 19, 2012, 6:11 p.m. UTC | #2
Hi

2012/9/12 Daniel Vetter <daniel@ffwll.ch>:
> On Wed, Sep 12, 2012 at 10:06:31AM -0300, Paulo Zanoni wrote:
>> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>>
>> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> Hm, I think we should extract the same code from i9xx_crtc_set_mode, too
> and share it in a common intel_set_pipe_timings. Their almost identical
> safe for:
> - vsyncshift is only gen4+

This is easy to solve.

> - source position handling is a bit different, but I think it'd be
>   semantically clearer if we leave that out of set_pipe_timings. Imo that
>   belongs to the panel fitter settings, which are currently splattered all
>   over. Meh.

Well, the PIPESRC register is described inside the "pipe timings"
documentation section, so I think it should be inside the
set_pipe_timings function.

I actually implemented your suggestion locally and the only real
problem is that on i9xx_crtc_mode_set we currently write to DSPSIZE
and DSPPOS before writing to PIPESRC, so to make the code look good we
have 2 options:
1 - Write to DSPPOS and DSPSIZE before writing all the timing registers
2 - Write to DSPPOS and DSPSIZE after writing all the timing registers

In both cases we are changing the writing order. I looked at the
documentation and it seems we should be writing to the plane registers
only after setting the pipe registers, so maybe solution 2 is the
correct. The problem is that yes, we are changing the behavior and I
don't even have such machines to test.

So, how do we proceed here? Want the version, keep the old one, or do
something entirely different?

>
> Comments?
> -Daniel
>> ---
>>  drivers/gpu/drm/i915/intel_display.c |   82 +++++++++++++++++++---------------
>>  1 file changed, 46 insertions(+), 36 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index cf1e628..5a4e363 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -4690,6 +4690,51 @@ static void ironlake_set_pipeconf(struct drm_crtc *crtc,
>>       POSTING_READ(PIPECONF(pipe));
>>  }
>>
>> +static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
>> +                                   struct drm_display_mode *mode,
>> +                                   struct drm_display_mode *adjusted_mode)
>> +{
>> +     struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
>> +     enum pipe pipe = intel_crtc->pipe;
>> +
>> +     if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
>> +             /* the chip adds 2 halflines automatically */
>> +             adjusted_mode->crtc_vtotal -= 1;
>> +             adjusted_mode->crtc_vblank_end -= 1;
>> +             I915_WRITE(VSYNCSHIFT(pipe),
>> +                        adjusted_mode->crtc_hsync_start
>> +                        - adjusted_mode->crtc_htotal/2);
>> +     } else {
>> +             I915_WRITE(VSYNCSHIFT(pipe), 0);
>> +     }
>> +
>> +     I915_WRITE(HTOTAL(pipe),
>> +                (adjusted_mode->crtc_hdisplay - 1) |
>> +                ((adjusted_mode->crtc_htotal - 1) << 16));
>> +     I915_WRITE(HBLANK(pipe),
>> +                (adjusted_mode->crtc_hblank_start - 1) |
>> +                ((adjusted_mode->crtc_hblank_end - 1) << 16));
>> +     I915_WRITE(HSYNC(pipe),
>> +                (adjusted_mode->crtc_hsync_start - 1) |
>> +                ((adjusted_mode->crtc_hsync_end - 1) << 16));
>> +
>> +     I915_WRITE(VTOTAL(pipe),
>> +                (adjusted_mode->crtc_vdisplay - 1) |
>> +                ((adjusted_mode->crtc_vtotal - 1) << 16));
>> +     I915_WRITE(VBLANK(pipe),
>> +                (adjusted_mode->crtc_vblank_start - 1) |
>> +                ((adjusted_mode->crtc_vblank_end - 1) << 16));
>> +     I915_WRITE(VSYNC(pipe),
>> +                (adjusted_mode->crtc_vsync_start - 1) |
>> +                ((adjusted_mode->crtc_vsync_end - 1) << 16));
>> +
>> +     /* pipesrc controls the size that is scaled from, which should
>> +      * always be the user's requested size.
>> +      */
>> +     I915_WRITE(PIPESRC(pipe),
>> +                ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
>> +}
>> +
>>  static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>>                                 struct drm_display_mode *mode,
>>                                 struct drm_display_mode *adjusted_mode,
>> @@ -4970,42 +5015,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
>>               }
>>       }
>>
>> -     if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
>> -             /* the chip adds 2 halflines automatically */
>> -             adjusted_mode->crtc_vtotal -= 1;
>> -             adjusted_mode->crtc_vblank_end -= 1;
>> -             I915_WRITE(VSYNCSHIFT(pipe),
>> -                        adjusted_mode->crtc_hsync_start
>> -                        - adjusted_mode->crtc_htotal/2);
>> -     } else {
>> -             I915_WRITE(VSYNCSHIFT(pipe), 0);
>> -     }
>> -
>> -     I915_WRITE(HTOTAL(pipe),
>> -                (adjusted_mode->crtc_hdisplay - 1) |
>> -                ((adjusted_mode->crtc_htotal - 1) << 16));
>> -     I915_WRITE(HBLANK(pipe),
>> -                (adjusted_mode->crtc_hblank_start - 1) |
>> -                ((adjusted_mode->crtc_hblank_end - 1) << 16));
>> -     I915_WRITE(HSYNC(pipe),
>> -                (adjusted_mode->crtc_hsync_start - 1) |
>> -                ((adjusted_mode->crtc_hsync_end - 1) << 16));
>> -
>> -     I915_WRITE(VTOTAL(pipe),
>> -                (adjusted_mode->crtc_vdisplay - 1) |
>> -                ((adjusted_mode->crtc_vtotal - 1) << 16));
>> -     I915_WRITE(VBLANK(pipe),
>> -                (adjusted_mode->crtc_vblank_start - 1) |
>> -                ((adjusted_mode->crtc_vblank_end - 1) << 16));
>> -     I915_WRITE(VSYNC(pipe),
>> -                (adjusted_mode->crtc_vsync_start - 1) |
>> -                ((adjusted_mode->crtc_vsync_end - 1) << 16));
>> -
>> -     /* pipesrc controls the size that is scaled from, which should
>> -      * always be the user's requested size.
>> -      */
>> -     I915_WRITE(PIPESRC(pipe),
>> -                ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
>> +     ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
>>
>>       I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
>>       I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
Daniel Vetter Sept. 20, 2012, 7:32 a.m. UTC | #3
On Wed, Sep 19, 2012 at 03:11:33PM -0300, Paulo Zanoni wrote:
> Hi
> 
> 2012/9/12 Daniel Vetter <daniel@ffwll.ch>:
> > On Wed, Sep 12, 2012 at 10:06:31AM -0300, Paulo Zanoni wrote:
> >> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >>
> >> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> >
> > Hm, I think we should extract the same code from i9xx_crtc_set_mode, too
> > and share it in a common intel_set_pipe_timings. Their almost identical
> > safe for:
> > - vsyncshift is only gen4+
> 
> This is easy to solve.
> 
> > - source position handling is a bit different, but I think it'd be
> >   semantically clearer if we leave that out of set_pipe_timings. Imo that
> >   belongs to the panel fitter settings, which are currently splattered all
> >   over. Meh.
> 
> Well, the PIPESRC register is described inside the "pipe timings"
> documentation section, so I think it should be inside the
> set_pipe_timings function.
> 
> I actually implemented your suggestion locally and the only real
> problem is that on i9xx_crtc_mode_set we currently write to DSPSIZE
> and DSPPOS before writing to PIPESRC, so to make the code look good we
> have 2 options:
> 1 - Write to DSPPOS and DSPSIZE before writing all the timing registers
> 2 - Write to DSPPOS and DSPSIZE after writing all the timing registers
> 
> In both cases we are changing the writing order. I looked at the
> documentation and it seems we should be writing to the plane registers
> only after setting the pipe registers, so maybe solution 2 is the
> correct. The problem is that yes, we are changing the behavior and I
> don't even have such machines to test.
> 
> So, how do we proceed here? Want the version, keep the old one, or do
> something entirely different?

I guess a quick patch to move around the DSP* regs down and run it on a
few gen2/3 machines. Then move things around if it doesn't blow up. Since
I'm travelling I think you need to volunteer Chris for the testing ;-)
-Daniel
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cf1e628..5a4e363 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4690,6 +4690,51 @@  static void ironlake_set_pipeconf(struct drm_crtc *crtc,
 	POSTING_READ(PIPECONF(pipe));
 }
 
+static void ironlake_set_pipe_timings(struct intel_crtc *intel_crtc,
+				      struct drm_display_mode *mode,
+				      struct drm_display_mode *adjusted_mode)
+{
+	struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
+	enum pipe pipe = intel_crtc->pipe;
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		/* the chip adds 2 halflines automatically */
+		adjusted_mode->crtc_vtotal -= 1;
+		adjusted_mode->crtc_vblank_end -= 1;
+		I915_WRITE(VSYNCSHIFT(pipe),
+			   adjusted_mode->crtc_hsync_start
+			   - adjusted_mode->crtc_htotal/2);
+	} else {
+		I915_WRITE(VSYNCSHIFT(pipe), 0);
+	}
+
+	I915_WRITE(HTOTAL(pipe),
+		   (adjusted_mode->crtc_hdisplay - 1) |
+		   ((adjusted_mode->crtc_htotal - 1) << 16));
+	I915_WRITE(HBLANK(pipe),
+		   (adjusted_mode->crtc_hblank_start - 1) |
+		   ((adjusted_mode->crtc_hblank_end - 1) << 16));
+	I915_WRITE(HSYNC(pipe),
+		   (adjusted_mode->crtc_hsync_start - 1) |
+		   ((adjusted_mode->crtc_hsync_end - 1) << 16));
+
+	I915_WRITE(VTOTAL(pipe),
+		   (adjusted_mode->crtc_vdisplay - 1) |
+		   ((adjusted_mode->crtc_vtotal - 1) << 16));
+	I915_WRITE(VBLANK(pipe),
+		   (adjusted_mode->crtc_vblank_start - 1) |
+		   ((adjusted_mode->crtc_vblank_end - 1) << 16));
+	I915_WRITE(VSYNC(pipe),
+		   (adjusted_mode->crtc_vsync_start - 1) |
+		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
+
+	/* pipesrc controls the size that is scaled from, which should
+	 * always be the user's requested size.
+	 */
+	I915_WRITE(PIPESRC(pipe),
+		   ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
+}
+
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 				  struct drm_display_mode *mode,
 				  struct drm_display_mode *adjusted_mode,
@@ -4970,42 +5015,7 @@  static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
 		}
 	}
 
-	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
-		/* the chip adds 2 halflines automatically */
-		adjusted_mode->crtc_vtotal -= 1;
-		adjusted_mode->crtc_vblank_end -= 1;
-		I915_WRITE(VSYNCSHIFT(pipe),
-			   adjusted_mode->crtc_hsync_start
-			   - adjusted_mode->crtc_htotal/2);
-	} else {
-		I915_WRITE(VSYNCSHIFT(pipe), 0);
-	}
-
-	I915_WRITE(HTOTAL(pipe),
-		   (adjusted_mode->crtc_hdisplay - 1) |
-		   ((adjusted_mode->crtc_htotal - 1) << 16));
-	I915_WRITE(HBLANK(pipe),
-		   (adjusted_mode->crtc_hblank_start - 1) |
-		   ((adjusted_mode->crtc_hblank_end - 1) << 16));
-	I915_WRITE(HSYNC(pipe),
-		   (adjusted_mode->crtc_hsync_start - 1) |
-		   ((adjusted_mode->crtc_hsync_end - 1) << 16));
-
-	I915_WRITE(VTOTAL(pipe),
-		   (adjusted_mode->crtc_vdisplay - 1) |
-		   ((adjusted_mode->crtc_vtotal - 1) << 16));
-	I915_WRITE(VBLANK(pipe),
-		   (adjusted_mode->crtc_vblank_start - 1) |
-		   ((adjusted_mode->crtc_vblank_end - 1) << 16));
-	I915_WRITE(VSYNC(pipe),
-		   (adjusted_mode->crtc_vsync_start - 1) |
-		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
-
-	/* pipesrc controls the size that is scaled from, which should
-	 * always be the user's requested size.
-	 */
-	I915_WRITE(PIPESRC(pipe),
-		   ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
+	ironlake_set_pipe_timings(intel_crtc, mode, adjusted_mode);
 
 	I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
 	I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);