};
 
 static const intel_limit_t intel_limits_vlv = {
-       .dot = { .min = 25000, .max = 270000 },
+        /*
+         * These are the data rate limits (measured in fast clocks)
+         * since those are the strictest limits we have. The fast
+         * clock and actual rate limits are more relaxed, so checking
+         * them would make no difference.
+         */
+       .dot = { .min = 25000 * 5, .max = 270000 * 5 },
        .vco = { .min = 4000000, .max = 6000000 },
        .n = { .min = 1, .max = 7 },
        .m1 = { .min = 2, .max = 3 },
                               const intel_limit_t *limit,
                               const intel_clock_t *clock)
 {
+       if (clock->n   < limit->n.min   || limit->n.max   < clock->n)
+               INTELPllInvalid("n out of range\n");
        if (clock->p1  < limit->p1.min  || limit->p1.max  < clock->p1)
                INTELPllInvalid("p1 out of range\n");
-       if (clock->p   < limit->p.min   || limit->p.max   < clock->p)
-               INTELPllInvalid("p out of range\n");
        if (clock->m2  < limit->m2.min  || limit->m2.max  < clock->m2)
                INTELPllInvalid("m2 out of range\n");
        if (clock->m1  < limit->m1.min  || limit->m1.max  < clock->m1)
                INTELPllInvalid("m1 out of range\n");
-       if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev))
-               INTELPllInvalid("m1 <= m2\n");
-       if (clock->m   < limit->m.min   || limit->m.max   < clock->m)
-               INTELPllInvalid("m out of range\n");
-       if (clock->n   < limit->n.min   || limit->n.max   < clock->n)
-               INTELPllInvalid("n out of range\n");
+
+       if (!IS_PINEVIEW(dev) && !IS_VALLEYVIEW(dev))
+               if (clock->m1 <= clock->m2)
+                       INTELPllInvalid("m1 <= m2\n");
+
+       if (!IS_VALLEYVIEW(dev)) {
+               if (clock->p < limit->p.min || limit->p.max < clock->p)
+                       INTELPllInvalid("p out of range\n");
+               if (clock->m < limit->m.min || limit->m.max < clock->m)
+                       INTELPllInvalid("m out of range\n");
+       }
+
        if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
                INTELPllInvalid("vco out of range\n");
        /* XXX: We may need to be checking "Dot clock" depending on the multiplier,
                   int target, int refclk, intel_clock_t *match_clock,
                   intel_clock_t *best_clock)
 {
+       struct drm_device *dev = crtc->dev;
        intel_clock_t clock;
        unsigned int bestppm = 1000000;
        /* min update 19.2 MHz */
 
                                        vlv_clock(refclk, &clock);
 
-                                       if (clock.vco < limit->vco.min ||
-                                           clock.vco >= limit->vco.max)
+                                       if (!intel_PLL_is_valid(dev, limit,
+                                                               &clock))
                                                continue;
 
                                        diff = abs(clock.dot - target);