diff mbox

[6/9] drm/i915: extract common link_m_n helpers

Message ID 1352120854-16533-7-git-send-email-daniel.vetter@ffwll.ch (mailing list archive)
State New, archived
Headers show

Commit Message

Daniel Vetter Nov. 5, 2012, 1:07 p.m. UTC
Both the dp and fdi code use the exact same computations (ignore minor
differences in conversion between bits and bytes).

This makes it even more apparent that we have a _massive_ mess between
cpu transcoder/fdi link/pch transcoder and pch link settings. And also
that we have hilarious amounts of confusion between edp and dp
(despite that they're identical at a link level).

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_drv.h      | 13 ++++++++++++
 drivers/gpu/drm/i915/intel_display.c | 31 +++++++++-------------------
 drivers/gpu/drm/i915/intel_dp.c      | 39 +++---------------------------------
 3 files changed, 26 insertions(+), 57 deletions(-)

Comments

Paulo Zanoni Nov. 20, 2012, 11:24 a.m. UTC | #1
Hi

2012/11/5 Daniel Vetter <daniel.vetter@ffwll.ch>:
> Both the dp and fdi code use the exact same computations (ignore minor
> differences in conversion between bits and bytes).
>
> This makes it even more apparent that we have a _massive_ mess between
> cpu transcoder/fdi link/pch transcoder and pch link settings. And also
> that we have hilarious amounts of confusion between edp and dp
> (despite that they're identical at a link level).
>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>

This is certainly a first improvement to the m_n code and doing the
exact same thing as you did was even on my TODO list. I think there's
a lot more to do, but this patch is certainly the first step. There is
just one minor bikeshed below:

> ---
>  drivers/gpu/drm/i915/i915_drv.h      | 13 ++++++++++++
>  drivers/gpu/drm/i915/intel_display.c | 31 +++++++++-------------------
>  drivers/gpu/drm/i915/intel_dp.c      | 39 +++---------------------------------
>  3 files changed, 26 insertions(+), 57 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index c4339c2..23cea8f 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -101,6 +101,19 @@ struct intel_pch_pll {
>  };
>  #define I915_NUM_PLLS 2
>
> +/* Used by dp and fdi links */
> +struct intel_link_m_n {
> +       uint32_t        tu;
> +       uint32_t        gmch_m;
> +       uint32_t        gmch_n;
> +       uint32_t        link_m;
> +       uint32_t        link_n;
> +};
> +
> +void intel_link_compute_m_n(int bpp, int nlanes,
> +                           int pixel_clock, int link_clock,
> +                           struct intel_link_m_n *m_n);
> +
>  struct intel_ddi_plls {
>         int spll_refcount;
>         int wrpll1_refcount;
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 0c923a6..5432e9c 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3956,16 +3956,8 @@ static int i830_get_display_clock_speed(struct drm_device *dev)
>         return 133000;
>  }
>
> -struct fdi_m_n {
> -       u32        tu;
> -       u32        gmch_m;
> -       u32        gmch_n;
> -       u32        link_m;
> -       u32        link_n;
> -};
> -
>  static void
> -fdi_reduce_ratio(u32 *num, u32 *den)
> +intel_reduce_ratio(uint32_t *num, uint32_t *den)
>  {
>         while (*num > 0xffffff || *den > 0xffffff) {
>                 *num >>= 1;
> @@ -3973,20 +3965,18 @@ fdi_reduce_ratio(u32 *num, u32 *den)
>         }
>  }
>
> -static void
> -ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
> -                    int link_clock, struct fdi_m_n *m_n)
> +void
> +intel_link_compute_m_n(int bits_per_pixel, int nlanes,
> +                      int pixel_clock, int link_clock,
> +                      struct intel_link_m_n *m_n)
>  {
> -       m_n->tu = 64; /* default size */
> -
> -       /* BUG_ON(pixel_clock > INT_MAX / 36); */
> +       m_n->tu = 64;
>         m_n->gmch_m = bits_per_pixel * pixel_clock;
>         m_n->gmch_n = link_clock * nlanes * 8;

I think here we should keep the gmch_m and gmch_n calculations used in
the DP code instead of this one, since it matches the spec a little
better... The spec says that gmch_m should be "dot clock * bytes per
pixel" and gmch_n should be "ls_clk * number of lanes". So the lines
that are currently inside intel_dp_compute_m_n look better:

       m_n->gmch_m = (pixel_clock * bpp) >> 3;
       m_n->gmch_n = link_clock * nlanes;

(Also, in this case we'll need even higher numbers before we overflow)

I applied a version with the DP values locally and tested. So my
version of this patch is Reviewed-by and Tested-by me.

> -       fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
> -
> +       intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
>         m_n->link_m = pixel_clock;
>         m_n->link_n = link_clock;
> -       fdi_reduce_ratio(&m_n->link_m, &m_n->link_n);
> +       intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
>  }
>
>  static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
> @@ -5100,7 +5090,7 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>         enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
>         struct intel_encoder *intel_encoder, *edp_encoder = NULL;
> -       struct fdi_m_n m_n = {0};
> +       struct intel_link_m_n m_n = {0};
>         int target_clock, pixel_multiplier, lane, link_bw;
>         bool is_dp = false, is_cpu_edp = false;
>
> @@ -5158,8 +5148,7 @@ static void ironlake_set_m_n(struct drm_crtc *crtc,
>
>         if (pixel_multiplier > 1)
>                 link_bw *= pixel_multiplier;
> -       ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
> -                            &m_n);
> +       intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n);
>
>         I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m);
>         I915_WRITE(PIPE_DATA_N1(cpu_transcoder), m_n.gmch_n);
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index 8ec4d1c..5d8ae65 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -742,39 +742,6 @@ intel_dp_mode_fixup(struct drm_encoder *encoder,
>         return false;
>  }
>
> -struct intel_dp_m_n {
> -       uint32_t        tu;
> -       uint32_t        gmch_m;
> -       uint32_t        gmch_n;
> -       uint32_t        link_m;
> -       uint32_t        link_n;
> -};
> -
> -static void
> -intel_reduce_ratio(uint32_t *num, uint32_t *den)
> -{
> -       while (*num > 0xffffff || *den > 0xffffff) {
> -               *num >>= 1;
> -               *den >>= 1;
> -       }
> -}
> -
> -static void
> -intel_dp_compute_m_n(int bpp,
> -                    int nlanes,
> -                    int pixel_clock,
> -                    int link_clock,
> -                    struct intel_dp_m_n *m_n)
> -{
> -       m_n->tu = 64;
> -       m_n->gmch_m = (pixel_clock * bpp) >> 3;
> -       m_n->gmch_n = link_clock * nlanes;
> -       intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
> -       m_n->link_m = pixel_clock;
> -       m_n->link_n = link_clock;
> -       intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
> -}
> -
>  void
>  intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
>                  struct drm_display_mode *adjusted_mode)
> @@ -785,7 +752,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>         int lane_count = 4;
> -       struct intel_dp_m_n m_n;
> +       struct intel_link_m_n m_n;
>         int pipe = intel_crtc->pipe;
>         enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
>
> @@ -808,8 +775,8 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
>          * the number of bytes_per_pixel post-LUT, which we always
>          * set up for 8-bits of R/G/B, or 3 bytes total.
>          */
> -       intel_dp_compute_m_n(intel_crtc->bpp, lane_count,
> -                            mode->clock, adjusted_mode->clock, &m_n);
> +       intel_link_compute_m_n(intel_crtc->bpp, lane_count,
> +                              mode->clock, adjusted_mode->clock, &m_n);
>
>         if (IS_HASWELL(dev)) {
>                 I915_WRITE(PIPE_DATA_M1(cpu_transcoder),
> --
> 1.7.11.7
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Daniel Vetter Nov. 20, 2012, 11:38 a.m. UTC | #2
On Tue, Nov 20, 2012 at 12:24 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> I think here we should keep the gmch_m and gmch_n calculations used in
> the DP code instead of this one, since it matches the spec a little
> better... The spec says that gmch_m should be "dot clock * bytes per
> pixel" and gmch_n should be "ls_clk * number of lanes". So the lines
> that are currently inside intel_dp_compute_m_n look better:
>
>        m_n->gmch_m = (pixel_clock * bpp) >> 3;
>        m_n->gmch_n = link_clock * nlanes;
>
> (Also, in this case we'll need even higher numbers before we overflow)
>
> I applied a version with the DP values locally and tested. So my
> version of this patch is Reviewed-by and Tested-by me.

How exactly should dot_clock * bytes_per_pixel work for e.g. 6bpc?
Note that the above essentially just does part of the ratio reduction
intel_reduce does and doesn't gain us any headroom for overflows,
since in both cases we compute pixel_clock * bpp. The only difference
is that we don't compute link_clock *nlanes * 8, but since the data
can (almost) fill the link bw, we don't really gain anything.

So imo computing the ration of bits that flow through the link is much
more natural, and trying to compute the ration as bytes only
obfuscates things.
-Daniel
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c4339c2..23cea8f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -101,6 +101,19 @@  struct intel_pch_pll {
 };
 #define I915_NUM_PLLS 2
 
+/* Used by dp and fdi links */
+struct intel_link_m_n {
+	uint32_t	tu;
+	uint32_t	gmch_m;
+	uint32_t	gmch_n;
+	uint32_t	link_m;
+	uint32_t	link_n;
+};
+
+void intel_link_compute_m_n(int bpp, int nlanes,
+			    int pixel_clock, int link_clock,
+			    struct intel_link_m_n *m_n);
+
 struct intel_ddi_plls {
 	int spll_refcount;
 	int wrpll1_refcount;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0c923a6..5432e9c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3956,16 +3956,8 @@  static int i830_get_display_clock_speed(struct drm_device *dev)
 	return 133000;
 }
 
-struct fdi_m_n {
-	u32        tu;
-	u32        gmch_m;
-	u32        gmch_n;
-	u32        link_m;
-	u32        link_n;
-};
-
 static void
-fdi_reduce_ratio(u32 *num, u32 *den)
+intel_reduce_ratio(uint32_t *num, uint32_t *den)
 {
 	while (*num > 0xffffff || *den > 0xffffff) {
 		*num >>= 1;
@@ -3973,20 +3965,18 @@  fdi_reduce_ratio(u32 *num, u32 *den)
 	}
 }
 
-static void
-ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock,
-		     int link_clock, struct fdi_m_n *m_n)
+void
+intel_link_compute_m_n(int bits_per_pixel, int nlanes,
+		       int pixel_clock, int link_clock,
+		       struct intel_link_m_n *m_n)
 {
-	m_n->tu = 64; /* default size */
-
-	/* BUG_ON(pixel_clock > INT_MAX / 36); */
+	m_n->tu = 64;
 	m_n->gmch_m = bits_per_pixel * pixel_clock;
 	m_n->gmch_n = link_clock * nlanes * 8;
-	fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
-
+	intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
 	m_n->link_m = pixel_clock;
 	m_n->link_n = link_clock;
-	fdi_reduce_ratio(&m_n->link_m, &m_n->link_n);
+	intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
 }
 
 static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv)
@@ -5100,7 +5090,7 @@  static void ironlake_set_m_n(struct drm_crtc *crtc,
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
 	struct intel_encoder *intel_encoder, *edp_encoder = NULL;
-	struct fdi_m_n m_n = {0};
+	struct intel_link_m_n m_n = {0};
 	int target_clock, pixel_multiplier, lane, link_bw;
 	bool is_dp = false, is_cpu_edp = false;
 
@@ -5158,8 +5148,7 @@  static void ironlake_set_m_n(struct drm_crtc *crtc,
 
 	if (pixel_multiplier > 1)
 		link_bw *= pixel_multiplier;
-	ironlake_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw,
-			     &m_n);
+	intel_link_compute_m_n(intel_crtc->bpp, lane, target_clock, link_bw, &m_n);
 
 	I915_WRITE(PIPE_DATA_M1(cpu_transcoder), TU_SIZE(m_n.tu) | m_n.gmch_m);
 	I915_WRITE(PIPE_DATA_N1(cpu_transcoder), m_n.gmch_n);
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 8ec4d1c..5d8ae65 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -742,39 +742,6 @@  intel_dp_mode_fixup(struct drm_encoder *encoder,
 	return false;
 }
 
-struct intel_dp_m_n {
-	uint32_t	tu;
-	uint32_t	gmch_m;
-	uint32_t	gmch_n;
-	uint32_t	link_m;
-	uint32_t	link_n;
-};
-
-static void
-intel_reduce_ratio(uint32_t *num, uint32_t *den)
-{
-	while (*num > 0xffffff || *den > 0xffffff) {
-		*num >>= 1;
-		*den >>= 1;
-	}
-}
-
-static void
-intel_dp_compute_m_n(int bpp,
-		     int nlanes,
-		     int pixel_clock,
-		     int link_clock,
-		     struct intel_dp_m_n *m_n)
-{
-	m_n->tu = 64;
-	m_n->gmch_m = (pixel_clock * bpp) >> 3;
-	m_n->gmch_n = link_clock * nlanes;
-	intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n);
-	m_n->link_m = pixel_clock;
-	m_n->link_n = link_clock;
-	intel_reduce_ratio(&m_n->link_m, &m_n->link_n);
-}
-
 void
 intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 		 struct drm_display_mode *adjusted_mode)
@@ -785,7 +752,7 @@  intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int lane_count = 4;
-	struct intel_dp_m_n m_n;
+	struct intel_link_m_n m_n;
 	int pipe = intel_crtc->pipe;
 	enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder;
 
@@ -808,8 +775,8 @@  intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode,
 	 * the number of bytes_per_pixel post-LUT, which we always
 	 * set up for 8-bits of R/G/B, or 3 bytes total.
 	 */
-	intel_dp_compute_m_n(intel_crtc->bpp, lane_count,
-			     mode->clock, adjusted_mode->clock, &m_n);
+	intel_link_compute_m_n(intel_crtc->bpp, lane_count,
+			       mode->clock, adjusted_mode->clock, &m_n);
 
 	if (IS_HASWELL(dev)) {
 		I915_WRITE(PIPE_DATA_M1(cpu_transcoder),