drm/i915: Use the real FDI frequency for determining b/w
authorChris Wilson <chris@chris-wilson.co.uk>
Tue, 7 Sep 2010 19:54:59 +0000 (20:54 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 10 Sep 2010 22:13:51 +0000 (23:13 +0100)
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h

index d0b4b2375d56be3bad0797846a42bada3f887833..fbf58e0f25889aa284cc3c76bbf0cd51bf308463 100644 (file)
 #define  RR_HW_HIGH_POWER_FRAMES_MASK   0xff00
 
 #define FDI_PLL_BIOS_0  0x46000
+#define  FDI_PLL_FB_CLOCK_MASK  0xff
 #define FDI_PLL_BIOS_1  0x46004
 #define FDI_PLL_BIOS_2  0x46008
 #define DISPLAY_PORT_PLL_BIOS_0         0x4600c
index df410e4827e42d1fafb7db5cbb06d25de9eb3ede..5279b0c88e9cf500d7c464a962f71e8c4167a50a 100644 (file)
@@ -342,6 +342,13 @@ static bool
 intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc,
                           int target, int refclk, intel_clock_t *best_clock);
 
+static inline u32 /* units of 100MHz */
+intel_fdi_link_freq(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2;
+}
+
 static const intel_limit_t intel_limits_i8xx_dvo = {
         .dot = { .min = I8XX_DOT_MIN,          .max = I8XX_DOT_MAX },
         .vco = { .min = I8XX_VCO_MIN,          .max = I8XX_VCO_MAX },
@@ -3767,7 +3774,15 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                                target_clock = mode->clock;
                        else
                                target_clock = adjusted_mode->clock;
-                       link_bw = 270000;
+
+                       /* FDI is a binary signal running at ~2.7GHz, encoding
+                        * each output octet as 10 bits. The actual frequency
+                        * is stored as a divider into a 100MHz clock, and the
+                        * mode pixel clock is stored in units of 1KHz.
+                        * Hence the bw of each lane in terms of the mode signal
+                        * is:
+                        */
+                       link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
                }
 
                /* determine panel color depth */
index 1ada684ea569aa4b3416eae2c1c3bb3e07594368..6c6b897539f891a2ea65f67f1e10b8ffd32af401 100644 (file)
@@ -49,6 +49,9 @@
 #define wait_for(COND, MS) _wait_for(COND, MS, 1)
 #define wait_for_atomic(COND, MS) _wait_for(COND, MS, 0)
 
+#define KHz(x) (1000*x)
+#define MHz(x) KHz(1000*x)
+
 /*
  * Display related stuff
  */