Revert "drm/i915: Don't enable pipe/plane/VCO early (wait for DPMS on)."
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_display.c
index e94d1db35364e6bc983ae2fa28bb81e0aa89a939..cc8131ff319f3f0d243a15c0ddd924c1a93b8147 100644 (file)
@@ -1248,10 +1248,11 @@ static void intel_update_fbc(struct drm_crtc *crtc,
        return;
 
 out_disable:
-       DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
        /* Multiple disables should be harmless */
-       if (intel_fbc_enabled(dev))
+       if (intel_fbc_enabled(dev)) {
+               DRM_DEBUG_KMS("unsupported config, disabling FBC\n");
                intel_disable_fbc(dev);
+       }
 }
 
 static int
@@ -1395,7 +1396,8 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
        Start = obj_priv->gtt_offset;
        Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
 
-       DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+       DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
+                     Start, Offset, x, y, crtc->fb->pitch);
        I915_WRITE(dspstride, crtc->fb->pitch);
        if (IS_I965G(dev)) {
                I915_WRITE(dspbase, Offset);
@@ -2640,6 +2642,7 @@ static unsigned long intel_calculate_wm(unsigned long clock_in_khz,
 
 struct cxsr_latency {
        int is_desktop;
+       int is_ddr3;
        unsigned long fsb_freq;
        unsigned long mem_freq;
        unsigned long display_sr;
@@ -2649,33 +2652,45 @@ struct cxsr_latency {
 };
 
 static struct cxsr_latency cxsr_latency_table[] = {
-       {1, 800, 400, 3382, 33382, 3983, 33983},    /* DDR2-400 SC */
-       {1, 800, 667, 3354, 33354, 3807, 33807},    /* DDR2-667 SC */
-       {1, 800, 800, 3347, 33347, 3763, 33763},    /* DDR2-800 SC */
-
-       {1, 667, 400, 3400, 33400, 4021, 34021},    /* DDR2-400 SC */
-       {1, 667, 667, 3372, 33372, 3845, 33845},    /* DDR2-667 SC */
-       {1, 667, 800, 3386, 33386, 3822, 33822},    /* DDR2-800 SC */
-
-       {1, 400, 400, 3472, 33472, 4173, 34173},    /* DDR2-400 SC */
-       {1, 400, 667, 3443, 33443, 3996, 33996},    /* DDR2-667 SC */
-       {1, 400, 800, 3430, 33430, 3946, 33946},    /* DDR2-800 SC */
-
-       {0, 800, 400, 3438, 33438, 4065, 34065},    /* DDR2-400 SC */
-       {0, 800, 667, 3410, 33410, 3889, 33889},    /* DDR2-667 SC */
-       {0, 800, 800, 3403, 33403, 3845, 33845},    /* DDR2-800 SC */
-
-       {0, 667, 400, 3456, 33456, 4103, 34106},    /* DDR2-400 SC */
-       {0, 667, 667, 3428, 33428, 3927, 33927},    /* DDR2-667 SC */
-       {0, 667, 800, 3443, 33443, 3905, 33905},    /* DDR2-800 SC */
-
-       {0, 400, 400, 3528, 33528, 4255, 34255},    /* DDR2-400 SC */
-       {0, 400, 667, 3500, 33500, 4079, 34079},    /* DDR2-667 SC */
-       {0, 400, 800, 3487, 33487, 4029, 34029},    /* DDR2-800 SC */
+       {1, 0, 800, 400, 3382, 33382, 3983, 33983},    /* DDR2-400 SC */
+       {1, 0, 800, 667, 3354, 33354, 3807, 33807},    /* DDR2-667 SC */
+       {1, 0, 800, 800, 3347, 33347, 3763, 33763},    /* DDR2-800 SC */
+       {1, 1, 800, 667, 6420, 36420, 6873, 36873},    /* DDR3-667 SC */
+       {1, 1, 800, 800, 5902, 35902, 6318, 36318},    /* DDR3-800 SC */
+
+       {1, 0, 667, 400, 3400, 33400, 4021, 34021},    /* DDR2-400 SC */
+       {1, 0, 667, 667, 3372, 33372, 3845, 33845},    /* DDR2-667 SC */
+       {1, 0, 667, 800, 3386, 33386, 3822, 33822},    /* DDR2-800 SC */
+       {1, 1, 667, 667, 6438, 36438, 6911, 36911},    /* DDR3-667 SC */
+       {1, 1, 667, 800, 5941, 35941, 6377, 36377},    /* DDR3-800 SC */
+
+       {1, 0, 400, 400, 3472, 33472, 4173, 34173},    /* DDR2-400 SC */
+       {1, 0, 400, 667, 3443, 33443, 3996, 33996},    /* DDR2-667 SC */
+       {1, 0, 400, 800, 3430, 33430, 3946, 33946},    /* DDR2-800 SC */
+       {1, 1, 400, 667, 6509, 36509, 7062, 37062},    /* DDR3-667 SC */
+       {1, 1, 400, 800, 5985, 35985, 6501, 36501},    /* DDR3-800 SC */
+
+       {0, 0, 800, 400, 3438, 33438, 4065, 34065},    /* DDR2-400 SC */
+       {0, 0, 800, 667, 3410, 33410, 3889, 33889},    /* DDR2-667 SC */
+       {0, 0, 800, 800, 3403, 33403, 3845, 33845},    /* DDR2-800 SC */
+       {0, 1, 800, 667, 6476, 36476, 6955, 36955},    /* DDR3-667 SC */
+       {0, 1, 800, 800, 5958, 35958, 6400, 36400},    /* DDR3-800 SC */
+
+       {0, 0, 667, 400, 3456, 33456, 4103, 34106},    /* DDR2-400 SC */
+       {0, 0, 667, 667, 3428, 33428, 3927, 33927},    /* DDR2-667 SC */
+       {0, 0, 667, 800, 3443, 33443, 3905, 33905},    /* DDR2-800 SC */
+       {0, 1, 667, 667, 6494, 36494, 6993, 36993},    /* DDR3-667 SC */
+       {0, 1, 667, 800, 5998, 35998, 6460, 36460},    /* DDR3-800 SC */
+
+       {0, 0, 400, 400, 3528, 33528, 4255, 34255},    /* DDR2-400 SC */
+       {0, 0, 400, 667, 3500, 33500, 4079, 34079},    /* DDR2-667 SC */
+       {0, 0, 400, 800, 3487, 33487, 4029, 34029},    /* DDR2-800 SC */
+       {0, 1, 400, 667, 6566, 36566, 7145, 37145},    /* DDR3-667 SC */
+       {0, 1, 400, 800, 6042, 36042, 6584, 36584},    /* DDR3-800 SC */
 };
 
-static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
-                                                  int mem)
+static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, 
+                                                  int fsb, int mem)
 {
        int i;
        struct cxsr_latency *latency;
@@ -2686,6 +2701,7 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int fsb,
        for (i = 0; i < ARRAY_SIZE(cxsr_latency_table); i++) {
                latency = &cxsr_latency_table[i];
                if (is_desktop == latency->is_desktop &&
+                   is_ddr3 == latency->is_ddr3 &&
                    fsb == latency->fsb_freq && mem == latency->mem_freq)
                        return latency;
        }
@@ -2800,8 +2816,8 @@ static void pineview_update_wm(struct drm_device *dev,  int planea_clock,
        struct cxsr_latency *latency;
        int sr_clock;
 
-       latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->fsb_freq,
-                                        dev_priv->mem_freq);
+       latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, 
+                                        dev_priv->fsb_freq, dev_priv->mem_freq);
        if (!latency) {
                DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n");
                pineview_disable_cxsr(dev);
@@ -3637,6 +3653,11 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
                        pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
        }
 
+       dspcntr |= DISPLAY_PLANE_ENABLE;
+       pipeconf |= PIPEACONF_ENABLE;
+       dpll |= DPLL_VCO_ENABLE;
+
+
        /* Disable the panel fitter if it was on our pipe */
        if (!HAS_PCH_SPLIT(dev) && intel_panel_fitter_pipe(dev) == pipe)
                I915_WRITE(PFIT_CONTROL, 0);
@@ -3957,6 +3978,13 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                        DRM_ERROR("failed to pin cursor bo\n");
                        goto fail_locked;
                }
+
+               ret = i915_gem_object_set_to_gtt_domain(bo, 0);
+               if (ret) {
+                       DRM_ERROR("failed to move cursor bo into the GTT\n");
+                       goto fail_unpin;
+               }
+
                addr = obj_priv->gtt_offset;
        } else {
                ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1);
@@ -4000,6 +4028,8 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        intel_crtc->cursor_bo = bo;
 
        return 0;
+fail_unpin:
+       i915_gem_object_unpin(bo);
 fail_locked:
        mutex_unlock(&dev->struct_mutex);
 fail:
@@ -4589,12 +4619,6 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
        spin_lock_irqsave(&dev->event_lock, flags);
        work = intel_crtc->unpin_work;
        if (work == NULL || !work->pending) {
-               if (work && !work->pending) {
-                       obj_priv = to_intel_bo(work->pending_flip_obj);
-                       DRM_DEBUG_DRIVER("flip finish: %p (%d) not pending?\n",
-                                        obj_priv,
-                                        atomic_read(&obj_priv->pending_flip));
-               }
                spin_unlock_irqrestore(&dev->event_lock, flags);
                return;
        }
@@ -4659,8 +4683,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        if (work == NULL)
                return -ENOMEM;
 
-       mutex_lock(&dev->struct_mutex);
-
        work->event = event;
        work->dev = crtc->dev;
        intel_fb = to_intel_framebuffer(crtc->fb);
@@ -4670,10 +4692,10 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        /* We borrow the event spin lock for protecting unpin_work */
        spin_lock_irqsave(&dev->event_lock, flags);
        if (intel_crtc->unpin_work) {
-               DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
                spin_unlock_irqrestore(&dev->event_lock, flags);
                kfree(work);
-               mutex_unlock(&dev->struct_mutex);
+
+               DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
                return -EBUSY;
        }
        intel_crtc->unpin_work = work;
@@ -4682,13 +4704,19 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
        intel_fb = to_intel_framebuffer(fb);
        obj = intel_fb->obj;
 
+       mutex_lock(&dev->struct_mutex);
        ret = intel_pin_and_fence_fb_obj(dev, obj);
        if (ret != 0) {
-               DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
-                         to_intel_bo(obj));
-               kfree(work);
-               intel_crtc->unpin_work = NULL;
                mutex_unlock(&dev->struct_mutex);
+
+               spin_lock_irqsave(&dev->event_lock, flags);
+               intel_crtc->unpin_work = NULL;
+               spin_unlock_irqrestore(&dev->event_lock, flags);
+
+               kfree(work);
+
+               DRM_DEBUG_DRIVER("flip queue: %p pin & fence failed\n",
+                                to_intel_bo(obj));
                return ret;
        }
 
@@ -5412,11 +5440,13 @@ static void intel_init_display(struct drm_device *dev)
                        dev_priv->display.update_wm = NULL;
        } else if (IS_PINEVIEW(dev)) {
                if (!intel_get_cxsr_latency(IS_PINEVIEW_G(dev),
+                                           dev_priv->is_ddr3,
                                            dev_priv->fsb_freq,
                                            dev_priv->mem_freq)) {
                        DRM_INFO("failed to find known CxSR latency "
-                                "(found fsb freq %d, mem freq %d), "
+                                "(found ddr%s fsb freq %d, mem freq %d), "
                                 "disabling CxSR\n",
+                                (dev_priv->is_ddr3 == 1) ? "3": "2",
                                 dev_priv->fsb_freq, dev_priv->mem_freq);
                        /* Disable CxSR and never update its watermark again */
                        pineview_disable_cxsr(dev);
@@ -5445,7 +5475,6 @@ static void intel_init_display(struct drm_device *dev)
 void intel_modeset_init(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int num_pipe;
        int i;
 
        drm_mode_config_init(dev);
@@ -5475,13 +5504,13 @@ void intel_modeset_init(struct drm_device *dev)
                dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
 
        if (IS_MOBILE(dev) || IS_I9XX(dev))
-               num_pipe = 2;
+               dev_priv->num_pipe = 2;
        else
-               num_pipe = 1;
+               dev_priv->num_pipe = 1;
        DRM_DEBUG_KMS("%d display pipe%s available.\n",
-                 num_pipe, num_pipe > 1 ? "s" : "");
+                     dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : "");
 
-       for (i = 0; i < num_pipe; i++) {
+       for (i = 0; i < dev_priv->num_pipe; i++) {
                intel_crtc_init(dev, i);
        }