drm/i915: Use documented PLL timing limits for G4X platform
authorMa Ling <ling.ma@intel.com>
Wed, 18 Mar 2009 12:13:23 +0000 (20:13 +0800)
committerEric Anholt <eric@anholt.net>
Fri, 27 Mar 2009 21:45:11 +0000 (14:45 -0700)
The values come from the internal reference spreadsheet on PLL
timing limits for the G4X chipsets.

Part of fixing fd.o bug #17508

Signed-off-by: Ma Ling <ling.ma@intel.com>
[anholt: Cleaned up some whitespace]
Signed-off-by: Eric Anholt <eric@anholt.net>
drivers/gpu/drm/i915/intel_display.c

index a283427..89f7af0 100644 (file)
@@ -115,6 +115,89 @@ typedef struct {
 #define INTEL_LIMIT_I8XX_LVDS      1
 #define INTEL_LIMIT_I9XX_SDVO_DAC   2
 #define INTEL_LIMIT_I9XX_LVDS      3
+#define INTEL_LIMIT_G4X_SDVO       4
+#define INTEL_LIMIT_G4X_HDMI_DAC   5
+#define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS   6
+#define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS   7
+
+/*The parameter is for SDVO on G4x platform*/
+#define G4X_DOT_SDVO_MIN           25000
+#define G4X_DOT_SDVO_MAX           270000
+#define G4X_VCO_MIN                1750000
+#define G4X_VCO_MAX                3500000
+#define G4X_N_SDVO_MIN             1
+#define G4X_N_SDVO_MAX             4
+#define G4X_M_SDVO_MIN             104
+#define G4X_M_SDVO_MAX             138
+#define G4X_M1_SDVO_MIN            17
+#define G4X_M1_SDVO_MAX            23
+#define G4X_M2_SDVO_MIN            5
+#define G4X_M2_SDVO_MAX            11
+#define G4X_P_SDVO_MIN             10
+#define G4X_P_SDVO_MAX             30
+#define G4X_P1_SDVO_MIN            1
+#define G4X_P1_SDVO_MAX            3
+#define G4X_P2_SDVO_SLOW           10
+#define G4X_P2_SDVO_FAST           10
+#define G4X_P2_SDVO_LIMIT          270000
+
+/*The parameter is for HDMI_DAC on G4x platform*/
+#define G4X_DOT_HDMI_DAC_MIN           22000
+#define G4X_DOT_HDMI_DAC_MAX           400000
+#define G4X_N_HDMI_DAC_MIN             1
+#define G4X_N_HDMI_DAC_MAX             4
+#define G4X_M_HDMI_DAC_MIN             104
+#define G4X_M_HDMI_DAC_MAX             138
+#define G4X_M1_HDMI_DAC_MIN            16
+#define G4X_M1_HDMI_DAC_MAX            23
+#define G4X_M2_HDMI_DAC_MIN            5
+#define G4X_M2_HDMI_DAC_MAX            11
+#define G4X_P_HDMI_DAC_MIN             5
+#define G4X_P_HDMI_DAC_MAX             80
+#define G4X_P1_HDMI_DAC_MIN            1
+#define G4X_P1_HDMI_DAC_MAX            8
+#define G4X_P2_HDMI_DAC_SLOW           10
+#define G4X_P2_HDMI_DAC_FAST           5
+#define G4X_P2_HDMI_DAC_LIMIT          165000
+
+/*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/
+#define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN           20000
+#define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX           115000
+#define G4X_N_SINGLE_CHANNEL_LVDS_MIN             1
+#define G4X_N_SINGLE_CHANNEL_LVDS_MAX             3
+#define G4X_M_SINGLE_CHANNEL_LVDS_MIN             104
+#define G4X_M_SINGLE_CHANNEL_LVDS_MAX             138
+#define G4X_M1_SINGLE_CHANNEL_LVDS_MIN            17
+#define G4X_M1_SINGLE_CHANNEL_LVDS_MAX            23
+#define G4X_M2_SINGLE_CHANNEL_LVDS_MIN            5
+#define G4X_M2_SINGLE_CHANNEL_LVDS_MAX            11
+#define G4X_P_SINGLE_CHANNEL_LVDS_MIN             28
+#define G4X_P_SINGLE_CHANNEL_LVDS_MAX             112
+#define G4X_P1_SINGLE_CHANNEL_LVDS_MIN            2
+#define G4X_P1_SINGLE_CHANNEL_LVDS_MAX            8
+#define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW           14
+#define G4X_P2_SINGLE_CHANNEL_LVDS_FAST           14
+#define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT          0
+
+/*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/
+#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN           80000
+#define G4X_DOT_DUAL_CHANNEL_LVDS_MAX           224000
+#define G4X_N_DUAL_CHANNEL_LVDS_MIN             1
+#define G4X_N_DUAL_CHANNEL_LVDS_MAX             3
+#define G4X_M_DUAL_CHANNEL_LVDS_MIN             104
+#define G4X_M_DUAL_CHANNEL_LVDS_MAX             138
+#define G4X_M1_DUAL_CHANNEL_LVDS_MIN            17
+#define G4X_M1_DUAL_CHANNEL_LVDS_MAX            23
+#define G4X_M2_DUAL_CHANNEL_LVDS_MIN            5
+#define G4X_M2_DUAL_CHANNEL_LVDS_MAX            11
+#define G4X_P_DUAL_CHANNEL_LVDS_MIN             14
+#define G4X_P_DUAL_CHANNEL_LVDS_MAX             42
+#define G4X_P1_DUAL_CHANNEL_LVDS_MIN            2
+#define G4X_P1_DUAL_CHANNEL_LVDS_MAX            6
+#define G4X_P2_DUAL_CHANNEL_LVDS_SLOW           7
+#define G4X_P2_DUAL_CHANNEL_LVDS_FAST           7
+#define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT          0
+
 
 static const intel_limit_t intel_limits[] = {
     { /* INTEL_LIMIT_I8XX_DVO_DAC */
@@ -168,14 +251,116 @@ static const intel_limit_t intel_limits[] = {
        .p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
                 .p2_slow = I9XX_P2_LVDS_SLOW,  .p2_fast = I9XX_P2_LVDS_FAST },
     },
+    /* below parameter and function is for G4X Chipset Family*/
+    { /* INTEL_LIMIT_G4X_SDVO */
+       .dot = { .min = G4X_DOT_SDVO_MIN,       .max = G4X_DOT_SDVO_MAX },
+       .vco = { .min = G4X_VCO_MIN,            .max = G4X_VCO_MAX},
+       .n   = { .min = G4X_N_SDVO_MIN,         .max = G4X_N_SDVO_MAX },
+       .m   = { .min = G4X_M_SDVO_MIN,         .max = G4X_M_SDVO_MAX },
+       .m1  = { .min = G4X_M1_SDVO_MIN,        .max = G4X_M1_SDVO_MAX },
+       .m2  = { .min = G4X_M2_SDVO_MIN,        .max = G4X_M2_SDVO_MAX },
+       .p   = { .min = G4X_P_SDVO_MIN,         .max = G4X_P_SDVO_MAX },
+       .p1  = { .min = G4X_P1_SDVO_MIN,        .max = G4X_P1_SDVO_MAX},
+       .p2  = { .dot_limit = G4X_P2_SDVO_LIMIT,
+                .p2_slow = G4X_P2_SDVO_SLOW,
+                .p2_fast = G4X_P2_SDVO_FAST
+       },
+    },
+    { /* INTEL_LIMIT_G4X_HDMI_DAC */
+       .dot = { .min = G4X_DOT_HDMI_DAC_MIN,   .max = G4X_DOT_HDMI_DAC_MAX },
+       .vco = { .min = G4X_VCO_MIN,            .max = G4X_VCO_MAX},
+       .n   = { .min = G4X_N_HDMI_DAC_MIN,     .max = G4X_N_HDMI_DAC_MAX },
+       .m   = { .min = G4X_M_HDMI_DAC_MIN,     .max = G4X_M_HDMI_DAC_MAX },
+       .m1  = { .min = G4X_M1_HDMI_DAC_MIN,    .max = G4X_M1_HDMI_DAC_MAX },
+       .m2  = { .min = G4X_M2_HDMI_DAC_MIN,    .max = G4X_M2_HDMI_DAC_MAX },
+       .p   = { .min = G4X_P_HDMI_DAC_MIN,     .max = G4X_P_HDMI_DAC_MAX },
+       .p1  = { .min = G4X_P1_HDMI_DAC_MIN,    .max = G4X_P1_HDMI_DAC_MAX},
+       .p2  = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT,
+                .p2_slow = G4X_P2_HDMI_DAC_SLOW,
+                .p2_fast = G4X_P2_HDMI_DAC_FAST
+       },
+    },
+    { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */
+       .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN,
+                .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX },
+       .vco = { .min = G4X_VCO_MIN,
+                .max = G4X_VCO_MAX },
+       .n   = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN,
+                .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX },
+       .m   = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN,
+                .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX },
+       .m1  = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN,
+                .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX },
+       .m2  = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN,
+                .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX },
+       .p   = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN,
+                .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX },
+       .p1  = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN,
+                .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX },
+       .p2  = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT,
+                .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW,
+                .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
+       },
+    },
+    { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */
+       .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN,
+                .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX },
+       .vco = { .min = G4X_VCO_MIN,
+                .max = G4X_VCO_MAX },
+       .n   = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN,
+                .max = G4X_N_DUAL_CHANNEL_LVDS_MAX },
+       .m   = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN,
+                .max = G4X_M_DUAL_CHANNEL_LVDS_MAX },
+       .m1  = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN,
+                .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX },
+       .m2  = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN,
+                .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX },
+       .p   = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN,
+                .max = G4X_P_DUAL_CHANNEL_LVDS_MAX },
+       .p1  = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN,
+                .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX },
+       .p2  = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT,
+                .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW,
+                .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
+       },
+    },
 };
 
+static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       const intel_limit_t *limit;
+
+       if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
+               if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
+                   LVDS_CLKB_POWER_UP)
+                       /* LVDS with dual channel */
+                       limit = &intel_limits
+                                       [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS];
+               else
+                       /* LVDS with dual channel */
+                       limit = &intel_limits
+                                       [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS];
+       } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) ||
+                  intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
+               limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC];
+       } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) {
+               limit = &intel_limits[INTEL_LIMIT_G4X_SDVO];
+       } else /* The option is for other outputs */
+               limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+
+       return limit;
+}
+
 static const intel_limit_t *intel_limit(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
        const intel_limit_t *limit;
 
-       if (IS_I9XX(dev)) {
+       if (IS_G4X(dev)) {
+               limit = intel_g4x_limit(crtc);
+       } else if (IS_I9XX(dev)) {
                if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
                        limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
                else