drm/i915: try harder to find WR PLL clock settings
authorPaulo Zanoni <paulo.r.zanoni@intel.com>
Fri, 10 Aug 2012 13:03:03 +0000 (10:03 -0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 10 Aug 2012 16:35:28 +0000 (18:35 +0200)
If we don't find the exact refresh rate, go with the next one. This
makes some modes work for me. They won't have the best settings, but
will at least have something. Just returning from this function when
we don't find the perfect settings does not help us at all.

Version 2:
  - Remove duplicate lines on the clock table.
  - Add back debug message with refresh, p, n2 and r2.

Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_ddi.c

index ff03a3a5719377e9854dbbb589e132c05d0a1c81..958422606bc73686f540ed3079a31668017664fe 100644 (file)
@@ -267,7 +267,8 @@ struct wrpll_tmds_clock {
        u16 r2;         /* Reference divider */
 };
 
-/* Table of matching values for WRPLL clocks programming for each frequency */
+/* Table of matching values for WRPLL clocks programming for each frequency.
+ * The code assumes this table is sorted. */
 static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
        {19750, 38,     25,     18},
        {20000, 48,     32,     18},
@@ -277,7 +278,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
        {23000, 36,     23,     15},
        {23500, 40,     40,     23},
        {23750, 26,     16,     14},
-       {23750, 26,     16,     14},
        {24000, 36,     24,     15},
        {25000, 36,     25,     15},
        {25175, 26,     40,     33},
@@ -437,7 +437,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
        {108000,        8,      24,     15},
        {108108,        8,      173,    108},
        {109000,        6,      23,     19},
-       {109000,        6,      23,     19},
        {110000,        6,      22,     18},
        {110013,        6,      22,     18},
        {110250,        8,      49,     30},
@@ -614,7 +613,6 @@ static const struct wrpll_tmds_clock wrpll_tmds_clock_table[] = {
        {218250,        4,      42,     26},
        {218750,        4,      34,     21},
        {219000,        4,      47,     29},
-       {219000,        4,      47,     29},
        {220000,        4,      44,     27},
        {220640,        4,      49,     30},
        {220750,        4,      36,     22},
@@ -658,7 +656,7 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
        struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
        int port = intel_hdmi->ddi_port;
        int pipe = intel_crtc->pipe;
-       int p, n2, r2, valid=0;
+       int p, n2, r2;
        u32 temp, i;
 
        /* On Haswell, we need to enable the clocks and prepare DDI function to
@@ -666,26 +664,23 @@ void intel_ddi_mode_set(struct drm_encoder *encoder,
         */
        DRM_DEBUG_KMS("Preparing HDMI DDI mode for Haswell on port %c, pipe %c\n", port_name(port), pipe_name(pipe));
 
-       for (i=0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++) {
-               if (crtc->mode.clock == wrpll_tmds_clock_table[i].clock) {
-                       p = wrpll_tmds_clock_table[i].p;
-                       n2 = wrpll_tmds_clock_table[i].n2;
-                       r2 = wrpll_tmds_clock_table[i].r2;
+       for (i = 0; i < ARRAY_SIZE(wrpll_tmds_clock_table); i++)
+               if (crtc->mode.clock <= wrpll_tmds_clock_table[i].clock)
+                       break;
 
-                       DRM_DEBUG_KMS("WR PLL clock: found settings for %dKHz refresh rate: p=%d, n2=%d, r2=%d\n",
-                                       crtc->mode.clock,
-                                       p, n2, r2);
+       if (i == ARRAY_SIZE(wrpll_tmds_clock_table))
+               i--;
 
-                       valid = 1;
-                       break;
-               }
-       }
+       p = wrpll_tmds_clock_table[i].p;
+       n2 = wrpll_tmds_clock_table[i].n2;
+       r2 = wrpll_tmds_clock_table[i].r2;
 
-       if (!valid) {
-               DRM_ERROR("Unable to find WR PLL clock settings for %dKHz refresh rate\n",
-                               crtc->mode.clock);
-               return;
-       }
+       if (wrpll_tmds_clock_table[i].clock != crtc->mode.clock)
+               DRM_INFO("WR PLL: using settings for %dKHz on %dKHz mode\n",
+                        wrpll_tmds_clock_table[i].clock, crtc->mode.clock);
+
+       DRM_DEBUG_KMS("WR PLL: %dKHz refresh rate with p=%d, n2=%d r2=%d\n",
+                     crtc->mode.clock, p, n2, r2);
 
        /* Enable LCPLL if disabled */
        temp = I915_READ(LCPLL_CTL);