]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'drm/drm-next'
authorThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:35:53 +0000 (14:35 +0200)
committerThierry Reding <treding@nvidia.com>
Thu, 24 Oct 2013 12:35:53 +0000 (14:35 +0200)
Conflicts:
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h

15 files changed:
1  2 
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_fb_helper.c
drivers/gpu/drm/exynos/exynos_drm_drv.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_pm.c
drivers/gpu/drm/radeon/atombios_encoders.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/staging/imx-drm/imx-drm-core.c
include/uapi/drm/drm_mode.h

index 05ad9ba0a67e8ab4c9e79aade5b8ead441b7f3a8,b55f138bd990e5563168b82ee7ea4a3c2729f3dc..21bfb68093faa78ea719b41931ce1aee86889bbb
@@@ -69,6 -69,7 +69,7 @@@ static const struct drm_ioctl_desc drm_
        DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, DRM_UNLOCKED),
        DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, DRM_UNLOCKED),
        DRM_IOCTL_DEF(DRM_IOCTL_GET_CAP, drm_getcap, DRM_UNLOCKED|DRM_RENDER_ALLOW),
+       DRM_IOCTL_DEF(DRM_IOCTL_SET_CLIENT_CAP, drm_setclientcap, 0),
        DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER),
  
        DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
  
  #define DRM_CORE_IOCTL_COUNT  ARRAY_SIZE( drm_ioctls )
  
- /**
-  * drm_legacy_dev_reinit
-  *
-  * Reinitializes a legacy/ums drm device in it's lastclose function.
-  */
- static void drm_legacy_dev_reinit(struct drm_device *dev)
- {
-       int i;
-       if (drm_core_check_feature(dev, DRIVER_MODESET))
-               return;
-       atomic_set(&dev->ioctl_count, 0);
-       atomic_set(&dev->vma_count, 0);
-       for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
-               atomic_set(&dev->counts[i], 0);
-       dev->sigdata.lock = NULL;
-       dev->context_flag = 0;
-       dev->last_context = 0;
-       dev->if_version = 0;
- }
- /**
-  * Take down the DRM device.
-  *
-  * \param dev DRM device structure.
-  *
-  * Frees every resource in \p dev.
-  *
-  * \sa drm_device
-  */
- int drm_lastclose(struct drm_device * dev)
- {
-       struct drm_vma_entry *vma, *vma_temp;
-       DRM_DEBUG("\n");
-       if (dev->driver->lastclose)
-               dev->driver->lastclose(dev);
-       DRM_DEBUG("driver lastclose completed\n");
-       if (dev->irq_enabled && !drm_core_check_feature(dev, DRIVER_MODESET))
-               drm_irq_uninstall(dev);
-       mutex_lock(&dev->struct_mutex);
-       drm_agp_clear(dev);
-       drm_legacy_sg_cleanup(dev);
-       /* Clear vma list (only built for debugging) */
-       list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
-               list_del(&vma->head);
-               kfree(vma);
-       }
-       drm_legacy_dma_takedown(dev);
-       dev->dev_mapping = NULL;
-       mutex_unlock(&dev->struct_mutex);
-       drm_legacy_dev_reinit(dev);
-       DRM_DEBUG("lastclose completed\n");
-       return 0;
- }
  /** File operations structure */
  static const struct file_operations drm_stub_fops = {
        .owner = THIS_MODULE,
@@@ -385,7 -316,6 +316,6 @@@ long drm_ioctl(struct file *filp
                return -ENODEV;
  
        atomic_inc(&dev->ioctl_count);
-       atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
        ++file_priv->ioctl_count;
  
        if ((nr >= DRM_CORE_IOCTL_COUNT) &&
                cmd = ioctl->cmd_drv;
        }
        else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) {
 +              u32 drv_size;
 +
                ioctl = &drm_ioctls[nr];
 -              cmd = ioctl->cmd;
 +
 +              drv_size = _IOC_SIZE(ioctl->cmd);
                usize = asize = _IOC_SIZE(cmd);
 +              if (drv_size > asize)
 +                      asize = drv_size;
 +
 +              cmd = ioctl->cmd;
        } else
                goto err_i1;
  
index 3d13ca6e257f0f2c6bd366a49f8b7f3622e592dd,21742a81cb9c6159348fbd00cc1016a291d714b5..2cfaec74a6fa23d7e9a1ab575687be3ad8b49f62
@@@ -407,6 -407,14 +407,6 @@@ static void drm_fb_helper_dpms(struct f
        struct drm_connector *connector;
        int i, j;
  
 -      /*
 -       * fbdev->blank can be called from irq context in case of a panic.
 -       * Since we already have our own special panic handler which will
 -       * restore the fbdev console mode completely, just bail out early.
 -       */
 -      if (oops_in_progress)
 -              return;
 -
        /*
         * fbdev->blank can be called from irq context in case of a panic.
         * Since we already have our own special panic handler which will
@@@ -844,7 -852,6 +844,6 @@@ int drm_fb_helper_pan_display(struct fb
        struct drm_fb_helper *fb_helper = info->par;
        struct drm_device *dev = fb_helper->dev;
        struct drm_mode_set *modeset;
-       struct drm_crtc *crtc;
        int ret = 0;
        int i;
  
        }
  
        for (i = 0; i < fb_helper->crtc_count; i++) {
-               crtc = fb_helper->crtc_info[i].mode_set.crtc;
                modeset = &fb_helper->crtc_info[i].mode_set;
  
                modeset->x = var->xoffset;
@@@ -1352,7 -1357,6 +1349,6 @@@ static int drm_pick_crtcs(struct drm_fb
        struct drm_connector *connector;
        struct drm_connector_helper_funcs *connector_funcs;
        struct drm_encoder *encoder;
-       struct drm_fb_helper_crtc *best_crtc;
        int my_score, best_score, score;
        struct drm_fb_helper_crtc **crtcs, *crtc;
        struct drm_fb_helper_connector *fb_helper_conn;
        connector = fb_helper_conn->connector;
  
        best_crtcs[n] = NULL;
-       best_crtc = NULL;
        best_score = drm_pick_crtcs(fb_helper, best_crtcs, modes, n+1, width, height);
        if (modes[n] == NULL)
                return best_score;
                score = my_score + drm_pick_crtcs(fb_helper, crtcs, modes, n + 1,
                                                  width, height);
                if (score > best_score) {
-                       best_crtc = crtc;
                        best_score = score;
                        memcpy(best_crtcs, crtcs,
                               dev->mode_config.num_connector *
@@@ -1580,8 -1582,7 +1574,7 @@@ EXPORT_SYMBOL(drm_fb_helper_initial_con
  int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
  {
        struct drm_device *dev = fb_helper->dev;
-       int count = 0;
-       u32 max_width, max_height, bpp_sel;
+       u32 max_width, max_height;
  
        if (!fb_helper->fb)
                return 0;
  
        max_width = fb_helper->fb->width;
        max_height = fb_helper->fb->height;
-       bpp_sel = fb_helper->fb->bits_per_pixel;
  
-       count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
-                                                   max_height);
+       drm_fb_helper_probe_connector_modes(fb_helper, max_width, max_height);
        mutex_unlock(&fb_helper->dev->mode_config.mutex);
  
        drm_modeset_lock_all(dev);
index 81192d00b39ec55f72afc68aa3ce0aab448a3e5d,3a1e6d9b25f71f2dec3252baaf0a605c4e82dc12..b676006a95a0118951f8e12d04f8a6fff0c49fb0
@@@ -264,7 -264,6 +264,6 @@@ static struct drm_driver exynos_drm_dri
        .get_vblank_counter     = drm_vblank_count,
        .enable_vblank          = exynos_drm_crtc_enable_vblank,
        .disable_vblank         = exynos_drm_crtc_disable_vblank,
-       .gem_init_object        = exynos_drm_gem_init_object,
        .gem_free_object        = exynos_drm_gem_free_object,
        .gem_vm_ops             = &exynos_drm_gem_vm_ops,
        .dumb_create            = exynos_drm_gem_dumb_create,
  
  static int exynos_drm_platform_probe(struct platform_device *pdev)
  {
 -      pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
 +      int ret;
 +
 +      ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
 +      if (ret)
 +              return ret;
  
        return drm_platform_init(&exynos_drm_driver, pdev);
  }
index d5c784d486714d4cc5b9e1a45c8b17fe13d51871,b3873c945d1b19e7393433240596e38b0a2330b8..b20a8b2fe1f65b4c2201df38f150f39090d7dc9a
@@@ -52,7 -52,7 +52,7 @@@
        intel_ring_emit(LP_RING(dev_priv), x)
  
  #define ADVANCE_LP_RING() \
-       intel_ring_advance(LP_RING(dev_priv))
+       __intel_ring_advance(LP_RING(dev_priv))
  
  /**
   * Lock test for when it's just for synchronization of ring access.
@@@ -641,7 -641,7 +641,7 @@@ static int i915_batchbuffer(struct drm_
  
        if (batch->num_cliprects) {
                cliprects = kcalloc(batch->num_cliprects,
-                                   sizeof(struct drm_clip_rect),
+                                   sizeof(*cliprects),
                                    GFP_KERNEL);
                if (cliprects == NULL)
                        return -ENOMEM;
@@@ -703,7 -703,7 +703,7 @@@ static int i915_cmdbuffer(struct drm_de
  
        if (cmdbuf->num_cliprects) {
                cliprects = kcalloc(cmdbuf->num_cliprects,
-                                   sizeof(struct drm_clip_rect), GFP_KERNEL);
+                                   sizeof(*cliprects), GFP_KERNEL);
                if (cliprects == NULL) {
                        ret = -ENOMEM;
                        goto fail_batch_free;
@@@ -931,7 -931,7 +931,7 @@@ static int i915_getparam(struct drm_dev
                value = READ_BREADCRUMB(dev_priv);
                break;
        case I915_PARAM_CHIPSET_ID:
-               value = dev->pci_device;
+               value = dev->pdev->device;
                break;
        case I915_PARAM_HAS_GEM:
                value = 1;
@@@ -1290,9 -1290,12 +1290,9 @@@ static int i915_load_modeset_init(struc
         * then we do not take part in VGA arbitration and the
         * vga_client_register() fails with -ENODEV.
         */
 -      if (!HAS_PCH_SPLIT(dev)) {
 -              ret = vga_client_register(dev->pdev, dev, NULL,
 -                                        i915_vga_set_decode);
 -              if (ret && ret != -ENODEV)
 -                      goto out;
 -      }
 +      ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
 +      if (ret && ret != -ENODEV)
 +              goto out;
  
        intel_register_dsm_handler();
  
        if (ret)
                goto cleanup_gem_stolen;
  
+       intel_init_power_well(dev);
+       /* Keep VGA alive until i915_disable_vga_mem() */
+       intel_display_power_get(dev, POWER_DOMAIN_VGA);
        /* Important: The output setup functions called by modeset_init need
         * working irqs for e.g. gmbus and dp aux transfers. */
        intel_modeset_init(dev);
  
        ret = i915_gem_init(dev);
        if (ret)
-               goto cleanup_irq;
+               goto cleanup_power;
  
        INIT_WORK(&dev_priv->console_resume_work, intel_console_resume);
  
  
        /* Always safe in the mode setting case. */
        /* FIXME: do pre/post-mode set stuff in core KMS code */
-       dev->vblank_disable_allowed = 1;
-       if (INTEL_INFO(dev)->num_pipes == 0)
+       dev->vblank_disable_allowed = true;
+       if (INTEL_INFO(dev)->num_pipes == 0) {
+               intel_display_power_put(dev, POWER_DOMAIN_VGA);
                return 0;
+       }
  
        ret = intel_fbdev_init(dev);
        if (ret)
         */
        intel_fbdev_initial_config(dev);
  
 -      /*
 -       * Must do this after fbcon init so that
 -       * vgacon_save_screen() works during the handover.
 -       */
 -      i915_disable_vga_mem(dev);
+       intel_display_power_put(dev, POWER_DOMAIN_VGA);
        /* Only enable hotplug handling once the fbdev is fully set up. */
        dev_priv->enable_hotplug_processing = true;
  
@@@ -1362,7 -1379,8 +1371,8 @@@ cleanup_gem
        mutex_unlock(&dev->struct_mutex);
        i915_gem_cleanup_aliasing_ppgtt(dev);
        drm_mm_takedown(&dev_priv->gtt.base.mm);
- cleanup_irq:
+ cleanup_power:
+       intel_display_power_put(dev, POWER_DOMAIN_VGA);
        drm_irq_uninstall(dev);
  cleanup_gem_stolen:
        i915_gem_cleanup_stolen(dev);
@@@ -1462,14 -1480,7 +1472,7 @@@ int i915_driver_load(struct drm_device 
        if (info->gen >= 6 && !drm_core_check_feature(dev, DRIVER_MODESET))
                return -ENODEV;
  
-       /* i915 has 4 more counters */
-       dev->counters += 4;
-       dev->types[6] = _DRM_STAT_IRQ;
-       dev->types[7] = _DRM_STAT_PRIMARY;
-       dev->types[8] = _DRM_STAT_SECONDARY;
-       dev->types[9] = _DRM_STAT_DMA;
-       dev_priv = kzalloc(sizeof(drm_i915_private_t), GFP_KERNEL);
+       dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
        if (dev_priv == NULL)
                return -ENOMEM;
  
  
        ret = i915_gem_gtt_init(dev);
        if (ret)
-               goto put_bridge;
+               goto out_regs;
  
        if (drm_core_check_feature(dev, DRIVER_MODESET))
                i915_kick_out_firmware_fb(dev_priv);
                                     aperture_size);
        if (dev_priv->gtt.mappable == NULL) {
                ret = -EIO;
-               goto out_rmmap;
+               goto out_gtt;
        }
  
        dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base,
                ret = i915_load_modeset_init(dev);
                if (ret < 0) {
                        DRM_ERROR("failed to init modeset\n");
-                       goto out_gem_unload;
+                       goto out_power_well;
                }
        } else {
                /* Start out suspended in ums mode. */
  
        return 0;
  
+ out_power_well:
+       if (HAS_POWER_WELL(dev))
+               i915_remove_power_well(dev);
+       drm_vblank_cleanup(dev);
  out_gem_unload:
        if (dev_priv->mm.inactive_shrinker.scan_objects)
                unregister_shrinker(&dev_priv->mm.inactive_shrinker);
  out_mtrrfree:
        arch_phys_wc_del(dev_priv->gtt.mtrr);
        io_mapping_free(dev_priv->gtt.mappable);
+ out_gtt:
+       list_del(&dev_priv->gtt.base.global_link);
+       drm_mm_takedown(&dev_priv->gtt.base.mm);
        dev_priv->gtt.base.cleanup(&dev_priv->gtt.base);
- out_rmmap:
+ out_regs:
        pci_iounmap(dev->pdev, dev_priv->regs);
  put_bridge:
        pci_dev_put(dev_priv->bridge_dev);
  free_priv:
+       if (dev_priv->slab)
+               kmem_cache_destroy(dev_priv->slab);
        kfree(dev_priv);
        return ret;
  }
@@@ -1774,8 -1794,8 +1786,8 @@@ int i915_driver_unload(struct drm_devic
        list_del(&dev_priv->gtt.base.global_link);
        WARN_ON(!list_empty(&dev_priv->vm_list));
        drm_mm_takedown(&dev_priv->gtt.base.mm);
-       if (dev_priv->regs != NULL)
-               pci_iounmap(dev->pdev, dev_priv->regs);
+       drm_vblank_cleanup(dev);
  
        intel_teardown_gmbus(dev);
        intel_teardown_mchbar(dev);
  
        dev_priv->gtt.base.cleanup(&dev_priv->gtt.base);
  
+       intel_uncore_fini(dev);
+       if (dev_priv->regs != NULL)
+               pci_iounmap(dev->pdev, dev_priv->regs);
        if (dev_priv->slab)
                kmem_cache_destroy(dev_priv->slab);
  
  
  int i915_driver_open(struct drm_device *dev, struct drm_file *file)
  {
-       struct drm_i915_file_private *file_priv;
-       DRM_DEBUG_DRIVER("\n");
-       file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
-       if (!file_priv)
-               return -ENOMEM;
-       file->driver_priv = file_priv;
-       spin_lock_init(&file_priv->mm.lock);
-       INIT_LIST_HEAD(&file_priv->mm.request_list);
+       int ret;
  
-       idr_init(&file_priv->context_idr);
+       ret = i915_gem_open(dev, file);
+       if (ret)
+               return ret;
  
        return 0;
  }
index 2ad27880cd047bc93cf119784895040eeafc3bae,96f230497cbefd1918abe0239aa30b55cf1d6c60..a51f96a06d4f82034bedfda62b4db270f54a95d0
@@@ -416,7 -416,7 +416,7 @@@ void intel_detect_pch(struct drm_devic
                        } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
                                /* PantherPoint is CPT compatible */
                                dev_priv->pch_type = PCH_CPT;
-                               DRM_DEBUG_KMS("Found PatherPoint PCH\n");
+                               DRM_DEBUG_KMS("Found PantherPoint PCH\n");
                                WARN_ON(!(IS_GEN6(dev) || IS_IVYBRIDGE(dev)));
                        } else if (id == INTEL_PCH_LPT_DEVICE_ID_TYPE) {
                                dev_priv->pch_type = PCH_LPT;
@@@ -505,8 -505,6 +505,8 @@@ static int i915_drm_freeze(struct drm_d
                intel_modeset_suspend_hw(dev);
        }
  
 +      i915_gem_suspend_gtt_mappings(dev);
 +
        i915_save_state(dev);
  
        intel_opregion_fini(dev);
@@@ -578,11 -576,24 +578,25 @@@ static void intel_resume_hotplug(struc
        drm_helper_hpd_irq_event(dev);
  }
  
- static int __i915_drm_thaw(struct drm_device *dev)
+ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        int error = 0;
  
 -      }
+       intel_uncore_early_sanitize(dev);
+       intel_uncore_sanitize(dev);
+       if (drm_core_check_feature(dev, DRIVER_MODESET) &&
+           restore_gtt_mappings) {
+               mutex_lock(&dev->struct_mutex);
+               i915_gem_restore_gtt_mappings(dev);
+               mutex_unlock(&dev->struct_mutex);
++      } else if (drm_core_check_feature(dev, DRIVER_MODESET))
++              i915_check_and_clear_faults(dev);
+       intel_init_power_well(dev);
        i915_restore_state(dev);
        intel_opregion_setup(dev);
  
  
  static int i915_drm_thaw(struct drm_device *dev)
  {
-       int error = 0;
-       intel_uncore_sanitize(dev);
-       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
-               mutex_lock(&dev->struct_mutex);
-               i915_gem_restore_gtt_mappings(dev);
-               mutex_unlock(&dev->struct_mutex);
-       } else if (drm_core_check_feature(dev, DRIVER_MODESET))
-               i915_check_and_clear_faults(dev);
-       __i915_drm_thaw(dev);
-       return error;
+       return __i915_drm_thaw(dev, true);
  }
  
  int i915_resume(struct drm_device *dev)
  
        pci_set_master(dev->pdev);
  
-       intel_uncore_sanitize(dev);
        /*
         * Platforms with opregion should have sane BIOS, older ones (gen3 and
-        * earlier) need this since the BIOS might clear all our scratch PTEs.
+        * earlier) need to restore the GTT mappings since the BIOS might clear
+        * all our scratch PTEs.
         */
-       if (drm_core_check_feature(dev, DRIVER_MODESET) &&
-           !dev_priv->opregion.header) {
-               mutex_lock(&dev->struct_mutex);
-               i915_gem_restore_gtt_mappings(dev);
-               mutex_unlock(&dev->struct_mutex);
-       }
-       ret = __i915_drm_thaw(dev);
+       ret = __i915_drm_thaw(dev, !dev_priv->opregion.header);
        if (ret)
                return ret;
  
@@@ -722,24 -712,19 +715,19 @@@ int i915_reset(struct drm_device *dev
  
        simulated = dev_priv->gpu_error.stop_rings != 0;
  
-       if (!simulated && get_seconds() - dev_priv->gpu_error.last_reset < 5) {
-               DRM_ERROR("GPU hanging too fast, declaring wedged!\n");
-               ret = -ENODEV;
-       } else {
-               ret = intel_gpu_reset(dev);
-               /* Also reset the gpu hangman. */
-               if (simulated) {
-                       DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
-                       dev_priv->gpu_error.stop_rings = 0;
-                       if (ret == -ENODEV) {
-                               DRM_ERROR("Reset not implemented, but ignoring "
-                                         "error for simulated gpu hangs\n");
-                               ret = 0;
-                       }
-               } else
-                       dev_priv->gpu_error.last_reset = get_seconds();
+       ret = intel_gpu_reset(dev);
+       /* Also reset the gpu hangman. */
+       if (simulated) {
+               DRM_INFO("Simulated gpu hang, resetting stop_rings\n");
+               dev_priv->gpu_error.stop_rings = 0;
+               if (ret == -ENODEV) {
+                       DRM_ERROR("Reset not implemented, but ignoring "
+                                 "error for simulated gpu hangs\n");
+                       ret = 0;
+               }
        }
        if (ret) {
                DRM_ERROR("Failed to reset chip.\n");
                mutex_unlock(&dev->struct_mutex);
@@@ -802,6 -787,12 +790,12 @@@ static int i915_pci_probe(struct pci_de
        struct intel_device_info *intel_info =
                (struct intel_device_info *) ent->driver_data;
  
+       if (IS_PRELIMINARY_HW(intel_info) && !i915_preliminary_hw_support) {
+               DRM_INFO("This hardware requires preliminary hardware support.\n"
+                        "See CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT, and/or modparam preliminary_hw_support\n");
+               return -ENODEV;
+       }
        /* Only bind to function 0 of the device. Early generations
         * used function 1 as a placeholder for multi-head. This causes
         * us confusion instead, especially on the systems where both
@@@ -949,7 -940,6 +943,6 @@@ static struct drm_driver driver = 
        .debugfs_init = i915_debugfs_init,
        .debugfs_cleanup = i915_debugfs_cleanup,
  #endif
-       .gem_init_object = i915_gem_init_object,
        .gem_free_object = i915_gem_free_object,
        .gem_vm_ops = &i915_gem_vm_ops,
  
index ab0f2c0a440c6a4543a59d81282c4ab21316b2cc,6a5b7ab0c3fab9f4b6b1fe737c24c61d1b8990a2..ecbeb6ece9e3031633d4090c68f60817586f7d54
@@@ -99,6 -99,7 +99,7 @@@ enum intel_display_power_domain 
        POWER_DOMAIN_TRANSCODER_B,
        POWER_DOMAIN_TRANSCODER_C,
        POWER_DOMAIN_TRANSCODER_EDP = POWER_DOMAIN_TRANSCODER_A + 0xF,
+       POWER_DOMAIN_VGA,
  };
  
  #define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
@@@ -225,6 -226,8 +226,8 @@@ struct intel_opregion 
        struct opregion_header __iomem *header;
        struct opregion_acpi __iomem *acpi;
        struct opregion_swsci __iomem *swsci;
+       u32 swsci_gbda_sub_functions;
+       u32 swsci_sbcb_sub_functions;
        struct opregion_asle __iomem *asle;
        void __iomem *vbt;
        u32 __iomem *lid_state;
@@@ -321,11 -324,13 +324,13 @@@ struct drm_i915_error_state 
                u32 dirty:1;
                u32 purgeable:1;
                s32 ring:4;
-               u32 cache_level:2;
+               u32 cache_level:3;
        } **active_bo, **pinned_bo;
        u32 *active_bo_count, *pinned_bo_count;
        struct intel_overlay_error_state *overlay;
        struct intel_display_error_state *display;
+       int hangcheck_score[I915_NUM_RINGS];
+       enum intel_ring_hangcheck_action hangcheck_action[I915_NUM_RINGS];
  };
  
  struct intel_crtc_config;
@@@ -357,7 -362,7 +362,7 @@@ struct drm_i915_display_funcs 
                          int target, int refclk,
                          struct dpll *match_clock,
                          struct dpll *best_clock);
-       void (*update_wm)(struct drm_device *dev);
+       void (*update_wm)(struct drm_crtc *crtc);
        void (*update_sprite_wm)(struct drm_plane *plane,
                                 struct drm_crtc *crtc,
                                 uint32_t sprite_width, int pixel_size,
         * fills out the pipe-config with the hw state. */
        bool (*get_pipe_config)(struct intel_crtc *,
                                struct intel_crtc_config *);
-       void (*get_clock)(struct intel_crtc *, struct intel_crtc_config *);
        int (*crtc_mode_set)(struct drm_crtc *crtc,
                             int x, int y,
                             struct drm_framebuffer *old_fb);
@@@ -404,6 -408,8 +408,8 @@@ struct intel_uncore 
  
        unsigned fifo_count;
        unsigned forcewake_count;
+       struct delayed_work force_wake_work;
  };
  
  #define DEV_INFO_FOR_EACH_FLAG(func, sep) \
        func(is_ivybridge) sep \
        func(is_valleyview) sep \
        func(is_haswell) sep \
+       func(is_preliminary) sep \
        func(has_force_wake) sep \
        func(has_fbc) sep \
        func(has_pipe_cxsr) sep \
@@@ -497,12 -504,10 +504,12 @@@ struct i915_address_space 
  
        /* FIXME: Need a more generic return type */
        gen6_gtt_pte_t (*pte_encode)(dma_addr_t addr,
 -                                   enum i915_cache_level level);
 +                                   enum i915_cache_level level,
 +                                   bool valid); /* Create a valid PTE */
        void (*clear_range)(struct i915_address_space *vm,
                            unsigned int first_entry,
 -                          unsigned int num_entries);
 +                          unsigned int num_entries,
 +                          bool use_scratch);
        void (*insert_entries)(struct i915_address_space *vm,
                               struct sg_table *st,
                               unsigned int first_entry,
@@@ -570,6 -575,13 +577,13 @@@ struct i915_vma 
        /** This vma's place in the batchbuffer or on the eviction list */
        struct list_head exec_list;
  
+       /**
+        * Used for performing relocations during execbuffer insertion.
+        */
+       struct hlist_node exec_node;
+       unsigned long exec_handle;
+       struct drm_i915_gem_exec_object2 *exec_entry;
  };
  
  struct i915_ctx_hang_stats {
  
        /* This context had batch active when hang was declared */
        unsigned batch_active;
+       /* Time when this context was last blamed for a GPU reset */
+       unsigned long guilty_ts;
+       /* This context is banned to submit more work */
+       bool banned;
  };
  
  /* This must match up with the value previously used for execbuf2.rsvd1. */
@@@ -586,10 -604,13 +606,13 @@@ struct i915_hw_context 
        struct kref ref;
        int id;
        bool is_initialized;
+       uint8_t remap_slice;
        struct drm_i915_file_private *file_priv;
        struct intel_ring_buffer *ring;
        struct drm_i915_gem_object *obj;
        struct i915_ctx_hang_stats hang_stats;
+       struct list_head link;
  };
  
  struct i915_fbc {
        } no_fbc_reason;
  };
  
- enum no_psr_reason {
-       PSR_NO_SOURCE, /* Not supported on platform */
-       PSR_NO_SINK, /* Not supported by panel */
-       PSR_MODULE_PARAM,
-       PSR_CRTC_NOT_ACTIVE,
-       PSR_PWR_WELL_ENABLED,
-       PSR_NOT_TILED,
-       PSR_SPRITE_ENABLED,
-       PSR_S3D_ENABLED,
-       PSR_INTERLACED_ENABLED,
-       PSR_HSW_NOT_DDIA,
+ struct i915_psr {
+       bool sink_support;
+       bool source_ok;
  };
  
  enum intel_pch {
@@@ -823,17 -836,19 +838,19 @@@ struct intel_gen6_power_mgmt 
        struct work_struct work;
        u32 pm_iir;
  
-       /* On vlv we need to manually drop to Vmin with a delayed work. */
-       struct delayed_work vlv_work;
        /* The below variables an all the rps hw state are protected by
         * dev->struct mutext. */
        u8 cur_delay;
        u8 min_delay;
        u8 max_delay;
        u8 rpe_delay;
+       u8 rp1_delay;
+       u8 rp0_delay;
        u8 hw_max;
  
+       int last_adj;
+       enum { LOW_POWER, BETWEEN, HIGH_POWER } power;
        struct delayed_work delayed_resume_work;
  
        /*
@@@ -902,9 -917,11 +919,11 @@@ struct i915_ums_state 
        int mm_suspended;
  };
  
+ #define MAX_L3_SLICES 2
  struct intel_l3_parity {
-       u32 *remap_info;
+       u32 *remap_info[MAX_L3_SLICES];
        struct work_struct error_work;
+       int which_slice;
  };
  
  struct i915_gem_mm {
         */
        struct delayed_work retire_work;
  
+       /**
+        * When we detect an idle GPU, we want to turn on
+        * powersaving features. So once we see that there
+        * are no more requests outstanding and no more
+        * arrive within a small period of time, we fire
+        * off the idle_work.
+        */
+       struct delayed_work idle_work;
        /**
         * Are we in a non-interruptible section of code like
         * modesetting?
@@@ -979,6 -1005,9 +1007,9 @@@ struct i915_gpu_error 
        /* For hangcheck timer */
  #define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */
  #define DRM_I915_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)
+       /* Hang gpu twice in this window and your context gets banned */
+ #define DRM_I915_CTX_BAN_PERIOD DIV_ROUND_UP(8*DRM_I915_HANGCHECK_PERIOD, 1000)
        struct timer_list hangcheck_timer;
  
        /* For reset and error_state handling. */
        struct drm_i915_error_state *first_error;
        struct work_struct work;
  
-       unsigned long last_reset;
+       unsigned long missed_irq_rings;
  
        /**
         * State variable and reset counter controlling the reset flow
  
        /* For gpu hang simulation. */
        unsigned int stop_rings;
+       /* For missed irq/seqno simulation. */
+       unsigned int test_irq_rings;
  };
  
  enum modeset_restore {
        MODESET_SUSPENDED,
  };
  
+ struct ddi_vbt_port_info {
+       uint8_t hdmi_level_shift;
+       uint8_t supports_dvi:1;
+       uint8_t supports_hdmi:1;
+       uint8_t supports_dp:1;
+ };
  struct intel_vbt_data {
        struct drm_display_mode *lfp_lvds_vbt_mode; /* if any */
        struct drm_display_mode *sdvo_lvds_vbt_mode; /* if any */
        int edp_bpp;
        struct edp_power_seq edp_pps;
  
+       /* MIPI DSI */
+       struct {
+               u16 panel_id;
+       } dsi;
        int crt_ddc_pin;
  
        int child_dev_num;
-       struct child_device_config *child_dev;
+       union child_device_config *child_dev;
+       struct ddi_vbt_port_info ddi_port_info[I915_MAX_PORTS];
  };
  
  enum intel_ddb_partitioning {
@@@ -1300,7 -1348,7 +1350,7 @@@ typedef struct drm_i915_private 
        /* Haswell power well */
        struct i915_power_well power_well;
  
-       enum no_psr_reason no_psr_reason;
+       struct i915_psr psr;
  
        struct i915_gpu_error gpu_error;
  
  
        bool hw_contexts_disabled;
        uint32_t hw_context_size;
+       struct list_head context_list;
  
        u32 fdi_rx_config;
  
@@@ -1400,8 -1449,6 +1451,6 @@@ struct drm_i915_gem_object 
        struct list_head ring_list;
        /** Used in execbuf to temporarily hold a ref */
        struct list_head obj_exec_link;
-       /** This object's place in the batchbuffer or on the eviction list */
-       struct list_head exec_list;
  
        /**
         * This is set if the object is on the active lists (has pending
        void *dma_buf_vmapping;
        int vmapping_count;
  
-       /**
-        * Used for performing relocations during execbuffer insertion.
-        */
-       struct hlist_node exec_node;
-       unsigned long exec_handle;
-       struct drm_i915_gem_exec_object2 *exec_entry;
        struct intel_ring_buffer *ring;
  
        /** Breadcrumb of last rendering to the buffer. */
@@@ -1560,48 -1600,55 +1602,55 @@@ struct drm_i915_gem_request 
  };
  
  struct drm_i915_file_private {
+       struct drm_i915_private *dev_priv;
        struct {
                spinlock_t lock;
                struct list_head request_list;
+               struct delayed_work idle_work;
        } mm;
        struct idr context_idr;
  
        struct i915_ctx_hang_stats hang_stats;
+       atomic_t rps_wait_boost;
  };
  
  #define INTEL_INFO(dev)       (to_i915(dev)->info)
  
- #define IS_I830(dev)          ((dev)->pci_device == 0x3577)
- #define IS_845G(dev)          ((dev)->pci_device == 0x2562)
+ #define IS_I830(dev)          ((dev)->pdev->device == 0x3577)
+ #define IS_845G(dev)          ((dev)->pdev->device == 0x2562)
  #define IS_I85X(dev)          (INTEL_INFO(dev)->is_i85x)
- #define IS_I865G(dev)         ((dev)->pci_device == 0x2572)
+ #define IS_I865G(dev)         ((dev)->pdev->device == 0x2572)
  #define IS_I915G(dev)         (INTEL_INFO(dev)->is_i915g)
- #define IS_I915GM(dev)                ((dev)->pci_device == 0x2592)
- #define IS_I945G(dev)         ((dev)->pci_device == 0x2772)
+ #define IS_I915GM(dev)                ((dev)->pdev->device == 0x2592)
+ #define IS_I945G(dev)         ((dev)->pdev->device == 0x2772)
  #define IS_I945GM(dev)                (INTEL_INFO(dev)->is_i945gm)
  #define IS_BROADWATER(dev)    (INTEL_INFO(dev)->is_broadwater)
  #define IS_CRESTLINE(dev)     (INTEL_INFO(dev)->is_crestline)
- #define IS_GM45(dev)          ((dev)->pci_device == 0x2A42)
+ #define IS_GM45(dev)          ((dev)->pdev->device == 0x2A42)
  #define IS_G4X(dev)           (INTEL_INFO(dev)->is_g4x)
- #define IS_PINEVIEW_G(dev)    ((dev)->pci_device == 0xa001)
- #define IS_PINEVIEW_M(dev)    ((dev)->pci_device == 0xa011)
+ #define IS_PINEVIEW_G(dev)    ((dev)->pdev->device == 0xa001)
+ #define IS_PINEVIEW_M(dev)    ((dev)->pdev->device == 0xa011)
  #define IS_PINEVIEW(dev)      (INTEL_INFO(dev)->is_pineview)
  #define IS_G33(dev)           (INTEL_INFO(dev)->is_g33)
- #define IS_IRONLAKE_M(dev)    ((dev)->pci_device == 0x0046)
+ #define IS_IRONLAKE_M(dev)    ((dev)->pdev->device == 0x0046)
  #define IS_IVYBRIDGE(dev)     (INTEL_INFO(dev)->is_ivybridge)
- #define IS_IVB_GT1(dev)               ((dev)->pci_device == 0x0156 || \
-                                (dev)->pci_device == 0x0152 || \
-                                (dev)->pci_device == 0x015a)
- #define IS_SNB_GT1(dev)               ((dev)->pci_device == 0x0102 || \
-                                (dev)->pci_device == 0x0106 || \
-                                (dev)->pci_device == 0x010A)
+ #define IS_IVB_GT1(dev)               ((dev)->pdev->device == 0x0156 || \
+                                (dev)->pdev->device == 0x0152 || \
+                                (dev)->pdev->device == 0x015a)
+ #define IS_SNB_GT1(dev)               ((dev)->pdev->device == 0x0102 || \
+                                (dev)->pdev->device == 0x0106 || \
+                                (dev)->pdev->device == 0x010A)
  #define IS_VALLEYVIEW(dev)    (INTEL_INFO(dev)->is_valleyview)
  #define IS_HASWELL(dev)       (INTEL_INFO(dev)->is_haswell)
  #define IS_MOBILE(dev)                (INTEL_INFO(dev)->is_mobile)
  #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \
-                                ((dev)->pci_device & 0xFF00) == 0x0C00)
+                                ((dev)->pdev->device & 0xFF00) == 0x0C00)
  #define IS_ULT(dev)           (IS_HASWELL(dev) && \
-                                ((dev)->pci_device & 0xFF00) == 0x0A00)
+                                ((dev)->pdev->device & 0xFF00) == 0x0A00)
+ #define IS_HSW_GT3(dev)               (IS_HASWELL(dev) && \
+                                ((dev)->pdev->device & 0x00F0) == 0x0020)
+ #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary)
  
  /*
   * The genX designation typically refers to the render engine, so render
  #define SUPPORTS_DIGITAL_OUTPUTS(dev) (!IS_GEN2(dev) && !IS_PINEVIEW(dev))
  #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_GEN5(dev))
  #define SUPPORTS_INTEGRATED_DP(dev)   (IS_G4X(dev) || IS_GEN5(dev))
- #define SUPPORTS_EDP(dev)             (IS_IRONLAKE_M(dev))
  #define SUPPORTS_TV(dev)              (INTEL_INFO(dev)->supports_tv)
  #define I915_HAS_HOTPLUG(dev)          (INTEL_INFO(dev)->has_hotplug)
  
  #define HAS_DDI(dev)          (INTEL_INFO(dev)->has_ddi)
  #define HAS_POWER_WELL(dev)   (IS_HASWELL(dev))
  #define HAS_FPGA_DBG_UNCLAIMED(dev)   (INTEL_INFO(dev)->has_fpga_dbg)
+ #define HAS_PSR(dev)          (IS_HASWELL(dev))
  
  #define INTEL_PCH_DEVICE_ID_MASK              0xff00
  #define INTEL_PCH_IBX_DEVICE_ID_TYPE          0x3b00
  
  #define HAS_FORCE_WAKE(dev) (INTEL_INFO(dev)->has_force_wake)
  
- #define HAS_L3_GPU_CACHE(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+ /* DPF == dynamic parity feature */
+ #define HAS_L3_DPF(dev) (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+ #define NUM_L3_SLICES(dev) (IS_HSW_GT3(dev) ? 2 : HAS_L3_DPF(dev))
  
  #define GT_FREQUENCY_MULTIPLIER 50
  
@@@ -1767,6 -1816,7 +1818,7 @@@ extern void intel_uncore_early_sanitize
  extern void intel_uncore_init(struct drm_device *dev);
  extern void intel_uncore_clear_errors(struct drm_device *dev);
  extern void intel_uncore_check_errors(struct drm_device *dev);
+ extern void intel_uncore_fini(struct drm_device *dev);
  
  void
  i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
@@@ -1824,14 -1874,11 +1876,11 @@@ int i915_gem_wait_ioctl(struct drm_devi
  void i915_gem_load(struct drm_device *dev);
  void *i915_gem_object_alloc(struct drm_device *dev);
  void i915_gem_object_free(struct drm_i915_gem_object *obj);
- int i915_gem_init_object(struct drm_gem_object *obj);
  void i915_gem_object_init(struct drm_i915_gem_object *obj,
                         const struct drm_i915_gem_object_ops *ops);
  struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev,
                                                  size_t size);
  void i915_gem_free_object(struct drm_gem_object *obj);
- struct i915_vma *i915_gem_vma_create(struct drm_i915_gem_object *obj,
-                                    struct i915_address_space *vm);
  void i915_gem_vma_destroy(struct i915_vma *vma);
  
  int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj,
@@@ -1870,9 -1917,8 +1919,8 @@@ static inline void i915_gem_object_unpi
  int __must_check i915_mutex_lock_interruptible(struct drm_device *dev);
  int i915_gem_object_sync(struct drm_i915_gem_object *obj,
                         struct intel_ring_buffer *to);
- void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj,
-                                   struct intel_ring_buffer *ring);
+ void i915_vma_move_to_active(struct i915_vma *vma,
+                            struct intel_ring_buffer *ring);
  int i915_gem_dumb_create(struct drm_file *file_priv,
                         struct drm_device *dev,
                         struct drm_mode_create_dumb *args);
@@@ -1913,7 -1959,7 +1961,7 @@@ i915_gem_object_unpin_fence(struct drm_
        }
  }
  
void i915_gem_retire_requests(struct drm_device *dev);
bool i915_gem_retire_requests(struct drm_device *dev);
  void i915_gem_retire_requests_ring(struct intel_ring_buffer *ring);
  int __must_check i915_gem_check_wedge(struct i915_gpu_error *error,
                                      bool interruptible);
@@@ -1933,7 -1979,7 +1981,7 @@@ bool i915_gem_clflush_object(struct drm
  int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj);
  int __must_check i915_gem_init(struct drm_device *dev);
  int __must_check i915_gem_init_hw(struct drm_device *dev);
void i915_gem_l3_remap(struct drm_device *dev);
int i915_gem_l3_remap(struct intel_ring_buffer *ring, int slice);
  void i915_gem_init_swizzling(struct drm_device *dev);
  void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
  int __must_check i915_gpu_idle(struct drm_device *dev);
@@@ -1964,6 -2010,7 +2012,7 @@@ int i915_gem_attach_phys_object(struct 
  void i915_gem_detach_phys_object(struct drm_device *dev,
                                 struct drm_i915_gem_object *obj);
  void i915_gem_free_all_phys_object(struct drm_device *dev);
+ int i915_gem_open(struct drm_device *dev, struct drm_file *file);
  void i915_gem_release(struct drm_device *dev, struct drm_file *file);
  
  uint32_t
@@@ -1995,6 -2042,9 +2044,9 @@@ struct i915_vma *i915_gem_obj_to_vma(st
  struct i915_vma *
  i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj,
                                  struct i915_address_space *vm);
+ struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj);
  /* Some GGTT VM helpers */
  #define obj_to_ggtt(obj) \
        (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base)
@@@ -2031,7 -2081,6 +2083,6 @@@ i915_gem_obj_ggtt_pin(struct drm_i915_g
        return i915_gem_object_pin(obj, obj_to_ggtt(obj), alignment,
                                   map_and_fenceable, nonblocking);
  }
- #undef obj_to_ggtt
  
  /* i915_gem_context.c */
  void i915_gem_context_init(struct drm_device *dev);
@@@ -2067,8 -2116,6 +2118,8 @@@ void i915_ppgtt_bind_object(struct i915
  void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
                              struct drm_i915_gem_object *obj);
  
 +void i915_check_and_clear_faults(struct drm_device *dev);
 +void i915_gem_suspend_gtt_mappings(struct drm_device *dev);
  void i915_gem_restore_gtt_mappings(struct drm_device *dev);
  int __must_check i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj);
  void i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj,
@@@ -2094,6 -2141,7 +2145,7 @@@ int __must_check i915_gem_evict_somethi
                                          unsigned cache_level,
                                          bool mappable,
                                          bool nonblock);
+ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle);
  int i915_gem_evict_everything(struct drm_device *dev);
  
  /* i915_gem_stolen.c */
@@@ -2186,15 -2234,30 +2238,30 @@@ static inline bool intel_gmbus_is_force
  extern void intel_i2c_reset(struct drm_device *dev);
  
  /* intel_opregion.c */
+ struct intel_encoder;
  extern int intel_opregion_setup(struct drm_device *dev);
  #ifdef CONFIG_ACPI
  extern void intel_opregion_init(struct drm_device *dev);
  extern void intel_opregion_fini(struct drm_device *dev);
  extern void intel_opregion_asle_intr(struct drm_device *dev);
+ extern int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
+                                        bool enable);
+ extern int intel_opregion_notify_adapter(struct drm_device *dev,
+                                        pci_power_t state);
  #else
  static inline void intel_opregion_init(struct drm_device *dev) { return; }
  static inline void intel_opregion_fini(struct drm_device *dev) { return; }
  static inline void intel_opregion_asle_intr(struct drm_device *dev) { return; }
+ static inline int
+ intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, bool enable)
+ {
+       return 0;
+ }
+ static inline int
+ intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
+ {
+       return 0;
+ }
  #endif
  
  /* intel_acpi.c */
@@@ -2256,8 -2319,16 +2323,16 @@@ int sandybridge_pcode_write(struct drm_
  u32 vlv_punit_read(struct drm_i915_private *dev_priv, u8 addr);
  void vlv_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val);
  u32 vlv_nc_read(struct drm_i915_private *dev_priv, u8 addr);
- u32 vlv_dpio_read(struct drm_i915_private *dev_priv, int reg);
- void vlv_dpio_write(struct drm_i915_private *dev_priv, int reg, u32 val);
+ u32 vlv_gpio_nc_read(struct drm_i915_private *dev_priv, u32 reg);
+ void vlv_gpio_nc_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+ u32 vlv_cck_read(struct drm_i915_private *dev_priv, u32 reg);
+ void vlv_cck_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+ u32 vlv_ccu_read(struct drm_i915_private *dev_priv, u32 reg);
+ void vlv_ccu_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+ u32 vlv_gps_core_read(struct drm_i915_private *dev_priv, u32 reg);
+ void vlv_gps_core_write(struct drm_i915_private *dev_priv, u32 reg, u32 val);
+ u32 vlv_dpio_read(struct drm_i915_private *dev_priv, enum pipe pipe, int reg);
+ void vlv_dpio_write(struct drm_i915_private *dev_priv, enum pipe pipe, int reg, u32 val);
  u32 intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
                   enum intel_sbi_destination destination);
  void intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
index 1f7b4caefb6e0776bf61d78af519812765b37741,e999496532c6fed6e28dfa25e5be30cab48a69ff..c4c42e7cbd7bbf9a6641d1ca688e9b6be50d9f75
  #define HSW_WT_ELLC_LLC_AGE0          HSW_CACHEABILITY_CONTROL(0x6)
  
  static gen6_gtt_pte_t snb_pte_encode(dma_addr_t addr,
 -                                   enum i915_cache_level level)
 +                                   enum i915_cache_level level,
 +                                   bool valid)
  {
 -      gen6_gtt_pte_t pte = GEN6_PTE_VALID;
 +      gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
        pte |= GEN6_PTE_ADDR_ENCODE(addr);
  
        switch (level) {
  }
  
  static gen6_gtt_pte_t ivb_pte_encode(dma_addr_t addr,
 -                                   enum i915_cache_level level)
 +                                   enum i915_cache_level level,
 +                                   bool valid)
  {
 -      gen6_gtt_pte_t pte = GEN6_PTE_VALID;
 +      gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
        pte |= GEN6_PTE_ADDR_ENCODE(addr);
  
        switch (level) {
  #define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2)
  
  static gen6_gtt_pte_t byt_pte_encode(dma_addr_t addr,
 -                                   enum i915_cache_level level)
 +                                   enum i915_cache_level level,
 +                                   bool valid)
  {
 -      gen6_gtt_pte_t pte = GEN6_PTE_VALID;
 +      gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
        pte |= GEN6_PTE_ADDR_ENCODE(addr);
  
        /* Mark the page as writeable.  Other platforms don't have a
  }
  
  static gen6_gtt_pte_t hsw_pte_encode(dma_addr_t addr,
 -                                   enum i915_cache_level level)
 +                                   enum i915_cache_level level,
 +                                   bool valid)
  {
 -      gen6_gtt_pte_t pte = GEN6_PTE_VALID;
 +      gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
        pte |= HSW_PTE_ADDR_ENCODE(addr);
  
        if (level != I915_CACHE_NONE)
  }
  
  static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
 -                                    enum i915_cache_level level)
 +                                    enum i915_cache_level level,
 +                                    bool valid)
  {
 -      gen6_gtt_pte_t pte = GEN6_PTE_VALID;
 +      gen6_gtt_pte_t pte = valid ? GEN6_PTE_VALID : 0;
        pte |= HSW_PTE_ADDR_ENCODE(addr);
  
        switch (level) {
@@@ -241,8 -236,7 +241,8 @@@ static int gen6_ppgtt_enable(struct drm
  /* PPGTT support for Sandybdrige/Gen6 and later */
  static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
                                   unsigned first_entry,
 -                                 unsigned num_entries)
 +                                 unsigned num_entries,
 +                                 bool use_scratch)
  {
        struct i915_hw_ppgtt *ppgtt =
                container_of(vm, struct i915_hw_ppgtt, base);
        unsigned first_pte = first_entry % I915_PPGTT_PT_ENTRIES;
        unsigned last_pte, i;
  
 -      scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC);
 +      scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, true);
  
        while (num_entries) {
                last_pte = first_pte + num_entries;
@@@ -288,7 -282,7 +288,7 @@@ static void gen6_ppgtt_insert_entries(s
                dma_addr_t page_addr;
  
                page_addr = sg_page_iter_dma_address(&sg_iter);
 -              pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level);
 +              pt_vaddr[act_pte] = vm->pte_encode(page_addr, cache_level, true);
                if (++act_pte == I915_PPGTT_PT_ENTRIES) {
                        kunmap_atomic(pt_vaddr);
                        act_pt++;
@@@ -342,7 -336,7 +342,7 @@@ static int gen6_ppgtt_init(struct i915_
        ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
        ppgtt->base.cleanup = gen6_ppgtt_cleanup;
        ppgtt->base.scratch = dev_priv->gtt.base.scratch;
-       ppgtt->pt_pages = kzalloc(sizeof(struct page *)*ppgtt->num_pd_entries,
+       ppgtt->pt_pages = kcalloc(ppgtt->num_pd_entries, sizeof(struct page *),
                                  GFP_KERNEL);
        if (!ppgtt->pt_pages)
                return -ENOMEM;
                        goto err_pt_alloc;
        }
  
-       ppgtt->pt_dma_addr = kzalloc(sizeof(dma_addr_t) *ppgtt->num_pd_entries,
+       ppgtt->pt_dma_addr = kcalloc(ppgtt->num_pd_entries, sizeof(dma_addr_t),
                                     GFP_KERNEL);
        if (!ppgtt->pt_dma_addr)
                goto err_pt_alloc;
        }
  
        ppgtt->base.clear_range(&ppgtt->base, 0,
 -                              ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES);
 +                              ppgtt->num_pd_entries * I915_PPGTT_PT_ENTRIES, true);
  
        ppgtt->pd_offset = first_pd_entry_in_global_pt * sizeof(gen6_gtt_pte_t);
  
@@@ -450,8 -444,7 +450,8 @@@ void i915_ppgtt_unbind_object(struct i9
  {
        ppgtt->base.clear_range(&ppgtt->base,
                                i915_gem_obj_ggtt_offset(obj) >> PAGE_SHIFT,
 -                              obj->base.size >> PAGE_SHIFT);
 +                              obj->base.size >> PAGE_SHIFT,
 +                              true);
  }
  
  extern int intel_iommu_gfx_mapped;
@@@ -492,65 -485,15 +492,65 @@@ static void undo_idling(struct drm_i915
                dev_priv->mm.interruptible = interruptible;
  }
  
 +void i915_check_and_clear_faults(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +      struct intel_ring_buffer *ring;
 +      int i;
 +
 +      if (INTEL_INFO(dev)->gen < 6)
 +              return;
 +
 +      for_each_ring(ring, dev_priv, i) {
 +              u32 fault_reg;
 +              fault_reg = I915_READ(RING_FAULT_REG(ring));
 +              if (fault_reg & RING_FAULT_VALID) {
 +                      DRM_DEBUG_DRIVER("Unexpected fault\n"
 +                                       "\tAddr: 0x%08lx\\n"
 +                                       "\tAddress space: %s\n"
 +                                       "\tSource ID: %d\n"
 +                                       "\tType: %d\n",
 +                                       fault_reg & PAGE_MASK,
 +                                       fault_reg & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT",
 +                                       RING_FAULT_SRCID(fault_reg),
 +                                       RING_FAULT_FAULT_TYPE(fault_reg));
 +                      I915_WRITE(RING_FAULT_REG(ring),
 +                                 fault_reg & ~RING_FAULT_VALID);
 +              }
 +      }
 +      POSTING_READ(RING_FAULT_REG(&dev_priv->ring[RCS]));
 +}
 +
 +void i915_gem_suspend_gtt_mappings(struct drm_device *dev)
 +{
 +      struct drm_i915_private *dev_priv = dev->dev_private;
 +
 +      /* Don't bother messing with faults pre GEN6 as we have little
 +       * documentation supporting that it's a good idea.
 +       */
 +      if (INTEL_INFO(dev)->gen < 6)
 +              return;
 +
 +      i915_check_and_clear_faults(dev);
 +
 +      dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
 +                                     dev_priv->gtt.base.start / PAGE_SIZE,
 +                                     dev_priv->gtt.base.total / PAGE_SIZE,
 +                                     false);
 +}
 +
  void i915_gem_restore_gtt_mappings(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj;
  
 +      i915_check_and_clear_faults(dev);
 +
        /* First fill our portion of the GTT with scratch pages */
        dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
                                       dev_priv->gtt.base.start / PAGE_SIZE,
 -                                     dev_priv->gtt.base.total / PAGE_SIZE);
 +                                     dev_priv->gtt.base.total / PAGE_SIZE,
 +                                     true);
  
        list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
                i915_gem_clflush_object(obj, obj->pin_display);
@@@ -593,7 -536,7 +593,7 @@@ static void gen6_ggtt_insert_entries(st
  
        for_each_sg_page(st->sgl, &sg_iter, st->nents, 0) {
                addr = sg_page_iter_dma_address(&sg_iter);
 -              iowrite32(vm->pte_encode(addr, level), &gtt_entries[i]);
 +              iowrite32(vm->pte_encode(addr, level, true), &gtt_entries[i]);
                i++;
        }
  
         */
        if (i != 0)
                WARN_ON(readl(&gtt_entries[i-1]) !=
 -                      vm->pte_encode(addr, level));
 +                      vm->pte_encode(addr, level, true));
  
        /* This next bit makes the above posting read even more important. We
         * want to flush the TLBs only after we're certain all the PTE updates
  
  static void gen6_ggtt_clear_range(struct i915_address_space *vm,
                                  unsigned int first_entry,
 -                                unsigned int num_entries)
 +                                unsigned int num_entries,
 +                                bool use_scratch)
  {
        struct drm_i915_private *dev_priv = vm->dev->dev_private;
        gen6_gtt_pte_t scratch_pte, __iomem *gtt_base =
                 first_entry, num_entries, max_entries))
                num_entries = max_entries;
  
 -      scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC);
 +      scratch_pte = vm->pte_encode(vm->scratch.addr, I915_CACHE_LLC, use_scratch);
 +
        for (i = 0; i < num_entries; i++)
                iowrite32(scratch_pte, &gtt_base[i]);
        readl(gtt_base);
@@@ -653,8 -594,7 +653,8 @@@ static void i915_ggtt_insert_entries(st
  
  static void i915_ggtt_clear_range(struct i915_address_space *vm,
                                  unsigned int first_entry,
 -                                unsigned int num_entries)
 +                                unsigned int num_entries,
 +                                bool unused)
  {
        intel_gtt_clear_range(first_entry, num_entries);
  }
@@@ -682,8 -622,7 +682,8 @@@ void i915_gem_gtt_unbind_object(struct 
  
        dev_priv->gtt.base.clear_range(&dev_priv->gtt.base,
                                       entry,
 -                                     obj->base.size >> PAGE_SHIFT);
 +                                     obj->base.size >> PAGE_SHIFT,
 +                                     true);
  
        obj->has_global_gtt_mapping = 0;
  }
@@@ -770,11 -709,11 +770,11 @@@ void i915_gem_setup_global_gtt(struct d
                const unsigned long count = (hole_end - hole_start) / PAGE_SIZE;
                DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
                              hole_start, hole_end);
 -              ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count);
 +              ggtt_vm->clear_range(ggtt_vm, hole_start / PAGE_SIZE, count, true);
        }
  
        /* And finally clear the reserved guard page */
 -      ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1);
 +      ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1, true);
  }
  
  static bool
index ef9b35479f0136d0cb23ec7f6eb2bb59afa85e46,95385023e0bacd53eb8cb6c509509e063d9841b8..b83ec4903aa717f55493c0c87864e2117ed1235e
  #define  MI_SEMAPHORE_SYNC_VVE            (1<<16) /* VECS wait for VCS  (VEVSYNC) */
  #define  MI_SEMAPHORE_SYNC_RVE            (2<<16) /* VECS wait for RCS  (VERSYNC) */
  #define  MI_SEMAPHORE_SYNC_INVALID  (3<<16)
+ #define MI_PREDICATE_RESULT_2 (0x2214)
+ #define  LOWER_SLICE_ENABLED  (1<<0)
+ #define  LOWER_SLICE_DISABLED (0<<0)
  /*
   * 3D instructions used by the kernel
   */
  #define   IOSF_PORT_PUNIT                     0x4
  #define   IOSF_PORT_NC                                0x11
  #define   IOSF_PORT_DPIO                      0x12
+ #define   IOSF_PORT_GPIO_NC                   0x13
+ #define   IOSF_PORT_CCK                               0x14
+ #define   IOSF_PORT_CCU                               0xA9
+ #define   IOSF_PORT_GPS_CORE                  0x48
  #define VLV_IOSF_DATA                         (VLV_DISPLAY_BASE + 0x2104)
  #define VLV_IOSF_ADDR                         (VLV_DISPLAY_BASE + 0x2108)
  
  #define PUNIT_OPCODE_REG_READ                 6
  #define PUNIT_OPCODE_REG_WRITE                        7
  
+ #define PUNIT_REG_PWRGT_CTRL                  0x60
+ #define PUNIT_REG_PWRGT_STATUS                        0x61
+ #define         PUNIT_CLK_GATE                        1
+ #define         PUNIT_PWR_RESET                       2
+ #define         PUNIT_PWR_GATE                        3
+ #define         RENDER_PWRGT                          (PUNIT_PWR_GATE << 0)
+ #define         MEDIA_PWRGT                           (PUNIT_PWR_GATE << 2)
+ #define         DISP2D_PWRGT                          (PUNIT_PWR_GATE << 6)
  #define PUNIT_REG_GPU_LFM                     0xd3
  #define PUNIT_REG_GPU_FREQ_REQ                        0xd4
  #define PUNIT_REG_GPU_FREQ_STS                        0xd8
  #define   FB_FMAX_VMIN_FREQ_LO_SHIFT          27
  #define   FB_FMAX_VMIN_FREQ_LO_MASK           0xf8000000
  
+ /* vlv2 north clock has */
+ #define CCK_FUSE_REG                          0x8
+ #define  CCK_FUSE_HPLL_FREQ_MASK              0x3
+ #define CCK_REG_DSI_PLL_FUSE                  0x44
+ #define CCK_REG_DSI_PLL_CONTROL                       0x48
+ #define  DSI_PLL_VCO_EN                               (1 << 31)
+ #define  DSI_PLL_LDO_GATE                     (1 << 30)
+ #define  DSI_PLL_P1_POST_DIV_SHIFT            17
+ #define  DSI_PLL_P1_POST_DIV_MASK             (0x1ff << 17)
+ #define  DSI_PLL_P2_MUX_DSI0_DIV2             (1 << 13)
+ #define  DSI_PLL_P3_MUX_DSI1_DIV2             (1 << 12)
+ #define  DSI_PLL_MUX_MASK                     (3 << 9)
+ #define  DSI_PLL_MUX_DSI0_DSIPLL              (0 << 10)
+ #define  DSI_PLL_MUX_DSI0_CCK                 (1 << 10)
+ #define  DSI_PLL_MUX_DSI1_DSIPLL              (0 << 9)
+ #define  DSI_PLL_MUX_DSI1_CCK                 (1 << 9)
+ #define  DSI_PLL_CLK_GATE_MASK                        (0xf << 5)
+ #define  DSI_PLL_CLK_GATE_DSI0_DSIPLL         (1 << 8)
+ #define  DSI_PLL_CLK_GATE_DSI1_DSIPLL         (1 << 7)
+ #define  DSI_PLL_CLK_GATE_DSI0_CCK            (1 << 6)
+ #define  DSI_PLL_CLK_GATE_DSI1_CCK            (1 << 5)
+ #define  DSI_PLL_LOCK                         (1 << 0)
+ #define CCK_REG_DSI_PLL_DIVIDER                       0x4c
+ #define  DSI_PLL_LFSR                         (1 << 31)
+ #define  DSI_PLL_FRACTION_EN                  (1 << 30)
+ #define  DSI_PLL_FRAC_COUNTER_SHIFT           27
+ #define  DSI_PLL_FRAC_COUNTER_MASK            (7 << 27)
+ #define  DSI_PLL_USYNC_CNT_SHIFT              18
+ #define  DSI_PLL_USYNC_CNT_MASK                       (0x1ff << 18)
+ #define  DSI_PLL_N1_DIV_SHIFT                 16
+ #define  DSI_PLL_N1_DIV_MASK                  (3 << 16)
+ #define  DSI_PLL_M1_DIV_SHIFT                 0
+ #define  DSI_PLL_M1_DIV_MASK                  (0x1ff << 0)
  /*
   * DPIO - a special bus for various display related registers to hide behind
   *
  #define  DPIO_MODSEL1                 (1<<3) /* if ref clk b == 27 */
  #define  DPIO_MODSEL0                 (1<<2) /* if ref clk a == 27 */
  #define  DPIO_SFR_BYPASS              (1<<1)
- #define  DPIO_RESET                   (1<<0)
+ #define  DPIO_CMNRST                  (1<<0)
  
  #define _DPIO_TX3_SWING_CTL4_A                0x690
  #define _DPIO_TX3_SWING_CTL4_B                0x2a90
  #define   ARB_MODE_SWIZZLE_IVB        (1<<5)
  #define RENDER_HWS_PGA_GEN7   (0x04080)
  #define RING_FAULT_REG(ring)  (0x4094 + 0x100*(ring)->id)
 +#define   RING_FAULT_GTTSEL_MASK (1<<11)
 +#define   RING_FAULT_SRCID(x) ((x >> 3) & 0xff)
 +#define   RING_FAULT_FAULT_TYPE(x) ((x >> 1) & 0x3)
 +#define   RING_FAULT_VALID    (1<<0)
  #define DONE_REG              0x40b0
  #define BSD_HWS_PGA_GEN7      (0x04180)
  #define BLT_HWS_PGA_GEN7      (0x04280)
  #define GT_BLT_USER_INTERRUPT                 (1 << 22)
  #define GT_BSD_CS_ERROR_INTERRUPT             (1 << 15)
  #define GT_BSD_USER_INTERRUPT                 (1 << 12)
+ #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1        (1 << 11) /* hsw+; rsvd on snb, ivb, vlv */
  #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT   (1 <<  5) /* !snb */
  #define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT    (1 <<  4)
  #define GT_RENDER_CS_MASTER_ERROR_INTERRUPT   (1 <<  3)
  #define PM_VEBOX_CS_ERROR_INTERRUPT           (1 << 12) /* hsw+ */
  #define PM_VEBOX_USER_INTERRUPT                       (1 << 10) /* hsw+ */
  
+ #define GT_PARITY_ERROR(dev) \
+       (GT_RENDER_L3_PARITY_ERROR_INTERRUPT | \
+        (IS_HASWELL(dev) ? GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 : 0))
  /* These are all the "old" interrupts */
  #define ILK_BSD_USER_INTERRUPT                                (1<<5)
  #define I915_PIPE_CONTROL_NOTIFY_INTERRUPT            (1<<18)
  
  #define MI_ARB_VLV            (VLV_DISPLAY_BASE + 0x6504)
  
+ #define CZCLK_CDCLK_FREQ_RATIO        (VLV_DISPLAY_BASE + 0x6508)
+ #define   CDCLK_FREQ_SHIFT    4
+ #define   CDCLK_FREQ_MASK     (0x1f << CDCLK_FREQ_SHIFT)
+ #define   CZCLK_FREQ_MASK     0xf
+ #define GMBUSFREQ_VLV         (VLV_DISPLAY_BASE + 0x6510)
  /*
   * Palette regs
   */
   * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
   * every way.  It is not accessible from the CP register read instructions.
   *
+  * Starting from Haswell, you can't write registers using the MCHBAR mirror,
+  * just read.
   */
  #define MCHBAR_MIRROR_BASE    0x10000
  
   */
  #define HSW_CXT_TOTAL_SIZE            (17 * PAGE_SIZE)
  
+ #define VLV_CLK_CTL2                  0x101104
+ #define   CLK_CTL2_CZCOUNT_30NS_SHIFT 28
  /*
   * Overlay regs
   */
  #define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B)
  
  /* HSW eDP PSR registers */
- #define EDP_PSR_CTL                           0x64800
+ #define EDP_PSR_BASE(dev)                     0x64800
+ #define EDP_PSR_CTL(dev)                      (EDP_PSR_BASE(dev) + 0)
  #define   EDP_PSR_ENABLE                      (1<<31)
  #define   EDP_PSR_LINK_DISABLE                        (0<<27)
  #define   EDP_PSR_LINK_STANDBY                        (1<<27)
  #define   EDP_PSR_TP1_TIME_0us                        (3<<4)
  #define   EDP_PSR_IDLE_FRAME_SHIFT            0
  
- #define EDP_PSR_AUX_CTL                       0x64810
- #define EDP_PSR_AUX_DATA1             0x64814
+ #define EDP_PSR_AUX_CTL(dev)                  (EDP_PSR_BASE(dev) + 0x10)
+ #define EDP_PSR_AUX_DATA1(dev)                        (EDP_PSR_BASE(dev) + 0x14)
  #define   EDP_PSR_DPCD_COMMAND                0x80060000
- #define EDP_PSR_AUX_DATA2             0x64818
+ #define EDP_PSR_AUX_DATA2(dev)                        (EDP_PSR_BASE(dev) + 0x18)
  #define   EDP_PSR_DPCD_NORMAL_OPERATION       (1<<24)
- #define EDP_PSR_AUX_DATA3             0x6481c
- #define EDP_PSR_AUX_DATA4             0x64820
- #define EDP_PSR_AUX_DATA5             0x64824
+ #define EDP_PSR_AUX_DATA3(dev)                        (EDP_PSR_BASE(dev) + 0x1c)
+ #define EDP_PSR_AUX_DATA4(dev)                        (EDP_PSR_BASE(dev) + 0x20)
+ #define EDP_PSR_AUX_DATA5(dev)                        (EDP_PSR_BASE(dev) + 0x24)
  
- #define EDP_PSR_STATUS_CTL                    0x64840
+ #define EDP_PSR_STATUS_CTL(dev)                       (EDP_PSR_BASE(dev) + 0x40)
  #define   EDP_PSR_STATUS_STATE_MASK           (7<<29)
  #define   EDP_PSR_STATUS_STATE_IDLE           (0<<29)
  #define   EDP_PSR_STATUS_STATE_SRDONACK               (1<<29)
  #define   EDP_PSR_STATUS_SENDING_TP1          (1<<4)
  #define   EDP_PSR_STATUS_IDLE_MASK            0xf
  
- #define EDP_PSR_PERF_CNT              0x64844
+ #define EDP_PSR_PERF_CNT(dev)         (EDP_PSR_BASE(dev) + 0x44)
  #define   EDP_PSR_PERF_CNT_MASK               0xffffff
  
- #define EDP_PSR_DEBUG_CTL             0x64860
+ #define EDP_PSR_DEBUG_CTL(dev)                (EDP_PSR_BASE(dev) + 0x60)
  #define   EDP_PSR_DEBUG_MASK_LPSP     (1<<27)
  #define   EDP_PSR_DEBUG_MASK_MEMUP    (1<<26)
  #define   EDP_PSR_DEBUG_MASK_HPD      (1<<25)
  
  /* Gen 4 SDVO/HDMI bits: */
  #define   SDVO_COLOR_FORMAT_8bpc              (0 << 26)
+ #define   SDVO_COLOR_FORMAT_MASK              (7 << 26)
  #define   SDVO_ENCODING_SDVO                  (0 << 10)
  #define   SDVO_ENCODING_HDMI                  (2 << 10)
  #define   HDMI_MODE_SELECT_HDMI                       (1 << 9) /* HDMI only */
  #define   PIPECONF_DISABLE    0
  #define   PIPECONF_DOUBLE_WIDE        (1<<30)
  #define   I965_PIPECONF_ACTIVE        (1<<30)
+ #define   PIPECONF_DSI_PLL_LOCKED     (1<<29) /* vlv & pipe A only */
  #define   PIPECONF_FRAME_START_DELAY_MASK (3<<27)
  #define   PIPECONF_SINGLE_WIDE        0
  #define   PIPECONF_PIPE_UNLOCKED 0
  #define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG                0x9030
  #define  GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB     (1<<11)
  
 +#define HSW_SCRATCH1                          0xb038
 +#define  HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE (1<<27)
 +
  #define HSW_FUSE_STRAP                0x42014
  #define  HSW_CDCLK_LIMIT      (1 << 24)
  
  #define FDI_RX_CHICKEN(pipe) _PIPE(pipe, _FDI_RXA_CHICKEN, _FDI_RXB_CHICKEN)
  
  #define SOUTH_DSPCLK_GATE_D   0xc2020
 +#define  PCH_DPLUNIT_CLOCK_GATE_DISABLE (1<<30)
  #define  PCH_DPLSUNIT_CLOCK_GATE_DISABLE (1<<29)
 +#define  PCH_CPUNIT_CLOCK_GATE_DISABLE (1<<14)
  #define  PCH_LP_PARTITION_LEVEL_DISABLE  (1<<12)
  
  /* CPU: FDI_TX */
  #define PIPEA_PP_STATUS         (VLV_DISPLAY_BASE + 0x61200)
  #define PIPEA_PP_CONTROL        (VLV_DISPLAY_BASE + 0x61204)
  #define PIPEA_PP_ON_DELAYS      (VLV_DISPLAY_BASE + 0x61208)
+ #define  PANEL_PORT_SELECT_DPB_VLV    (1 << 30)
+ #define  PANEL_PORT_SELECT_DPC_VLV    (2 << 30)
  #define PIPEA_PP_OFF_DELAYS     (VLV_DISPLAY_BASE + 0x6120c)
  #define PIPEA_PP_DIVISOR        (VLV_DISPLAY_BASE + 0x61210)
  
  #define  PANEL_PORT_SELECT_MASK       (3 << 30)
  #define  PANEL_PORT_SELECT_LVDS       (0 << 30)
  #define  PANEL_PORT_SELECT_DPA        (1 << 30)
- #define  EDP_PANEL            (1 << 30)
  #define  PANEL_PORT_SELECT_DPC        (2 << 30)
  #define  PANEL_PORT_SELECT_DPD        (3 << 30)
  #define  PANEL_POWER_UP_DELAY_MASK    (0x1fff0000)
  #define  PANEL_LIGHT_ON_DELAY_SHIFT   0
  
  #define PCH_PP_OFF_DELAYS     0xc720c
- #define  PANEL_POWER_PORT_SELECT_MASK (0x3 << 30)
- #define  PANEL_POWER_PORT_LVDS                (0 << 30)
- #define  PANEL_POWER_PORT_DP_A                (1 << 30)
- #define  PANEL_POWER_PORT_DP_C                (2 << 30)
- #define  PANEL_POWER_PORT_DP_D                (3 << 30)
  #define  PANEL_POWER_DOWN_DELAY_MASK  (0x1fff0000)
  #define  PANEL_POWER_DOWN_DELAY_SHIFT 16
  #define  PANEL_LIGHT_OFF_DELAY_MASK   (0x1fff)
  #define   GEN6_RP_UP_IDLE_MIN                 (0x1<<3)
  #define   GEN6_RP_UP_BUSY_AVG                 (0x2<<3)
  #define   GEN6_RP_UP_BUSY_CONT                        (0x4<<3)
- #define   GEN7_RP_DOWN_IDLE_AVG                       (0x2<<0)
+ #define   GEN6_RP_DOWN_IDLE_AVG                       (0x2<<0)
  #define   GEN6_RP_DOWN_IDLE_CONT              (0x1<<0)
  #define GEN6_RP_UP_THRESHOLD                  0xA02C
  #define GEN6_RP_DOWN_THRESHOLD                        0xA030
                                                 GEN6_PM_RP_DOWN_TIMEOUT)
  
  #define GEN6_GT_GFX_RC6_LOCKED                        0x138104
+ #define VLV_COUNTER_CONTROL                   0x138104
+ #define   VLV_COUNT_RANGE_HIGH                        (1<<15)
+ #define   VLV_MEDIA_RC6_COUNT_EN              (1<<1)
+ #define   VLV_RENDER_RC6_COUNT_EN             (1<<0)
  #define GEN6_GT_GFX_RC6                               0x138108
  #define GEN6_GT_GFX_RC6p                      0x13810C
  #define GEN6_GT_GFX_RC6pp                     0x138110
  #define   GEN6_PCODE_READ_MIN_FREQ_TABLE      0x9
  #define         GEN6_PCODE_WRITE_RC6VIDS              0x4
  #define         GEN6_PCODE_READ_RC6VIDS               0x5
+ #define   GEN6_PCODE_READ_D_COMP              0x10
+ #define   GEN6_PCODE_WRITE_D_COMP             0x11
  #define   GEN6_ENCODE_RC6_VID(mv)             (((mv) - 245) / 5)
  #define   GEN6_DECODE_RC6_VID(vids)           (((vids) * 5) + 245)
  #define GEN6_PCODE_DATA                               0x138128
  
  /* IVYBRIDGE DPF */
  #define GEN7_L3CDERRST1                       0xB008 /* L3CD Error Status 1 */
+ #define HSW_L3CDERRST11                       0xB208 /* L3CD Error Status register 1 slice 1 */
  #define   GEN7_L3CDERRST1_ROW_MASK    (0x7ff<<14)
  #define   GEN7_PARITY_ERROR_VALID     (1<<13)
  #define   GEN7_L3CDERRST1_BANK_MASK   (3<<11)
  #define   GEN7_L3CDERRST1_ENABLE      (1<<7)
  
  #define GEN7_L3LOG_BASE                       0xB070
+ #define HSW_L3LOG_BASE_SLICE1         0xB270
  #define GEN7_L3LOG_SIZE                       0x80
  
  #define GEN7_HALF_SLICE_CHICKEN1      0xe100 /* IVB GT1 + VLV */
  #define GEN7_ROW_CHICKEN2_GT2         0xf4f4
  #define   DOP_CLOCK_GATING_DISABLE    (1<<0)
  
 +#define HSW_ROW_CHICKEN3              0xe49c
 +#define  HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE    (1 << 6)
 +
  #define G4X_AUD_VID_DID                       (dev_priv->info->display_mmio_offset + 0x62020)
  #define INTEL_AUDIO_DEVCL             0x808629FB
  #define INTEL_AUDIO_DEVBLC            0x80862801
  #define PIPE_CSC_POSTOFF_ME(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_ME, _PIPE_B_CSC_POSTOFF_ME)
  #define PIPE_CSC_POSTOFF_LO(pipe) _PIPE(pipe, _PIPE_A_CSC_POSTOFF_LO, _PIPE_B_CSC_POSTOFF_LO)
  
+ /* VLV MIPI registers */
+ #define _MIPIA_PORT_CTRL                      (VLV_DISPLAY_BASE + 0x61190)
+ #define _MIPIB_PORT_CTRL                      (VLV_DISPLAY_BASE + 0x61700)
+ #define MIPI_PORT_CTRL(pipe)          _PIPE(pipe, _MIPIA_PORT_CTRL, _MIPIB_PORT_CTRL)
+ #define  DPI_ENABLE                                   (1 << 31) /* A + B */
+ #define  MIPIA_MIPI4DPHY_DELAY_COUNT_SHIFT            27
+ #define  MIPIA_MIPI4DPHY_DELAY_COUNT_MASK             (0xf << 27)
+ #define  DUAL_LINK_MODE_MASK                          (1 << 26)
+ #define  DUAL_LINK_MODE_FRONT_BACK                    (0 << 26)
+ #define  DUAL_LINK_MODE_PIXEL_ALTERNATIVE             (1 << 26)
+ #define  DITHERING_ENABLE                             (1 << 25) /* A + B */
+ #define  FLOPPED_HSTX                                 (1 << 23)
+ #define  DE_INVERT                                    (1 << 19) /* XXX */
+ #define  MIPIA_FLISDSI_DELAY_COUNT_SHIFT              18
+ #define  MIPIA_FLISDSI_DELAY_COUNT_MASK                       (0xf << 18)
+ #define  AFE_LATCHOUT                                 (1 << 17)
+ #define  LP_OUTPUT_HOLD                                       (1 << 16)
+ #define  MIPIB_FLISDSI_DELAY_COUNT_HIGH_SHIFT         15
+ #define  MIPIB_FLISDSI_DELAY_COUNT_HIGH_MASK          (1 << 15)
+ #define  MIPIB_MIPI4DPHY_DELAY_COUNT_SHIFT            11
+ #define  MIPIB_MIPI4DPHY_DELAY_COUNT_MASK             (0xf << 11)
+ #define  CSB_SHIFT                                    9
+ #define  CSB_MASK                                     (3 << 9)
+ #define  CSB_20MHZ                                    (0 << 9)
+ #define  CSB_10MHZ                                    (1 << 9)
+ #define  CSB_40MHZ                                    (2 << 9)
+ #define  BANDGAP_MASK                                 (1 << 8)
+ #define  BANDGAP_PNW_CIRCUIT                          (0 << 8)
+ #define  BANDGAP_LNC_CIRCUIT                          (1 << 8)
+ #define  MIPIB_FLISDSI_DELAY_COUNT_LOW_SHIFT          5
+ #define  MIPIB_FLISDSI_DELAY_COUNT_LOW_MASK           (7 << 5)
+ #define  TEARING_EFFECT_DELAY                         (1 << 4) /* A + B */
+ #define  TEARING_EFFECT_SHIFT                         2 /* A + B */
+ #define  TEARING_EFFECT_MASK                          (3 << 2)
+ #define  TEARING_EFFECT_OFF                           (0 << 2)
+ #define  TEARING_EFFECT_DSI                           (1 << 2)
+ #define  TEARING_EFFECT_GPIO                          (2 << 2)
+ #define  LANE_CONFIGURATION_SHIFT                     0
+ #define  LANE_CONFIGURATION_MASK                      (3 << 0)
+ #define  LANE_CONFIGURATION_4LANE                     (0 << 0)
+ #define  LANE_CONFIGURATION_DUAL_LINK_A                       (1 << 0)
+ #define  LANE_CONFIGURATION_DUAL_LINK_B                       (2 << 0)
+ #define _MIPIA_TEARING_CTRL                   (VLV_DISPLAY_BASE + 0x61194)
+ #define _MIPIB_TEARING_CTRL                   (VLV_DISPLAY_BASE + 0x61704)
+ #define MIPI_TEARING_CTRL(pipe)               _PIPE(pipe, _MIPIA_TEARING_CTRL, _MIPIB_TEARING_CTRL)
+ #define  TEARING_EFFECT_DELAY_SHIFT                   0
+ #define  TEARING_EFFECT_DELAY_MASK                    (0xffff << 0)
+ /* XXX: all bits reserved */
+ #define _MIPIA_AUTOPWG                                (VLV_DISPLAY_BASE + 0x611a0)
+ /* MIPI DSI Controller and D-PHY registers */
+ #define _MIPIA_DEVICE_READY                   (VLV_DISPLAY_BASE + 0xb000)
+ #define _MIPIB_DEVICE_READY                   (VLV_DISPLAY_BASE + 0xb800)
+ #define MIPI_DEVICE_READY(pipe)               _PIPE(pipe, _MIPIA_DEVICE_READY, _MIPIB_DEVICE_READY)
+ #define  BUS_POSSESSION                                       (1 << 3) /* set to give bus to receiver */
+ #define  ULPS_STATE_MASK                              (3 << 1)
+ #define  ULPS_STATE_ENTER                             (2 << 1)
+ #define  ULPS_STATE_EXIT                              (1 << 1)
+ #define  ULPS_STATE_NORMAL_OPERATION                  (0 << 1)
+ #define  DEVICE_READY                                 (1 << 0)
+ #define _MIPIA_INTR_STAT                      (VLV_DISPLAY_BASE + 0xb004)
+ #define _MIPIB_INTR_STAT                      (VLV_DISPLAY_BASE + 0xb804)
+ #define MIPI_INTR_STAT(pipe)          _PIPE(pipe, _MIPIA_INTR_STAT, _MIPIB_INTR_STAT)
+ #define _MIPIA_INTR_EN                                (VLV_DISPLAY_BASE + 0xb008)
+ #define _MIPIB_INTR_EN                                (VLV_DISPLAY_BASE + 0xb808)
+ #define MIPI_INTR_EN(pipe)            _PIPE(pipe, _MIPIA_INTR_EN, _MIPIB_INTR_EN)
+ #define  TEARING_EFFECT                                       (1 << 31)
+ #define  SPL_PKT_SENT_INTERRUPT                               (1 << 30)
+ #define  GEN_READ_DATA_AVAIL                          (1 << 29)
+ #define  LP_GENERIC_WR_FIFO_FULL                      (1 << 28)
+ #define  HS_GENERIC_WR_FIFO_FULL                      (1 << 27)
+ #define  RX_PROT_VIOLATION                            (1 << 26)
+ #define  RX_INVALID_TX_LENGTH                         (1 << 25)
+ #define  ACK_WITH_NO_ERROR                            (1 << 24)
+ #define  TURN_AROUND_ACK_TIMEOUT                      (1 << 23)
+ #define  LP_RX_TIMEOUT                                        (1 << 22)
+ #define  HS_TX_TIMEOUT                                        (1 << 21)
+ #define  DPI_FIFO_UNDERRUN                            (1 << 20)
+ #define  LOW_CONTENTION                                       (1 << 19)
+ #define  HIGH_CONTENTION                              (1 << 18)
+ #define  TXDSI_VC_ID_INVALID                          (1 << 17)
+ #define  TXDSI_DATA_TYPE_NOT_RECOGNISED                       (1 << 16)
+ #define  TXCHECKSUM_ERROR                             (1 << 15)
+ #define  TXECC_MULTIBIT_ERROR                         (1 << 14)
+ #define  TXECC_SINGLE_BIT_ERROR                               (1 << 13)
+ #define  TXFALSE_CONTROL_ERROR                                (1 << 12)
+ #define  RXDSI_VC_ID_INVALID                          (1 << 11)
+ #define  RXDSI_DATA_TYPE_NOT_REGOGNISED                       (1 << 10)
+ #define  RXCHECKSUM_ERROR                             (1 << 9)
+ #define  RXECC_MULTIBIT_ERROR                         (1 << 8)
+ #define  RXECC_SINGLE_BIT_ERROR                               (1 << 7)
+ #define  RXFALSE_CONTROL_ERROR                                (1 << 6)
+ #define  RXHS_RECEIVE_TIMEOUT_ERROR                   (1 << 5)
+ #define  RX_LP_TX_SYNC_ERROR                          (1 << 4)
+ #define  RXEXCAPE_MODE_ENTRY_ERROR                    (1 << 3)
+ #define  RXEOT_SYNC_ERROR                             (1 << 2)
+ #define  RXSOT_SYNC_ERROR                             (1 << 1)
+ #define  RXSOT_ERROR                                  (1 << 0)
+ #define _MIPIA_DSI_FUNC_PRG                   (VLV_DISPLAY_BASE + 0xb00c)
+ #define _MIPIB_DSI_FUNC_PRG                   (VLV_DISPLAY_BASE + 0xb80c)
+ #define MIPI_DSI_FUNC_PRG(pipe)               _PIPE(pipe, _MIPIA_DSI_FUNC_PRG, _MIPIB_DSI_FUNC_PRG)
+ #define  CMD_MODE_DATA_WIDTH_MASK                     (7 << 13)
+ #define  CMD_MODE_NOT_SUPPORTED                               (0 << 13)
+ #define  CMD_MODE_DATA_WIDTH_16_BIT                   (1 << 13)
+ #define  CMD_MODE_DATA_WIDTH_9_BIT                    (2 << 13)
+ #define  CMD_MODE_DATA_WIDTH_8_BIT                    (3 << 13)
+ #define  CMD_MODE_DATA_WIDTH_OPTION1                  (4 << 13)
+ #define  CMD_MODE_DATA_WIDTH_OPTION2                  (5 << 13)
+ #define  VID_MODE_FORMAT_MASK                         (0xf << 7)
+ #define  VID_MODE_NOT_SUPPORTED                               (0 << 7)
+ #define  VID_MODE_FORMAT_RGB565                               (1 << 7)
+ #define  VID_MODE_FORMAT_RGB666                               (2 << 7)
+ #define  VID_MODE_FORMAT_RGB666_LOOSE                 (3 << 7)
+ #define  VID_MODE_FORMAT_RGB888                               (4 << 7)
+ #define  CMD_MODE_CHANNEL_NUMBER_SHIFT                        5
+ #define  CMD_MODE_CHANNEL_NUMBER_MASK                 (3 << 5)
+ #define  VID_MODE_CHANNEL_NUMBER_SHIFT                        3
+ #define  VID_MODE_CHANNEL_NUMBER_MASK                 (3 << 3)
+ #define  DATA_LANES_PRG_REG_SHIFT                     0
+ #define  DATA_LANES_PRG_REG_MASK                      (7 << 0)
+ #define _MIPIA_HS_TX_TIMEOUT                  (VLV_DISPLAY_BASE + 0xb010)
+ #define _MIPIB_HS_TX_TIMEOUT                  (VLV_DISPLAY_BASE + 0xb810)
+ #define MIPI_HS_TX_TIMEOUT(pipe)      _PIPE(pipe, _MIPIA_HS_TX_TIMEOUT, _MIPIB_HS_TX_TIMEOUT)
+ #define  HIGH_SPEED_TX_TIMEOUT_COUNTER_MASK           0xffffff
+ #define _MIPIA_LP_RX_TIMEOUT                  (VLV_DISPLAY_BASE + 0xb014)
+ #define _MIPIB_LP_RX_TIMEOUT                  (VLV_DISPLAY_BASE + 0xb814)
+ #define MIPI_LP_RX_TIMEOUT(pipe)      _PIPE(pipe, _MIPIA_LP_RX_TIMEOUT, _MIPIB_LP_RX_TIMEOUT)
+ #define  LOW_POWER_RX_TIMEOUT_COUNTER_MASK            0xffffff
+ #define _MIPIA_TURN_AROUND_TIMEOUT            (VLV_DISPLAY_BASE + 0xb018)
+ #define _MIPIB_TURN_AROUND_TIMEOUT            (VLV_DISPLAY_BASE + 0xb818)
+ #define MIPI_TURN_AROUND_TIMEOUT(pipe)        _PIPE(pipe, _MIPIA_TURN_AROUND_TIMEOUT, _MIPIB_TURN_AROUND_TIMEOUT)
+ #define  TURN_AROUND_TIMEOUT_MASK                     0x3f
+ #define _MIPIA_DEVICE_RESET_TIMER             (VLV_DISPLAY_BASE + 0xb01c)
+ #define _MIPIB_DEVICE_RESET_TIMER             (VLV_DISPLAY_BASE + 0xb81c)
+ #define MIPI_DEVICE_RESET_TIMER(pipe) _PIPE(pipe, _MIPIA_DEVICE_RESET_TIMER, _MIPIB_DEVICE_RESET_TIMER)
+ #define  DEVICE_RESET_TIMER_MASK                      0xffff
+ #define _MIPIA_DPI_RESOLUTION                 (VLV_DISPLAY_BASE + 0xb020)
+ #define _MIPIB_DPI_RESOLUTION                 (VLV_DISPLAY_BASE + 0xb820)
+ #define MIPI_DPI_RESOLUTION(pipe)     _PIPE(pipe, _MIPIA_DPI_RESOLUTION, _MIPIB_DPI_RESOLUTION)
+ #define  VERTICAL_ADDRESS_SHIFT                               16
+ #define  VERTICAL_ADDRESS_MASK                                (0xffff << 16)
+ #define  HORIZONTAL_ADDRESS_SHIFT                     0
+ #define  HORIZONTAL_ADDRESS_MASK                      0xffff
+ #define _MIPIA_DBI_FIFO_THROTTLE              (VLV_DISPLAY_BASE + 0xb024)
+ #define _MIPIB_DBI_FIFO_THROTTLE              (VLV_DISPLAY_BASE + 0xb824)
+ #define MIPI_DBI_FIFO_THROTTLE(pipe)  _PIPE(pipe, _MIPIA_DBI_FIFO_THROTTLE, _MIPIB_DBI_FIFO_THROTTLE)
+ #define  DBI_FIFO_EMPTY_HALF                          (0 << 0)
+ #define  DBI_FIFO_EMPTY_QUARTER                               (1 << 0)
+ #define  DBI_FIFO_EMPTY_7_LOCATIONS                   (2 << 0)
+ /* regs below are bits 15:0 */
+ #define _MIPIA_HSYNC_PADDING_COUNT            (VLV_DISPLAY_BASE + 0xb028)
+ #define _MIPIB_HSYNC_PADDING_COUNT            (VLV_DISPLAY_BASE + 0xb828)
+ #define MIPI_HSYNC_PADDING_COUNT(pipe)        _PIPE(pipe, _MIPIA_HSYNC_PADDING_COUNT, _MIPIB_HSYNC_PADDING_COUNT)
+ #define _MIPIA_HBP_COUNT                      (VLV_DISPLAY_BASE + 0xb02c)
+ #define _MIPIB_HBP_COUNT                      (VLV_DISPLAY_BASE + 0xb82c)
+ #define MIPI_HBP_COUNT(pipe)          _PIPE(pipe, _MIPIA_HBP_COUNT, _MIPIB_HBP_COUNT)
+ #define _MIPIA_HFP_COUNT                      (VLV_DISPLAY_BASE + 0xb030)
+ #define _MIPIB_HFP_COUNT                      (VLV_DISPLAY_BASE + 0xb830)
+ #define MIPI_HFP_COUNT(pipe)          _PIPE(pipe, _MIPIA_HFP_COUNT, _MIPIB_HFP_COUNT)
+ #define _MIPIA_HACTIVE_AREA_COUNT             (VLV_DISPLAY_BASE + 0xb034)
+ #define _MIPIB_HACTIVE_AREA_COUNT             (VLV_DISPLAY_BASE + 0xb834)
+ #define MIPI_HACTIVE_AREA_COUNT(pipe) _PIPE(pipe, _MIPIA_HACTIVE_AREA_COUNT, _MIPIB_HACTIVE_AREA_COUNT)
+ #define _MIPIA_VSYNC_PADDING_COUNT            (VLV_DISPLAY_BASE + 0xb038)
+ #define _MIPIB_VSYNC_PADDING_COUNT            (VLV_DISPLAY_BASE + 0xb838)
+ #define MIPI_VSYNC_PADDING_COUNT(pipe)        _PIPE(pipe, _MIPIA_VSYNC_PADDING_COUNT, _MIPIB_VSYNC_PADDING_COUNT)
+ #define _MIPIA_VBP_COUNT                      (VLV_DISPLAY_BASE + 0xb03c)
+ #define _MIPIB_VBP_COUNT                      (VLV_DISPLAY_BASE + 0xb83c)
+ #define MIPI_VBP_COUNT(pipe)          _PIPE(pipe, _MIPIA_VBP_COUNT, _MIPIB_VBP_COUNT)
+ #define _MIPIA_VFP_COUNT                      (VLV_DISPLAY_BASE + 0xb040)
+ #define _MIPIB_VFP_COUNT                      (VLV_DISPLAY_BASE + 0xb840)
+ #define MIPI_VFP_COUNT(pipe)          _PIPE(pipe, _MIPIA_VFP_COUNT, _MIPIB_VFP_COUNT)
+ #define _MIPIA_HIGH_LOW_SWITCH_COUNT          (VLV_DISPLAY_BASE + 0xb044)
+ #define _MIPIB_HIGH_LOW_SWITCH_COUNT          (VLV_DISPLAY_BASE + 0xb844)
+ #define MIPI_HIGH_LOW_SWITCH_COUNT(pipe)      _PIPE(pipe, _MIPIA_HIGH_LOW_SWITCH_COUNT, _MIPIB_HIGH_LOW_SWITCH_COUNT)
+ /* regs above are bits 15:0 */
+ #define _MIPIA_DPI_CONTROL                    (VLV_DISPLAY_BASE + 0xb048)
+ #define _MIPIB_DPI_CONTROL                    (VLV_DISPLAY_BASE + 0xb848)
+ #define MIPI_DPI_CONTROL(pipe)                _PIPE(pipe, _MIPIA_DPI_CONTROL, _MIPIB_DPI_CONTROL)
+ #define  DPI_LP_MODE                                  (1 << 6)
+ #define  BACKLIGHT_OFF                                        (1 << 5)
+ #define  BACKLIGHT_ON                                 (1 << 4)
+ #define  COLOR_MODE_OFF                                       (1 << 3)
+ #define  COLOR_MODE_ON                                        (1 << 2)
+ #define  TURN_ON                                      (1 << 1)
+ #define  SHUTDOWN                                     (1 << 0)
+ #define _MIPIA_DPI_DATA                               (VLV_DISPLAY_BASE + 0xb04c)
+ #define _MIPIB_DPI_DATA                               (VLV_DISPLAY_BASE + 0xb84c)
+ #define MIPI_DPI_DATA(pipe)           _PIPE(pipe, _MIPIA_DPI_DATA, _MIPIB_DPI_DATA)
+ #define  COMMAND_BYTE_SHIFT                           0
+ #define  COMMAND_BYTE_MASK                            (0x3f << 0)
+ #define _MIPIA_INIT_COUNT                     (VLV_DISPLAY_BASE + 0xb050)
+ #define _MIPIB_INIT_COUNT                     (VLV_DISPLAY_BASE + 0xb850)
+ #define MIPI_INIT_COUNT(pipe)         _PIPE(pipe, _MIPIA_INIT_COUNT, _MIPIB_INIT_COUNT)
+ #define  MASTER_INIT_TIMER_SHIFT                      0
+ #define  MASTER_INIT_TIMER_MASK                               (0xffff << 0)
+ #define _MIPIA_MAX_RETURN_PKT_SIZE            (VLV_DISPLAY_BASE + 0xb054)
+ #define _MIPIB_MAX_RETURN_PKT_SIZE            (VLV_DISPLAY_BASE + 0xb854)
+ #define MIPI_MAX_RETURN_PKT_SIZE(pipe)        _PIPE(pipe, _MIPIA_MAX_RETURN_PKT_SIZE, _MIPIB_MAX_RETURN_PKT_SIZE)
+ #define  MAX_RETURN_PKT_SIZE_SHIFT                    0
+ #define  MAX_RETURN_PKT_SIZE_MASK                     (0x3ff << 0)
+ #define _MIPIA_VIDEO_MODE_FORMAT              (VLV_DISPLAY_BASE + 0xb058)
+ #define _MIPIB_VIDEO_MODE_FORMAT              (VLV_DISPLAY_BASE + 0xb858)
+ #define MIPI_VIDEO_MODE_FORMAT(pipe)  _PIPE(pipe, _MIPIA_VIDEO_MODE_FORMAT, _MIPIB_VIDEO_MODE_FORMAT)
+ #define  RANDOM_DPI_DISPLAY_RESOLUTION                        (1 << 4)
+ #define  DISABLE_VIDEO_BTA                            (1 << 3)
+ #define  IP_TG_CONFIG                                 (1 << 2)
+ #define  VIDEO_MODE_NON_BURST_WITH_SYNC_PULSE         (1 << 0)
+ #define  VIDEO_MODE_NON_BURST_WITH_SYNC_EVENTS                (2 << 0)
+ #define  VIDEO_MODE_BURST                             (3 << 0)
+ #define _MIPIA_EOT_DISABLE                    (VLV_DISPLAY_BASE + 0xb05c)
+ #define _MIPIB_EOT_DISABLE                    (VLV_DISPLAY_BASE + 0xb85c)
+ #define MIPI_EOT_DISABLE(pipe)                _PIPE(pipe, _MIPIA_EOT_DISABLE, _MIPIB_EOT_DISABLE)
+ #define  LP_RX_TIMEOUT_ERROR_RECOVERY_DISABLE         (1 << 7)
+ #define  HS_RX_TIMEOUT_ERROR_RECOVERY_DISABLE         (1 << 6)
+ #define  LOW_CONTENTION_RECOVERY_DISABLE              (1 << 5)
+ #define  HIGH_CONTENTION_RECOVERY_DISABLE             (1 << 4)
+ #define  TXDSI_TYPE_NOT_RECOGNISED_ERROR_RECOVERY_DISABLE (1 << 3)
+ #define  TXECC_MULTIBIT_ERROR_RECOVERY_DISABLE                (1 << 2)
+ #define  CLOCKSTOP                                    (1 << 1)
+ #define  EOT_DISABLE                                  (1 << 0)
+ #define _MIPIA_LP_BYTECLK                     (VLV_DISPLAY_BASE + 0xb060)
+ #define _MIPIB_LP_BYTECLK                     (VLV_DISPLAY_BASE + 0xb860)
+ #define MIPI_LP_BYTECLK(pipe)         _PIPE(pipe, _MIPIA_LP_BYTECLK, _MIPIB_LP_BYTECLK)
+ #define  LP_BYTECLK_SHIFT                             0
+ #define  LP_BYTECLK_MASK                              (0xffff << 0)
+ /* bits 31:0 */
+ #define _MIPIA_LP_GEN_DATA                    (VLV_DISPLAY_BASE + 0xb064)
+ #define _MIPIB_LP_GEN_DATA                    (VLV_DISPLAY_BASE + 0xb864)
+ #define MIPI_LP_GEN_DATA(pipe)                _PIPE(pipe, _MIPIA_LP_GEN_DATA, _MIPIB_LP_GEN_DATA)
+ /* bits 31:0 */
+ #define _MIPIA_HS_GEN_DATA                    (VLV_DISPLAY_BASE + 0xb068)
+ #define _MIPIB_HS_GEN_DATA                    (VLV_DISPLAY_BASE + 0xb868)
+ #define MIPI_HS_GEN_DATA(pipe)                _PIPE(pipe, _MIPIA_HS_GEN_DATA, _MIPIB_HS_GEN_DATA)
+ #define _MIPIA_LP_GEN_CTRL                    (VLV_DISPLAY_BASE + 0xb06c)
+ #define _MIPIB_LP_GEN_CTRL                    (VLV_DISPLAY_BASE + 0xb86c)
+ #define MIPI_LP_GEN_CTRL(pipe)                _PIPE(pipe, _MIPIA_LP_GEN_CTRL, _MIPIB_LP_GEN_CTRL)
+ #define _MIPIA_HS_GEN_CTRL                    (VLV_DISPLAY_BASE + 0xb070)
+ #define _MIPIB_HS_GEN_CTRL                    (VLV_DISPLAY_BASE + 0xb870)
+ #define MIPI_HS_GEN_CTRL(pipe)                _PIPE(pipe, _MIPIA_HS_GEN_CTRL, _MIPIB_HS_GEN_CTRL)
+ #define  LONG_PACKET_WORD_COUNT_SHIFT                 8
+ #define  LONG_PACKET_WORD_COUNT_MASK                  (0xffff << 8)
+ #define  SHORT_PACKET_PARAM_SHIFT                     8
+ #define  SHORT_PACKET_PARAM_MASK                      (0xffff << 8)
+ #define  VIRTUAL_CHANNEL_SHIFT                                6
+ #define  VIRTUAL_CHANNEL_MASK                         (3 << 6)
+ #define  DATA_TYPE_SHIFT                              0
+ #define  DATA_TYPE_MASK                                       (3f << 0)
+ /* data type values, see include/video/mipi_display.h */
+ #define _MIPIA_GEN_FIFO_STAT                  (VLV_DISPLAY_BASE + 0xb074)
+ #define _MIPIB_GEN_FIFO_STAT                  (VLV_DISPLAY_BASE + 0xb874)
+ #define MIPI_GEN_FIFO_STAT(pipe)      _PIPE(pipe, _MIPIA_GEN_FIFO_STAT, _MIPIB_GEN_FIFO_STAT)
+ #define  DPI_FIFO_EMPTY                                       (1 << 28)
+ #define  DBI_FIFO_EMPTY                                       (1 << 27)
+ #define  LP_CTRL_FIFO_EMPTY                           (1 << 26)
+ #define  LP_CTRL_FIFO_HALF_EMPTY                      (1 << 25)
+ #define  LP_CTRL_FIFO_FULL                            (1 << 24)
+ #define  HS_CTRL_FIFO_EMPTY                           (1 << 18)
+ #define  HS_CTRL_FIFO_HALF_EMPTY                      (1 << 17)
+ #define  HS_CTRL_FIFO_FULL                            (1 << 16)
+ #define  LP_DATA_FIFO_EMPTY                           (1 << 10)
+ #define  LP_DATA_FIFO_HALF_EMPTY                      (1 << 9)
+ #define  LP_DATA_FIFO_FULL                            (1 << 8)
+ #define  HS_DATA_FIFO_EMPTY                           (1 << 2)
+ #define  HS_DATA_FIFO_HALF_EMPTY                      (1 << 1)
+ #define  HS_DATA_FIFO_FULL                            (1 << 0)
+ #define _MIPIA_HS_LS_DBI_ENABLE                       (VLV_DISPLAY_BASE + 0xb078)
+ #define _MIPIB_HS_LS_DBI_ENABLE                       (VLV_DISPLAY_BASE + 0xb878)
+ #define MIPI_HS_LP_DBI_ENABLE(pipe)   _PIPE(pipe, _MIPIA_HS_LS_DBI_ENABLE, _MIPIB_HS_LS_DBI_ENABLE)
+ #define  DBI_HS_LP_MODE_MASK                          (1 << 0)
+ #define  DBI_LP_MODE                                  (1 << 0)
+ #define  DBI_HS_MODE                                  (0 << 0)
+ #define _MIPIA_DPHY_PARAM                     (VLV_DISPLAY_BASE + 0xb080)
+ #define _MIPIB_DPHY_PARAM                     (VLV_DISPLAY_BASE + 0xb880)
+ #define MIPI_DPHY_PARAM(pipe)         _PIPE(pipe, _MIPIA_DPHY_PARAM, _MIPIB_DPHY_PARAM)
+ #define  EXIT_ZERO_COUNT_SHIFT                                24
+ #define  EXIT_ZERO_COUNT_MASK                         (0x3f << 24)
+ #define  TRAIL_COUNT_SHIFT                            16
+ #define  TRAIL_COUNT_MASK                             (0x1f << 16)
+ #define  CLK_ZERO_COUNT_SHIFT                         8
+ #define  CLK_ZERO_COUNT_MASK                          (0xff << 8)
+ #define  PREPARE_COUNT_SHIFT                          0
+ #define  PREPARE_COUNT_MASK                           (0x3f << 0)
+ /* bits 31:0 */
+ #define _MIPIA_DBI_BW_CTRL                    (VLV_DISPLAY_BASE + 0xb084)
+ #define _MIPIB_DBI_BW_CTRL                    (VLV_DISPLAY_BASE + 0xb884)
+ #define MIPI_DBI_BW_CTRL(pipe)                _PIPE(pipe, _MIPIA_DBI_BW_CTRL, _MIPIB_DBI_BW_CTRL)
+ #define _MIPIA_CLK_LANE_SWITCH_TIME_CNT               (VLV_DISPLAY_BASE + 0xb088)
+ #define _MIPIB_CLK_LANE_SWITCH_TIME_CNT               (VLV_DISPLAY_BASE + 0xb888)
+ #define MIPI_CLK_LANE_SWITCH_TIME_CNT(pipe)   _PIPE(pipe, _MIPIA_CLK_LANE_SWITCH_TIME_CNT, _MIPIB_CLK_LANE_SWITCH_TIME_CNT)
+ #define  LP_HS_SSW_CNT_SHIFT                          16
+ #define  LP_HS_SSW_CNT_MASK                           (0xffff << 16)
+ #define  HS_LP_PWR_SW_CNT_SHIFT                               0
+ #define  HS_LP_PWR_SW_CNT_MASK                                (0xffff << 0)
+ #define _MIPIA_STOP_STATE_STALL                       (VLV_DISPLAY_BASE + 0xb08c)
+ #define _MIPIB_STOP_STATE_STALL                       (VLV_DISPLAY_BASE + 0xb88c)
+ #define MIPI_STOP_STATE_STALL(pipe)   _PIPE(pipe, _MIPIA_STOP_STATE_STALL, _MIPIB_STOP_STATE_STALL)
+ #define  STOP_STATE_STALL_COUNTER_SHIFT                       0
+ #define  STOP_STATE_STALL_COUNTER_MASK                        (0xff << 0)
+ #define _MIPIA_INTR_STAT_REG_1                        (VLV_DISPLAY_BASE + 0xb090)
+ #define _MIPIB_INTR_STAT_REG_1                        (VLV_DISPLAY_BASE + 0xb890)
+ #define MIPI_INTR_STAT_REG_1(pipe)    _PIPE(pipe, _MIPIA_INTR_STAT_REG_1, _MIPIB_INTR_STAT_REG_1)
+ #define _MIPIA_INTR_EN_REG_1                  (VLV_DISPLAY_BASE + 0xb094)
+ #define _MIPIB_INTR_EN_REG_1                  (VLV_DISPLAY_BASE + 0xb894)
+ #define MIPI_INTR_EN_REG_1(pipe)      _PIPE(pipe, _MIPIA_INTR_EN_REG_1, _MIPIB_INTR_EN_REG_1)
+ #define  RX_CONTENTION_DETECTED                               (1 << 0)
+ /* XXX: only pipe A ?!? */
+ #define MIPIA_DBI_TYPEC_CTRL                  (VLV_DISPLAY_BASE + 0xb100)
+ #define  DBI_TYPEC_ENABLE                             (1 << 31)
+ #define  DBI_TYPEC_WIP                                        (1 << 30)
+ #define  DBI_TYPEC_OPTION_SHIFT                               28
+ #define  DBI_TYPEC_OPTION_MASK                                (3 << 28)
+ #define  DBI_TYPEC_FREQ_SHIFT                         24
+ #define  DBI_TYPEC_FREQ_MASK                          (0xf << 24)
+ #define  DBI_TYPEC_OVERRIDE                           (1 << 8)
+ #define  DBI_TYPEC_OVERRIDE_COUNTER_SHIFT             0
+ #define  DBI_TYPEC_OVERRIDE_COUNTER_MASK              (0xff << 0)
+ /* MIPI adapter registers */
+ #define _MIPIA_CTRL                           (VLV_DISPLAY_BASE + 0xb104)
+ #define _MIPIB_CTRL                           (VLV_DISPLAY_BASE + 0xb904)
+ #define MIPI_CTRL(pipe)                       _PIPE(pipe, _MIPIA_CTRL, _MIPIB_CTRL)
+ #define  ESCAPE_CLOCK_DIVIDER_SHIFT                   5 /* A only */
+ #define  ESCAPE_CLOCK_DIVIDER_MASK                    (3 << 5)
+ #define  ESCAPE_CLOCK_DIVIDER_1                               (0 << 5)
+ #define  ESCAPE_CLOCK_DIVIDER_2                               (1 << 5)
+ #define  ESCAPE_CLOCK_DIVIDER_4                               (2 << 5)
+ #define  READ_REQUEST_PRIORITY_SHIFT                  3
+ #define  READ_REQUEST_PRIORITY_MASK                   (3 << 3)
+ #define  READ_REQUEST_PRIORITY_LOW                    (0 << 3)
+ #define  READ_REQUEST_PRIORITY_HIGH                   (3 << 3)
+ #define  RGB_FLIP_TO_BGR                              (1 << 2)
+ #define _MIPIA_DATA_ADDRESS                   (VLV_DISPLAY_BASE + 0xb108)
+ #define _MIPIB_DATA_ADDRESS                   (VLV_DISPLAY_BASE + 0xb908)
+ #define MIPI_DATA_ADDRESS(pipe)               _PIPE(pipe, _MIPIA_DATA_ADDRESS, _MIPIB_DATA_ADDRESS)
+ #define  DATA_MEM_ADDRESS_SHIFT                               5
+ #define  DATA_MEM_ADDRESS_MASK                                (0x7ffffff << 5)
+ #define  DATA_VALID                                   (1 << 0)
+ #define _MIPIA_DATA_LENGTH                    (VLV_DISPLAY_BASE + 0xb10c)
+ #define _MIPIB_DATA_LENGTH                    (VLV_DISPLAY_BASE + 0xb90c)
+ #define MIPI_DATA_LENGTH(pipe)                _PIPE(pipe, _MIPIA_DATA_LENGTH, _MIPIB_DATA_LENGTH)
+ #define  DATA_LENGTH_SHIFT                            0
+ #define  DATA_LENGTH_MASK                             (0xfffff << 0)
+ #define _MIPIA_COMMAND_ADDRESS                        (VLV_DISPLAY_BASE + 0xb110)
+ #define _MIPIB_COMMAND_ADDRESS                        (VLV_DISPLAY_BASE + 0xb910)
+ #define MIPI_COMMAND_ADDRESS(pipe)    _PIPE(pipe, _MIPIA_COMMAND_ADDRESS, _MIPIB_COMMAND_ADDRESS)
+ #define  COMMAND_MEM_ADDRESS_SHIFT                    5
+ #define  COMMAND_MEM_ADDRESS_MASK                     (0x7ffffff << 5)
+ #define  AUTO_PWG_ENABLE                              (1 << 2)
+ #define  MEMORY_WRITE_DATA_FROM_PIPE_RENDERING                (1 << 1)
+ #define  COMMAND_VALID                                        (1 << 0)
+ #define _MIPIA_COMMAND_LENGTH                 (VLV_DISPLAY_BASE + 0xb114)
+ #define _MIPIB_COMMAND_LENGTH                 (VLV_DISPLAY_BASE + 0xb914)
+ #define MIPI_COMMAND_LENGTH(pipe)     _PIPE(pipe, _MIPIA_COMMAND_LENGTH, _MIPIB_COMMAND_LENGTH)
+ #define  COMMAND_LENGTH_SHIFT(n)                      (8 * (n)) /* n: 0...3 */
+ #define  COMMAND_LENGTH_MASK(n)                               (0xff << (8 * (n)))
+ #define _MIPIA_READ_DATA_RETURN0              (VLV_DISPLAY_BASE + 0xb118)
+ #define _MIPIB_READ_DATA_RETURN0              (VLV_DISPLAY_BASE + 0xb918)
+ #define MIPI_READ_DATA_RETURN(pipe, n) \
+       (_PIPE(pipe, _MIPIA_READ_DATA_RETURN0, _MIPIB_READ_DATA_RETURN0) + 4 * (n)) /* n: 0...7 */
+ #define _MIPIA_READ_DATA_VALID                        (VLV_DISPLAY_BASE + 0xb138)
+ #define _MIPIB_READ_DATA_VALID                        (VLV_DISPLAY_BASE + 0xb938)
+ #define MIPI_READ_DATA_VALID(pipe)    _PIPE(pipe, _MIPIA_READ_DATA_VALID, _MIPIB_READ_DATA_VALID)
+ #define  READ_DATA_VALID(n)                           (1 << (n))
  #endif /* _I915_REG_H_ */
index 725f0bea1e4c9647a43cbb04acb08ec750a4a75a,617b963dfb67f230bbabdaf8a66f613592bacd88..f674267d24dfcecc15602f3d04b97138106908c0
  #include <drm/drm_crtc_helper.h>
  #include <linux/dma_remapping.h>
  
- bool intel_pipe_has_type(struct drm_crtc *crtc, int type);
  static void intel_increase_pllclock(struct drm_crtc *crtc);
  static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on);
  
  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
                                struct intel_crtc_config *pipe_config);
- static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
-                                   struct intel_crtc_config *pipe_config);
+ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
+                                  struct intel_crtc_config *pipe_config);
  
  static int intel_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
                          int x, int y, struct drm_framebuffer *old_fb);
@@@ -69,9 -68,6 +68,6 @@@ struct intel_limit 
        intel_p2_t          p2;
  };
  
- /* FDI */
- #define IRONLAKE_FDI_FREQ             2700000 /* in kHz for mode->clock */
  int
  intel_pch_rawclk(struct drm_device *dev)
  {
@@@ -339,18 -335,20 +335,20 @@@ static const intel_limit_t intel_limits
                .p2_slow = 2, .p2_fast = 20 },
  };
  
- static const intel_limit_t intel_limits_vlv_dp = {
-       .dot = { .min = 25000, .max = 270000 },
-       .vco = { .min = 4000000, .max = 6000000 },
-       .n = { .min = 1, .max = 7 },
-       .m = { .min = 22, .max = 450 },
-       .m1 = { .min = 2, .max = 3 },
-       .m2 = { .min = 11, .max = 156 },
-       .p = { .min = 10, .max = 30 },
-       .p1 = { .min = 1, .max = 3 },
-       .p2 = { .dot_limit = 270000,
-               .p2_slow = 2, .p2_fast = 20 },
- };
+ /**
+  * Returns whether any output on the specified pipe is of the specified type
+  */
+ static bool intel_pipe_has_type(struct drm_crtc *crtc, int type)
+ {
+       struct drm_device *dev = crtc->dev;
+       struct intel_encoder *encoder;
+       for_each_encoder_on_crtc(dev, crtc, encoder)
+               if (encoder->type == type)
+                       return true;
+       return false;
+ }
  
  static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
                                                int refclk)
@@@ -414,10 -412,8 +412,8 @@@ static const intel_limit_t *intel_limit
        } else if (IS_VALLEYVIEW(dev)) {
                if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG))
                        limit = &intel_limits_vlv_dac;
-               else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI))
-                       limit = &intel_limits_vlv_hdmi;
                else
-                       limit = &intel_limits_vlv_dp;
+                       limit = &intel_limits_vlv_hdmi;
        } else if (!IS_GEN2(dev)) {
                if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
                        limit = &intel_limits_i9xx_lvds;
@@@ -456,21 -452,6 +452,6 @@@ static void i9xx_clock(int refclk, inte
        clock->dot = clock->vco / clock->p;
  }
  
- /**
-  * Returns whether any output on the specified pipe is of the specified type
-  */
- bool intel_pipe_has_type(struct drm_crtc *crtc, int type)
- {
-       struct drm_device *dev = crtc->dev;
-       struct intel_encoder *encoder;
-       for_each_encoder_on_crtc(dev, crtc, encoder)
-               if (encoder->type == type)
-                       return true;
-       return false;
- }
  #define INTELPllInvalid(s)   do { /* DRM_DEBUG(s); */ return false; } while (0)
  /**
   * Returns whether the given set of divisors are valid for a given refclk with
@@@ -714,29 -695,30 +695,30 @@@ vlv_find_best_dpll(const intel_limit_t 
                                p = p1 * p2;
                                /* based on hardware requirement, prefer bigger m1,m2 values */
                                for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) {
-                                       m2 = (((2*(fastclk * p * n / m1 )) +
-                                              refclk) / (2*refclk));
+                                       m2 = DIV_ROUND_CLOSEST(fastclk * p * n, refclk * m1);
                                        m = m1 * m2;
                                        vco = updrate * m;
-                                       if (vco >= limit->vco.min && vco < limit->vco.max) {
-                                               ppm = 1000000 * ((vco / p) - fastclk) / fastclk;
-                                               absppm = (ppm > 0) ? ppm : (-ppm);
-                                               if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) {
-                                                       bestppm = 0;
-                                                       flag = 1;
-                                               }
-                                               if (absppm < bestppm - 10) {
-                                                       bestppm = absppm;
-                                                       flag = 1;
-                                               }
-                                               if (flag) {
-                                                       bestn = n;
-                                                       bestm1 = m1;
-                                                       bestm2 = m2;
-                                                       bestp1 = p1;
-                                                       bestp2 = p2;
-                                                       flag = 0;
-                                               }
+                                       if (vco < limit->vco.min || vco >= limit->vco.max)
+                                               continue;
+                                       ppm = 1000000 * ((vco / p) - fastclk) / fastclk;
+                                       absppm = (ppm > 0) ? ppm : (-ppm);
+                                       if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) {
+                                               bestppm = 0;
+                                               flag = 1;
+                                       }
+                                       if (absppm < bestppm - 10) {
+                                               bestppm = absppm;
+                                               flag = 1;
+                                       }
+                                       if (flag) {
+                                               bestn = n;
+                                               bestm1 = m1;
+                                               bestm2 = m2;
+                                               bestp1 = p1;
+                                               bestp2 = p2;
+                                               flag = 0;
                                        }
                                }
                        }
        return true;
  }
  
+ bool intel_crtc_active(struct drm_crtc *crtc)
+ {
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       /* Be paranoid as we can arrive here with only partial
+        * state retrieved from the hardware during setup.
+        *
+        * We can ditch the adjusted_mode.crtc_clock check as soon
+        * as Haswell has gained clock readout/fastboot support.
+        *
+        * We can ditch the crtc->fb check as soon as we can
+        * properly reconstruct framebuffers.
+        */
+       return intel_crtc->active && crtc->fb &&
+               intel_crtc->config.adjusted_mode.crtc_clock;
+ }
  enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv,
                                             enum pipe pipe)
  {
@@@ -929,6 -928,24 +928,24 @@@ void assert_pll(struct drm_i915_privat
             state_string(state), state_string(cur_state));
  }
  
+ /* XXX: the dsi pll is shared between MIPI DSI ports */
+ static void assert_dsi_pll(struct drm_i915_private *dev_priv, bool state)
+ {
+       u32 val;
+       bool cur_state;
+       mutex_lock(&dev_priv->dpio_lock);
+       val = vlv_cck_read(dev_priv, CCK_REG_DSI_PLL_CONTROL);
+       mutex_unlock(&dev_priv->dpio_lock);
+       cur_state = val & DSI_PLL_VCO_EN;
+       WARN(cur_state != state,
+            "DSI PLL state assertion failure (expected %s, current %s)\n",
+            state_string(state), state_string(cur_state));
+ }
+ #define assert_dsi_pll_enabled(d) assert_dsi_pll(d, true)
+ #define assert_dsi_pll_disabled(d) assert_dsi_pll(d, false)
  struct intel_shared_dpll *
  intel_crtc_to_shared_dpll(struct intel_crtc *crtc)
  {
@@@ -1069,6 -1086,26 +1086,26 @@@ static void assert_panel_unlocked(struc
             pipe_name(pipe));
  }
  
+ static void assert_cursor(struct drm_i915_private *dev_priv,
+                         enum pipe pipe, bool state)
+ {
+       struct drm_device *dev = dev_priv->dev;
+       bool cur_state;
+       if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
+               cur_state = I915_READ(CURCNTR_IVB(pipe)) & CURSOR_MODE;
+       else if (IS_845G(dev) || IS_I865G(dev))
+               cur_state = I915_READ(_CURACNTR) & CURSOR_ENABLE;
+       else
+               cur_state = I915_READ(CURCNTR(pipe)) & CURSOR_MODE;
+       WARN(cur_state != state,
+            "cursor on pipe %c assertion failure (expected %s, current %s)\n",
+            pipe_name(pipe), state_string(state), state_string(cur_state));
+ }
+ #define assert_cursor_enabled(d, p) assert_cursor(d, p, true)
+ #define assert_cursor_disabled(d, p) assert_cursor(d, p, false)
  void assert_pipe(struct drm_i915_private *dev_priv,
                 enum pipe pipe, bool state)
  {
@@@ -1323,6 -1360,26 +1360,26 @@@ static void assert_pch_ports_disabled(s
        assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
  }
  
+ static void intel_init_dpio(struct drm_device *dev)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       if (!IS_VALLEYVIEW(dev))
+               return;
+       /*
+        * From VLV2A0_DP_eDP_DPIO_driver_vbios_notes_10.docx -
+        *  6.  De-assert cmn_reset/side_reset. Same as VLV X0.
+        *   a. GUnit 0x2110 bit[0] set to 1 (def 0)
+        *   b. The other bits such as sfr settings / modesel may all be set
+        *      to 0.
+        *
+        * This should only be done on init and resume from S3 with both
+        * PLLs disabled, or we risk losing DPIO and PLL synchronization.
+        */
+       I915_WRITE(DPIO_CTL, I915_READ(DPIO_CTL) | DPIO_CMNRST);
+ }
  static void vlv_enable_pll(struct intel_crtc *crtc)
  {
        struct drm_device *dev = crtc->base.dev;
@@@ -1429,6 -1486,20 +1486,20 @@@ static void i9xx_disable_pll(struct drm
        POSTING_READ(DPLL(pipe));
  }
  
+ static void vlv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
+ {
+       u32 val = 0;
+       /* Make sure the pipe isn't still relying on us */
+       assert_pipe_disabled(dev_priv, pipe);
+       /* Leave integrated clock source enabled */
+       if (pipe == PIPE_B)
+               val = DPLL_INTEGRATED_CRI_CLK_VLV;
+       I915_WRITE(DPLL(pipe), val);
+       POSTING_READ(DPLL(pipe));
+ }
  void vlv_wait_port_ready(struct drm_i915_private *dev_priv, int port)
  {
        u32 port_mask;
@@@ -1661,7 -1732,7 +1732,7 @@@ static void lpt_disable_pch_transcoder(
   * returning.
   */
  static void intel_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe,
-                             bool pch_port)
+                             bool pch_port, bool dsi)
  {
        enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
                                                                      pipe);
        u32 val;
  
        assert_planes_disabled(dev_priv, pipe);
+       assert_cursor_disabled(dev_priv, pipe);
        assert_sprites_disabled(dev_priv, pipe);
  
        if (HAS_PCH_LPT(dev_priv->dev))
         * need the check.
         */
        if (!HAS_PCH_SPLIT(dev_priv->dev))
-               assert_pll_enabled(dev_priv, pipe);
+               if (dsi)
+                       assert_dsi_pll_enabled(dev_priv);
+               else
+                       assert_pll_enabled(dev_priv, pipe);
        else {
                if (pch_port) {
                        /* if driving the PCH, we need FDI enabled */
@@@ -1728,6 -1803,7 +1803,7 @@@ static void intel_disable_pipe(struct d
         * or we might hang the display.
         */
        assert_planes_disabled(dev_priv, pipe);
+       assert_cursor_disabled(dev_priv, pipe);
        assert_sprites_disabled(dev_priv, pipe);
  
        /* Don't disable pipe A or pipe A PLLs if needed */
@@@ -2244,11 -2320,26 +2320,26 @@@ intel_pipe_set_base(struct drm_crtc *cr
                return ret;
        }
  
-       /* Update pipe size and adjust fitter if needed */
+       /*
+        * Update pipe size and adjust fitter if needed: the reason for this is
+        * that in compute_mode_changes we check the native mode (not the pfit
+        * mode) to see if we can flip rather than do a full mode set. In the
+        * fastboot case, we'll flip, but if we don't update the pipesrc and
+        * pfit state, we'll end up with a big fb scanned out into the wrong
+        * sized surface.
+        *
+        * To fix this properly, we need to hoist the checks up into
+        * compute_mode_changes (or above), check the actual pfit state and
+        * whether the platform allows pfit disable with pipe active, and only
+        * then update the pipesrc and pfit state, even on the flip path.
+        */
        if (i915_fastboot) {
+               const struct drm_display_mode *adjusted_mode =
+                       &intel_crtc->config.adjusted_mode;
                I915_WRITE(PIPESRC(intel_crtc->pipe),
-                          ((crtc->mode.hdisplay - 1) << 16) |
-                          (crtc->mode.vdisplay - 1));
+                          ((adjusted_mode->crtc_hdisplay - 1) << 16) |
+                          (adjusted_mode->crtc_vdisplay - 1));
                if (!intel_crtc->config.pch_pfit.enabled &&
                    (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) ||
                     intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))) {
@@@ -2872,6 -2963,7 +2963,7 @@@ static void lpt_program_iclkip(struct d
  {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
        u32 divsel, phaseinc, auxdiv, phasedir = 0;
        u32 temp;
  
                        SBI_ICLK);
  
        /* 20MHz is a corner case which is out of range for the 7-bit divisor */
-       if (crtc->mode.clock == 20000) {
+       if (clock == 20000) {
                auxdiv = 1;
                divsel = 0x41;
                phaseinc = 0x20;
        } else {
                /* The iCLK virtual clock root frequency is in MHz,
-                * but the crtc->mode.clock in in KHz. To get the divisors,
-                * it is necessary to divide one by another, so we
+                * but the adjusted_mode->crtc_clock in in KHz. To get the
+                * divisors, it is necessary to divide one by another, so we
                 * convert the virtual clock precision to KHz here for higher
                 * precision.
                 */
                u32 iclk_pi_range = 64;
                u32 desired_divisor, msb_divisor_value, pi_value;
  
-               desired_divisor = (iclk_virtual_root_freq / crtc->mode.clock);
+               desired_divisor = (iclk_virtual_root_freq / clock);
                msb_divisor_value = desired_divisor / iclk_pi_range;
                pi_value = desired_divisor % iclk_pi_range;
  
                ~SBI_SSCDIVINTPHASE_INCVAL_MASK);
  
        DRM_DEBUG_KMS("iCLKIP clock: found settings for %dKHz refresh rate: auxdiv=%x, divsel=%x, phasedir=%x, phaseinc=%x\n",
-                       crtc->mode.clock,
+                       clock,
                        auxdiv,
                        divsel,
                        phasedir,
@@@ -3240,6 -3332,84 +3332,84 @@@ static void intel_disable_planes(struc
                        intel_plane_disable(&intel_plane->base);
  }
  
+ static void hsw_enable_ips(struct intel_crtc *crtc)
+ {
+       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+       if (!crtc->config.ips_enabled)
+               return;
+       /* We can only enable IPS after we enable a plane and wait for a vblank.
+        * We guarantee that the plane is enabled by calling intel_enable_ips
+        * only after intel_enable_plane. And intel_enable_plane already waits
+        * for a vblank, so all we need to do here is to enable the IPS bit. */
+       assert_plane_enabled(dev_priv, crtc->plane);
+       I915_WRITE(IPS_CTL, IPS_ENABLE);
+ }
+ static void hsw_disable_ips(struct intel_crtc *crtc)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       if (!crtc->config.ips_enabled)
+               return;
+       assert_plane_enabled(dev_priv, crtc->plane);
+       I915_WRITE(IPS_CTL, 0);
+       POSTING_READ(IPS_CTL);
+       /* We need to wait for a vblank before we can disable the plane. */
+       intel_wait_for_vblank(dev, crtc->pipe);
+ }
+ /** Loads the palette/gamma unit for the CRTC with the prepared values */
+ static void intel_crtc_load_lut(struct drm_crtc *crtc)
+ {
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       enum pipe pipe = intel_crtc->pipe;
+       int palreg = PALETTE(pipe);
+       int i;
+       bool reenable_ips = false;
+       /* The clocks have to be on to load the palette. */
+       if (!crtc->enabled || !intel_crtc->active)
+               return;
+       if (!HAS_PCH_SPLIT(dev_priv->dev)) {
+               if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI))
+                       assert_dsi_pll_enabled(dev_priv);
+               else
+                       assert_pll_enabled(dev_priv, pipe);
+       }
+       /* use legacy palette for Ironlake */
+       if (HAS_PCH_SPLIT(dev))
+               palreg = LGC_PALETTE(pipe);
+       /* Workaround : Do not read or write the pipe palette/gamma data while
+        * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
+        */
+       if (intel_crtc->config.ips_enabled &&
+           ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
+            GAMMA_MODE_MODE_SPLIT)) {
+               hsw_disable_ips(intel_crtc);
+               reenable_ips = true;
+       }
+       for (i = 0; i < 256; i++) {
+               I915_WRITE(palreg + 4 * i,
+                          (intel_crtc->lut_r[i] << 16) |
+                          (intel_crtc->lut_g[i] << 8) |
+                          intel_crtc->lut_b[i]);
+       }
+       if (reenable_ips)
+               hsw_enable_ips(intel_crtc);
+ }
  static void ironlake_crtc_enable(struct drm_crtc *crtc)
  {
        struct drm_device *dev = crtc->dev;
        intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
        intel_set_pch_fifo_underrun_reporting(dev, pipe, true);
  
-       intel_update_watermarks(dev);
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->pre_enable)
                        encoder->pre_enable(encoder);
         */
        intel_crtc_load_lut(crtc);
  
+       intel_update_watermarks(crtc);
        intel_enable_pipe(dev_priv, pipe,
-                         intel_crtc->config.has_pch_encoder);
+                         intel_crtc->config.has_pch_encoder, false);
        intel_enable_plane(dev_priv, plane, pipe);
        intel_enable_planes(crtc);
        intel_crtc_update_cursor(crtc, true);
@@@ -3319,34 -3488,74 +3488,74 @@@ static bool hsw_crtc_supports_ips(struc
        return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A;
  }
  
- static void hsw_enable_ips(struct intel_crtc *crtc)
+ static void haswell_crtc_enable_planes(struct drm_crtc *crtc)
  {
-       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+       struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int pipe = intel_crtc->pipe;
+       int plane = intel_crtc->plane;
  
-       if (!crtc->config.ips_enabled)
-               return;
+       intel_enable_plane(dev_priv, plane, pipe);
+       intel_enable_planes(crtc);
+       intel_crtc_update_cursor(crtc, true);
  
-       /* We can only enable IPS after we enable a plane and wait for a vblank.
-        * We guarantee that the plane is enabled by calling intel_enable_ips
-        * only after intel_enable_plane. And intel_enable_plane already waits
-        * for a vblank, so all we need to do here is to enable the IPS bit. */
-       assert_plane_enabled(dev_priv, crtc->plane);
-       I915_WRITE(IPS_CTL, IPS_ENABLE);
+       hsw_enable_ips(intel_crtc);
+       mutex_lock(&dev->struct_mutex);
+       intel_update_fbc(dev);
+       mutex_unlock(&dev->struct_mutex);
  }
  
- static void hsw_disable_ips(struct intel_crtc *crtc)
+ static void haswell_crtc_disable_planes(struct drm_crtc *crtc)
  {
-       struct drm_device *dev = crtc->base.dev;
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       int pipe = intel_crtc->pipe;
+       int plane = intel_crtc->plane;
  
-       if (!crtc->config.ips_enabled)
-               return;
+       intel_crtc_wait_for_pending_flips(crtc);
+       drm_vblank_off(dev, pipe);
  
-       assert_plane_enabled(dev_priv, crtc->plane);
-       I915_WRITE(IPS_CTL, 0);
+       /* FBC must be disabled before disabling the plane on HSW. */
+       if (dev_priv->fbc.plane == plane)
+               intel_disable_fbc(dev);
  
-       /* We need to wait for a vblank before we can disable the plane. */
-       intel_wait_for_vblank(dev, crtc->pipe);
+       hsw_disable_ips(intel_crtc);
+       intel_crtc_update_cursor(crtc, false);
+       intel_disable_planes(crtc);
+       intel_disable_plane(dev_priv, plane, pipe);
+ }
+ /*
+  * This implements the workaround described in the "notes" section of the mode
+  * set sequence documentation. When going from no pipes or single pipe to
+  * multiple pipes, and planes are enabled after the pipe, we need to wait at
+  * least 2 vblanks on the first pipe before enabling planes on the second pipe.
+  */
+ static void haswell_mode_set_planes_workaround(struct intel_crtc *crtc)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct intel_crtc *crtc_it, *other_active_crtc = NULL;
+       /* We want to get the other_active_crtc only if there's only 1 other
+        * active crtc. */
+       list_for_each_entry(crtc_it, &dev->mode_config.crtc_list, base.head) {
+               if (!crtc_it->active || crtc_it == crtc)
+                       continue;
+               if (other_active_crtc)
+                       return;
+               other_active_crtc = crtc_it;
+       }
+       if (!other_active_crtc)
+               return;
+       intel_wait_for_vblank(dev, other_active_crtc->pipe);
+       intel_wait_for_vblank(dev, other_active_crtc->pipe);
  }
  
  static void haswell_crtc_enable(struct drm_crtc *crtc)
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
-       int plane = intel_crtc->plane;
  
        WARN_ON(!crtc->enabled);
  
        if (intel_crtc->config.has_pch_encoder)
                intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, true);
  
-       intel_update_watermarks(dev);
        if (intel_crtc->config.has_pch_encoder)
                dev_priv->display.fdi_link_train(crtc);
  
        intel_ddi_set_pipe_settings(crtc);
        intel_ddi_enable_transcoder_func(crtc);
  
+       intel_update_watermarks(crtc);
        intel_enable_pipe(dev_priv, pipe,
-                         intel_crtc->config.has_pch_encoder);
-       intel_enable_plane(dev_priv, plane, pipe);
-       intel_enable_planes(crtc);
-       intel_crtc_update_cursor(crtc, true);
-       hsw_enable_ips(intel_crtc);
+                         intel_crtc->config.has_pch_encoder, false);
  
        if (intel_crtc->config.has_pch_encoder)
                lpt_pch_enable(crtc);
  
-       mutex_lock(&dev->struct_mutex);
-       intel_update_fbc(dev);
-       mutex_unlock(&dev->struct_mutex);
-       for_each_encoder_on_crtc(dev, crtc, encoder)
+       for_each_encoder_on_crtc(dev, crtc, encoder) {
                encoder->enable(encoder);
+               intel_opregion_notify_encoder(encoder, true);
+       }
+       /* If we change the relative order between pipe/planes enabling, we need
+        * to change the workaround. */
+       haswell_mode_set_planes_workaround(intel_crtc);
+       haswell_crtc_enable_planes(crtc);
  
        /*
         * There seems to be a race in PCH platform hw (at least on some
@@@ -3501,7 -3706,7 +3706,7 @@@ static void ironlake_crtc_disable(struc
        }
  
        intel_crtc->active = false;
-       intel_update_watermarks(dev);
+       intel_update_watermarks(crtc);
  
        mutex_lock(&dev->struct_mutex);
        intel_update_fbc(dev);
@@@ -3515,27 -3720,17 +3720,17 @@@ static void haswell_crtc_disable(struc
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
-       int plane = intel_crtc->plane;
        enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
  
        if (!intel_crtc->active)
                return;
  
-       for_each_encoder_on_crtc(dev, crtc, encoder)
-               encoder->disable(encoder);
-       intel_crtc_wait_for_pending_flips(crtc);
-       drm_vblank_off(dev, pipe);
-       /* FBC must be disabled before disabling the plane on HSW. */
-       if (dev_priv->fbc.plane == plane)
-               intel_disable_fbc(dev);
+       haswell_crtc_disable_planes(crtc);
  
-       hsw_disable_ips(intel_crtc);
-       intel_crtc_update_cursor(crtc, false);
-       intel_disable_planes(crtc);
-       intel_disable_plane(dev_priv, plane, pipe);
+       for_each_encoder_on_crtc(dev, crtc, encoder) {
+               intel_opregion_notify_encoder(encoder, false);
+               encoder->disable(encoder);
+       }
  
        if (intel_crtc->config.has_pch_encoder)
                intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false);
        }
  
        intel_crtc->active = false;
-       intel_update_watermarks(dev);
+       intel_update_watermarks(crtc);
  
        mutex_lock(&dev->struct_mutex);
        intel_update_fbc(dev);
@@@ -3650,6 -3845,7 +3845,7 @@@ static void valleyview_crtc_enable(stru
        struct intel_encoder *encoder;
        int pipe = intel_crtc->pipe;
        int plane = intel_crtc->plane;
+       bool is_dsi;
  
        WARN_ON(!crtc->enabled);
  
                return;
  
        intel_crtc->active = true;
-       intel_update_watermarks(dev);
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->pre_pll_enable)
                        encoder->pre_pll_enable(encoder);
  
-       vlv_enable_pll(intel_crtc);
+       is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI);
+       if (!is_dsi)
+               vlv_enable_pll(intel_crtc);
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->pre_enable)
  
        intel_crtc_load_lut(crtc);
  
-       intel_enable_pipe(dev_priv, pipe, false);
+       intel_update_watermarks(crtc);
+       intel_enable_pipe(dev_priv, pipe, false, is_dsi);
        intel_enable_plane(dev_priv, plane, pipe);
        intel_enable_planes(crtc);
        intel_crtc_update_cursor(crtc, true);
@@@ -3699,7 -3898,6 +3898,6 @@@ static void i9xx_crtc_enable(struct drm
                return;
  
        intel_crtc->active = true;
-       intel_update_watermarks(dev);
  
        for_each_encoder_on_crtc(dev, crtc, encoder)
                if (encoder->pre_enable)
  
        intel_crtc_load_lut(crtc);
  
-       intel_enable_pipe(dev_priv, pipe, false);
+       intel_update_watermarks(crtc);
+       intel_enable_pipe(dev_priv, pipe, false, false);
        intel_enable_plane(dev_priv, plane, pipe);
        intel_enable_planes(crtc);
        /* The fixup needs to happen before cursor is enabled */
@@@ -3778,11 -3977,15 +3977,15 @@@ static void i9xx_crtc_disable(struct dr
                if (encoder->post_disable)
                        encoder->post_disable(encoder);
  
-       i9xx_disable_pll(dev_priv, pipe);
+       if (IS_VALLEYVIEW(dev) && !intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI))
+               vlv_disable_pll(dev_priv, pipe);
+       else if (!IS_VALLEYVIEW(dev))
+               i9xx_disable_pll(dev_priv, pipe);
  
        intel_crtc->active = false;
+       intel_update_watermarks(crtc);
        intel_update_fbc(dev);
-       intel_update_watermarks(dev);
  }
  
  static void i9xx_crtc_off(struct drm_crtc *crtc)
@@@ -3856,6 -4059,7 +4059,7 @@@ static void intel_crtc_disable(struct d
        dev_priv->display.off(crtc);
  
        assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
+       assert_cursor_disabled(dev_priv, to_intel_crtc(crtc)->pipe);
        assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
  
        if (crtc->fb) {
@@@ -3941,6 -4145,8 +4145,6 @@@ static void intel_connector_check_state
   * consider. */
  void intel_connector_dpms(struct drm_connector *connector, int mode)
  {
 -      struct intel_encoder *encoder = intel_attached_encoder(connector);
 -
        /* All the simple cases only support two dpms states. */
        if (mode != DRM_MODE_DPMS_ON)
                mode = DRM_MODE_DPMS_OFF;
        connector->dpms = mode;
  
        /* Only need to change hw state when actually enabled */
 -      if (encoder->base.crtc)
 -              intel_encoder_dpms(encoder, mode);
 -      else
 -              WARN_ON(encoder->connectors_active != false);
 +      if (connector->encoder)
 +              intel_encoder_dpms(to_intel_encoder(connector->encoder), mode);
  
        intel_modeset_check_state(connector->dev);
  }
@@@ -4045,8 -4253,7 +4249,7 @@@ retry
         */
        link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
  
-       fdi_dotclock = adjusted_mode->clock;
-       fdi_dotclock /= pipe_config->pixel_multiplier;
+       fdi_dotclock = adjusted_mode->crtc_clock;
  
        lane = ironlake_get_lanes_required(fdi_dotclock, link_bw,
                                           pipe_config->pipe_bpp);
@@@ -4088,13 -4295,39 +4291,39 @@@ static int intel_crtc_compute_config(st
        struct drm_device *dev = crtc->base.dev;
        struct drm_display_mode *adjusted_mode = &pipe_config->adjusted_mode;
  
-       if (HAS_PCH_SPLIT(dev)) {
-               /* FDI link clock is fixed at 2.7G */
-               if (pipe_config->requested_mode.clock * 3
-                   > IRONLAKE_FDI_FREQ * 4)
+       /* FIXME should check pixel clock limits on all platforms */
+       if (INTEL_INFO(dev)->gen < 4) {
+               struct drm_i915_private *dev_priv = dev->dev_private;
+               int clock_limit =
+                       dev_priv->display.get_display_clock_speed(dev);
+               /*
+                * Enable pixel doubling when the dot clock
+                * is > 90% of the (display) core speed.
+                *
+                * GDG double wide on either pipe,
+                * otherwise pipe A only.
+                */
+               if ((crtc->pipe == PIPE_A || IS_I915G(dev)) &&
+                   adjusted_mode->crtc_clock > clock_limit * 9 / 10) {
+                       clock_limit *= 2;
+                       pipe_config->double_wide = true;
+               }
+               if (adjusted_mode->crtc_clock > clock_limit * 9 / 10)
                        return -EINVAL;
        }
  
+       /*
+        * Pipe horizontal size must be even in:
+        * - DVO ganged mode
+        * - LVDS dual channel mode
+        * - Double wide pipe
+        */
+       if ((intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_LVDS) &&
+            intel_is_dual_link_lvds(dev)) || pipe_config->double_wide)
+               pipe_config->pipe_src_w &= ~1;
        /* Cantiga+ cannot handle modes with a hsync front porch of 0.
         * WaPruneModeWithIncorrectHsyncOffset:ctg,elk,ilk,snb,ivb,vlv,hsw.
         */
@@@ -4258,28 -4491,6 +4487,6 @@@ static inline bool intel_panel_use_ssc(
                && !(dev_priv->quirks & QUIRK_LVDS_SSC_DISABLE);
  }
  
- static int vlv_get_refclk(struct drm_crtc *crtc)
- {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       int refclk = 27000; /* for DP & HDMI */
-       return 100000; /* only one validated so far */
-       if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) {
-               refclk = 96000;
-       } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
-               if (intel_panel_use_ssc(dev_priv))
-                       refclk = 100000;
-               else
-                       refclk = 96000;
-       } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) {
-               refclk = 100000;
-       }
-       return refclk;
- }
  static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors)
  {
        struct drm_device *dev = crtc->dev;
        int refclk;
  
        if (IS_VALLEYVIEW(dev)) {
-               refclk = vlv_get_refclk(crtc);
+               refclk = 100000;
        } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
            intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
                refclk = dev_priv->vbt.lvds_ssc_freq * 1000;
@@@ -4345,7 -4556,8 +4552,8 @@@ static void i9xx_update_pll_dividers(st
        }
  }
  
- static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv)
+ static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv, enum pipe
+               pipe)
  {
        u32 reg_val;
  
         * PLLB opamp always calibrates to max value of 0x3f, force enable it
         * and set it to a reasonable value instead.
         */
-       reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1));
+       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF(1));
        reg_val &= 0xffffff00;
        reg_val |= 0x00000030;
-       vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val);
+       vlv_dpio_write(dev_priv, pipe, DPIO_IREF(1), reg_val);
  
-       reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION);
+       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_CALIBRATION);
        reg_val &= 0x8cffffff;
        reg_val = 0x8c000000;
-       vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val);
+       vlv_dpio_write(dev_priv, pipe, DPIO_CALIBRATION, reg_val);
  
-       reg_val = vlv_dpio_read(dev_priv, DPIO_IREF(1));
+       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF(1));
        reg_val &= 0xffffff00;
-       vlv_dpio_write(dev_priv, DPIO_IREF(1), reg_val);
+       vlv_dpio_write(dev_priv, pipe, DPIO_IREF(1), reg_val);
  
-       reg_val = vlv_dpio_read(dev_priv, DPIO_CALIBRATION);
+       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_CALIBRATION);
        reg_val &= 0x00ffffff;
        reg_val |= 0xb0000000;
-       vlv_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val);
+       vlv_dpio_write(dev_priv, pipe, DPIO_CALIBRATION, reg_val);
  }
  
  static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc,
@@@ -4436,18 -4648,18 +4644,18 @@@ static void vlv_update_pll(struct intel
  
        /* PLL B needs special handling */
        if (pipe)
-               vlv_pllb_recal_opamp(dev_priv);
+               vlv_pllb_recal_opamp(dev_priv, pipe);
  
        /* Set up Tx target for periodic Rcomp update */
-       vlv_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f);
+       vlv_dpio_write(dev_priv, pipe, DPIO_IREF_BCAST, 0x0100000f);
  
        /* Disable target IRef on PLL */
-       reg_val = vlv_dpio_read(dev_priv, DPIO_IREF_CTL(pipe));
+       reg_val = vlv_dpio_read(dev_priv, pipe, DPIO_IREF_CTL(pipe));
        reg_val &= 0x00ffffff;
-       vlv_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val);
+       vlv_dpio_write(dev_priv, pipe, DPIO_IREF_CTL(pipe), reg_val);
  
        /* Disable fast lock */
-       vlv_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610);
+       vlv_dpio_write(dev_priv, pipe, DPIO_FASTCLK_DISABLE, 0x610);
  
        /* Set idtafcrecal before PLL is enabled */
        mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK));
         * Note: don't use the DAC post divider as it seems unstable.
         */
        mdiv |= (DPIO_POST_DIV_HDMIDP << DPIO_POST_DIV_SHIFT);
-       vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
+       vlv_dpio_write(dev_priv, pipe, DPIO_DIV(pipe), mdiv);
  
        mdiv |= DPIO_ENABLE_CALIBRATION;
-       vlv_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv);
+       vlv_dpio_write(dev_priv, pipe, DPIO_DIV(pipe), mdiv);
  
        /* Set HBR and RBR LPF coefficients */
        if (crtc->config.port_clock == 162000 ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_ANALOG) ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_HDMI))
-               vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
+               vlv_dpio_write(dev_priv, pipe, DPIO_LPF_COEFF(pipe),
                                 0x009f0003);
        else
-               vlv_dpio_write(dev_priv, DPIO_LPF_COEFF(pipe),
+               vlv_dpio_write(dev_priv, pipe, DPIO_LPF_COEFF(pipe),
                                 0x00d0000f);
  
        if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP) ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT)) {
                /* Use SSC source */
                if (!pipe)
-                       vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
                                         0x0df40000);
                else
-                       vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
                                         0x0df70000);
        } else { /* HDMI or VGA */
                /* Use bend source */
                if (!pipe)
-                       vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
                                         0x0df70000);
                else
-                       vlv_dpio_write(dev_priv, DPIO_REFSFR(pipe),
+                       vlv_dpio_write(dev_priv, pipe, DPIO_REFSFR(pipe),
                                         0x0df40000);
        }
  
-       coreclk = vlv_dpio_read(dev_priv, DPIO_CORE_CLK(pipe));
+       coreclk = vlv_dpio_read(dev_priv, pipe, DPIO_CORE_CLK(pipe));
        coreclk = (coreclk & 0x0000ff00) | 0x01c00000;
        if (intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_DISPLAYPORT) ||
            intel_pipe_has_type(&crtc->base, INTEL_OUTPUT_EDP))
                coreclk |= 0x01000000;
-       vlv_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk);
+       vlv_dpio_write(dev_priv, pipe, DPIO_CORE_CLK(pipe), coreclk);
  
-       vlv_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000);
+       vlv_dpio_write(dev_priv, pipe, DPIO_PLL_CML(pipe), 0x87871000);
  
        /* Enable DPIO clock input */
        dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV |
                DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV;
-       if (pipe)
+       /* We should never disable this, set it here for state tracking */
+       if (pipe == PIPE_B)
                dpll |= DPLL_INTEGRATED_CRI_CLK_VLV;
        dpll |= DPLL_VCO_ENABLE;
        crtc->config.dpll_hw_state.dpll = dpll;
  
@@@ -4647,7 -4859,6 +4855,6 @@@ static void intel_set_pipe_timings(stru
        enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
        struct drm_display_mode *adjusted_mode =
                &intel_crtc->config.adjusted_mode;
-       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
        uint32_t vsyncshift, crtc_vtotal, crtc_vblank_end;
  
        /* We need to be careful not to changed the adjusted mode, for otherwise
         * always be the user's requested size.
         */
        I915_WRITE(PIPESRC(pipe),
-                  ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
+                  ((intel_crtc->config.pipe_src_w - 1) << 16) |
+                  (intel_crtc->config.pipe_src_h - 1));
  }
  
  static void intel_get_pipe_timings(struct intel_crtc *crtc,
        }
  
        tmp = I915_READ(PIPESRC(crtc->pipe));
-       pipe_config->requested_mode.vdisplay = (tmp & 0xffff) + 1;
-       pipe_config->requested_mode.hdisplay = ((tmp >> 16) & 0xffff) + 1;
+       pipe_config->pipe_src_h = (tmp & 0xffff) + 1;
+       pipe_config->pipe_src_w = ((tmp >> 16) & 0xffff) + 1;
+       pipe_config->requested_mode.vdisplay = pipe_config->pipe_src_h;
+       pipe_config->requested_mode.hdisplay = pipe_config->pipe_src_w;
  }
  
  static void intel_crtc_mode_from_pipe_config(struct intel_crtc *intel_crtc,
  
        crtc->mode.flags = pipe_config->adjusted_mode.flags;
  
-       crtc->mode.clock = pipe_config->adjusted_mode.clock;
+       crtc->mode.clock = pipe_config->adjusted_mode.crtc_clock;
        crtc->mode.flags |= pipe_config->adjusted_mode.flags;
  }
  
@@@ -4775,17 -4990,8 +4986,8 @@@ static void i9xx_set_pipeconf(struct in
            I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE)
                pipeconf |= PIPECONF_ENABLE;
  
-       if (intel_crtc->pipe == 0 && INTEL_INFO(dev)->gen < 4) {
-               /* Enable pixel doubling when the dot clock is > 90% of the (display)
-                * core speed.
-                *
-                * XXX: No double-wide on 915GM pipe B. Is that the only reason for the
-                * pipe == 0 check?
-                */
-               if (intel_crtc->config.requested_mode.clock >
-                   dev_priv->display.get_display_clock_speed(dev) * 9 / 10)
-                       pipeconf |= PIPECONF_DOUBLE_WIDE;
-       }
+       if (intel_crtc->config.double_wide)
+               pipeconf |= PIPECONF_DOUBLE_WIDE;
  
        /* only g4x and later have fancy bpc/dither controls */
        if (IS_G4X(dev) || IS_VALLEYVIEW(dev)) {
@@@ -4839,14 -5045,13 +5041,13 @@@ static int i9xx_crtc_mode_set(struct dr
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct drm_display_mode *mode = &intel_crtc->config.requested_mode;
        int pipe = intel_crtc->pipe;
        int plane = intel_crtc->plane;
        int refclk, num_connectors = 0;
        intel_clock_t clock, reduced_clock;
        u32 dspcntr;
        bool ok, has_reduced_clock = false;
-       bool is_lvds = false;
+       bool is_lvds = false, is_dsi = false;
        struct intel_encoder *encoder;
        const intel_limit_t *limit;
        int ret;
                case INTEL_OUTPUT_LVDS:
                        is_lvds = true;
                        break;
+               case INTEL_OUTPUT_DSI:
+                       is_dsi = true;
+                       break;
                }
  
                num_connectors++;
        }
  
-       refclk = i9xx_get_refclk(crtc, num_connectors);
+       if (is_dsi)
+               goto skip_dpll;
  
-       /*
-        * Returns a set of divisors for the desired target clock with the given
-        * refclk, or FALSE.  The returned values represent the clock equation:
-        * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
-        */
-       limit = intel_limit(crtc, refclk);
-       ok = dev_priv->display.find_dpll(limit, crtc,
-                                        intel_crtc->config.port_clock,
-                                        refclk, NULL, &clock);
-       if (!ok && !intel_crtc->config.clock_set) {
-               DRM_ERROR("Couldn't find PLL settings for mode!\n");
-               return -EINVAL;
-       }
+       if (!intel_crtc->config.clock_set) {
+               refclk = i9xx_get_refclk(crtc, num_connectors);
  
-       if (is_lvds && dev_priv->lvds_downclock_avail) {
                /*
-                * Ensure we match the reduced clock's P to the target clock.
-                * If the clocks don't match, we can't switch the display clock
-                * by using the FP0/FP1. In such case we will disable the LVDS
-                * downclock feature.
-               */
-               has_reduced_clock =
-                       dev_priv->display.find_dpll(limit, crtc,
-                                                   dev_priv->lvds_downclock,
-                                                   refclk, &clock,
-                                                   &reduced_clock);
-       }
-       /* Compat-code for transition, will disappear. */
-       if (!intel_crtc->config.clock_set) {
+                * Returns a set of divisors for the desired target clock with
+                * the given refclk, or FALSE.  The returned values represent
+                * the clock equation: reflck * (5 * (m1 + 2) + (m2 + 2)) / (n +
+                * 2) / p1 / p2.
+                */
+               limit = intel_limit(crtc, refclk);
+               ok = dev_priv->display.find_dpll(limit, crtc,
+                                                intel_crtc->config.port_clock,
+                                                refclk, NULL, &clock);
+               if (!ok) {
+                       DRM_ERROR("Couldn't find PLL settings for mode!\n");
+                       return -EINVAL;
+               }
+               if (is_lvds && dev_priv->lvds_downclock_avail) {
+                       /*
+                        * Ensure we match the reduced clock's P to the target
+                        * clock.  If the clocks don't match, we can't switch
+                        * the display clock by using the FP0/FP1. In such case
+                        * we will disable the LVDS downclock feature.
+                        */
+                       has_reduced_clock =
+                               dev_priv->display.find_dpll(limit, crtc,
+                                                           dev_priv->lvds_downclock,
+                                                           refclk, &clock,
+                                                           &reduced_clock);
+               }
+               /* Compat-code for transition, will disappear. */
                intel_crtc->config.dpll.n = clock.n;
                intel_crtc->config.dpll.m1 = clock.m1;
                intel_crtc->config.dpll.m2 = clock.m2;
                intel_crtc->config.dpll.p2 = clock.p2;
        }
  
-       if (IS_GEN2(dev))
+       if (IS_GEN2(dev)) {
                i8xx_update_pll(intel_crtc,
                                has_reduced_clock ? &reduced_clock : NULL,
                                num_connectors);
-       else if (IS_VALLEYVIEW(dev))
+       } else if (IS_VALLEYVIEW(dev)) {
                vlv_update_pll(intel_crtc);
-       else
+       } else {
                i9xx_update_pll(intel_crtc,
                                has_reduced_clock ? &reduced_clock : NULL,
                                  num_connectors);
+       }
  
+ skip_dpll:
        /* Set up the display plane register */
        dspcntr = DISPPLANE_GAMMA_ENABLE;
  
         * which should always be the user's requested size.
         */
        I915_WRITE(DSPSIZE(plane),
-                  ((mode->vdisplay - 1) << 16) |
-                  (mode->hdisplay - 1));
+                  ((intel_crtc->config.pipe_src_h - 1) << 16) |
+                  (intel_crtc->config.pipe_src_w - 1));
        I915_WRITE(DSPPOS(plane), 0);
  
        i9xx_set_pipeconf(intel_crtc);
  
        ret = intel_pipe_set_base(crtc, x, y, fb);
  
-       intel_update_watermarks(dev);
        return ret;
  }
  
@@@ -4969,6 -5181,32 +5177,32 @@@ static void i9xx_get_pfit_config(struc
                        I915_READ(LVDS) & LVDS_BORDER_ENABLE;
  }
  
+ static void vlv_crtc_clock_get(struct intel_crtc *crtc,
+                              struct intel_crtc_config *pipe_config)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int pipe = pipe_config->cpu_transcoder;
+       intel_clock_t clock;
+       u32 mdiv;
+       int refclk = 100000;
+       mutex_lock(&dev_priv->dpio_lock);
+       mdiv = vlv_dpio_read(dev_priv, pipe, DPIO_DIV(pipe));
+       mutex_unlock(&dev_priv->dpio_lock);
+       clock.m1 = (mdiv >> DPIO_M1DIV_SHIFT) & 7;
+       clock.m2 = mdiv & DPIO_M2DIV_MASK;
+       clock.n = (mdiv >> DPIO_N_SHIFT) & 0xf;
+       clock.p1 = (mdiv >> DPIO_P1_SHIFT) & 7;
+       clock.p2 = (mdiv >> DPIO_P2_SHIFT) & 0x1f;
+       clock.vco = refclk * clock.m1 * clock.m2 / clock.n;
+       clock.dot = 2 * clock.vco / (clock.p1 * clock.p2);
+       pipe_config->port_clock = clock.dot / 10;
+ }
  static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
                                 struct intel_crtc_config *pipe_config)
  {
                }
        }
  
+       if (INTEL_INFO(dev)->gen < 4)
+               pipe_config->double_wide = tmp & PIPECONF_DOUBLE_WIDE;
        intel_get_pipe_timings(crtc, pipe_config);
  
        i9xx_get_pfit_config(crtc, pipe_config);
                                                     DPLL_PORTB_READY_MASK);
        }
  
+       if (IS_VALLEYVIEW(dev))
+               vlv_crtc_clock_get(crtc, pipe_config);
+       else
+               i9xx_crtc_clock_get(crtc, pipe_config);
        return true;
  }
  
@@@ -5838,25 -6084,67 +6080,67 @@@ static int ironlake_crtc_mode_set(struc
  
        ret = intel_pipe_set_base(crtc, x, y, fb);
  
-       intel_update_watermarks(dev);
        return ret;
  }
  
- static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
-                                       struct intel_crtc_config *pipe_config)
+ static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc,
+                                        struct intel_link_m_n *m_n)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum pipe pipe = crtc->pipe;
+       m_n->link_m = I915_READ(PCH_TRANS_LINK_M1(pipe));
+       m_n->link_n = I915_READ(PCH_TRANS_LINK_N1(pipe));
+       m_n->gmch_m = I915_READ(PCH_TRANS_DATA_M1(pipe))
+               & ~TU_SIZE_MASK;
+       m_n->gmch_n = I915_READ(PCH_TRANS_DATA_N1(pipe));
+       m_n->tu = ((I915_READ(PCH_TRANS_DATA_M1(pipe))
+                   & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+ }
+ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc,
+                                        enum transcoder transcoder,
+                                        struct intel_link_m_n *m_n)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       enum transcoder transcoder = pipe_config->cpu_transcoder;
+       enum pipe pipe = crtc->pipe;
+       if (INTEL_INFO(dev)->gen >= 5) {
+               m_n->link_m = I915_READ(PIPE_LINK_M1(transcoder));
+               m_n->link_n = I915_READ(PIPE_LINK_N1(transcoder));
+               m_n->gmch_m = I915_READ(PIPE_DATA_M1(transcoder))
+                       & ~TU_SIZE_MASK;
+               m_n->gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
+               m_n->tu = ((I915_READ(PIPE_DATA_M1(transcoder))
+                           & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+       } else {
+               m_n->link_m = I915_READ(PIPE_LINK_M_G4X(pipe));
+               m_n->link_n = I915_READ(PIPE_LINK_N_G4X(pipe));
+               m_n->gmch_m = I915_READ(PIPE_DATA_M_G4X(pipe))
+                       & ~TU_SIZE_MASK;
+               m_n->gmch_n = I915_READ(PIPE_DATA_N_G4X(pipe));
+               m_n->tu = ((I915_READ(PIPE_DATA_M_G4X(pipe))
+                           & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+       }
+ }
+ void intel_dp_get_m_n(struct intel_crtc *crtc,
+                     struct intel_crtc_config *pipe_config)
+ {
+       if (crtc->config.has_pch_encoder)
+               intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n);
+       else
+               intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
+                                            &pipe_config->dp_m_n);
+ }
  
-       pipe_config->fdi_m_n.link_m = I915_READ(PIPE_LINK_M1(transcoder));
-       pipe_config->fdi_m_n.link_n = I915_READ(PIPE_LINK_N1(transcoder));
-       pipe_config->fdi_m_n.gmch_m = I915_READ(PIPE_DATA_M1(transcoder))
-                                       & ~TU_SIZE_MASK;
-       pipe_config->fdi_m_n.gmch_n = I915_READ(PIPE_DATA_N1(transcoder));
-       pipe_config->fdi_m_n.tu = ((I915_READ(PIPE_DATA_M1(transcoder))
-                                  & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1;
+ static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc,
+                                       struct intel_crtc_config *pipe_config)
+ {
+       intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder,
+                                    &pipe_config->fdi_m_n);
  }
  
  static void ironlake_get_pfit_config(struct intel_crtc *crtc,
@@@ -5945,6 -6233,8 +6229,8 @@@ static bool ironlake_get_pipe_config(st
                pipe_config->pixel_multiplier =
                        ((tmp & PLL_REF_SDVO_HDMI_MULTIPLIER_MASK)
                         >> PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT) + 1;
+               ironlake_pch_clock_get(crtc, pipe_config);
        } else {
                pipe_config->pixel_multiplier = 1;
        }
@@@ -6001,8 -6291,8 +6287,8 @@@ static void assert_can_disable_lcpll(st
   * register. Callers should take care of disabling all the display engine
   * functions, doing the mode unset, fixing interrupts, etc.
   */
- void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
-                      bool switch_to_fclk, bool allow_power_down)
static void hsw_disable_lcpll(struct drm_i915_private *dev_priv,
+                             bool switch_to_fclk, bool allow_power_down)
  {
        uint32_t val;
  
  
        val = I915_READ(D_COMP);
        val |= D_COMP_COMP_DISABLE;
-       I915_WRITE(D_COMP, val);
+       mutex_lock(&dev_priv->rps.hw_lock);
+       if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val))
+               DRM_ERROR("Failed to disable D_COMP\n");
+       mutex_unlock(&dev_priv->rps.hw_lock);
        POSTING_READ(D_COMP);
        ndelay(100);
  
   * Fully restores LCPLL, disallowing power down and switching back to LCPLL
   * source.
   */
- void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
static void hsw_restore_lcpll(struct drm_i915_private *dev_priv)
  {
        uint32_t val;
  
        val = I915_READ(D_COMP);
        val |= D_COMP_COMP_FORCE;
        val &= ~D_COMP_COMP_DISABLE;
-       I915_WRITE(D_COMP, val);
+       mutex_lock(&dev_priv->rps.hw_lock);
+       if (sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_D_COMP, val))
+               DRM_ERROR("Failed to enable D_COMP\n");
+       mutex_unlock(&dev_priv->rps.hw_lock);
        POSTING_READ(D_COMP);
  
        val = I915_READ(LCPLL_CTL);
@@@ -6309,8 -6605,6 +6601,6 @@@ static int haswell_crtc_mode_set(struc
  
        ret = intel_pipe_set_base(crtc, x, y, fb);
  
-       intel_update_watermarks(dev);
        return ret;
  }
  
@@@ -6673,49 -6967,6 +6963,6 @@@ void intel_write_eld(struct drm_encode
                dev_priv->display.write_eld(connector, crtc);
  }
  
- /** Loads the palette/gamma unit for the CRTC with the prepared values */
- void intel_crtc_load_lut(struct drm_crtc *crtc)
- {
-       struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       enum pipe pipe = intel_crtc->pipe;
-       int palreg = PALETTE(pipe);
-       int i;
-       bool reenable_ips = false;
-       /* The clocks have to be on to load the palette. */
-       if (!crtc->enabled || !intel_crtc->active)
-               return;
-       if (!HAS_PCH_SPLIT(dev_priv->dev))
-               assert_pll_enabled(dev_priv, pipe);
-       /* use legacy palette for Ironlake */
-       if (HAS_PCH_SPLIT(dev))
-               palreg = LGC_PALETTE(pipe);
-       /* Workaround : Do not read or write the pipe palette/gamma data while
-        * GAMMA_MODE is configured for split gamma and IPS_CTL has IPS enabled.
-        */
-       if (intel_crtc->config.ips_enabled &&
-           ((I915_READ(GAMMA_MODE(pipe)) & GAMMA_MODE_MODE_MASK) ==
-            GAMMA_MODE_MODE_SPLIT)) {
-               hsw_disable_ips(intel_crtc);
-               reenable_ips = true;
-       }
-       for (i = 0; i < 256; i++) {
-               I915_WRITE(palreg + 4 * i,
-                          (intel_crtc->lut_r[i] << 16) |
-                          (intel_crtc->lut_g[i] << 8) |
-                          intel_crtc->lut_b[i]);
-       }
-       if (reenable_ips)
-               hsw_enable_ips(intel_crtc);
- }
  static void i845_update_cursor(struct drm_crtc *crtc, u32 base)
  {
        struct drm_device *dev = crtc->dev;
@@@ -6811,23 -7062,20 +7058,20 @@@ static void intel_crtc_update_cursor(st
        int pipe = intel_crtc->pipe;
        int x = intel_crtc->cursor_x;
        int y = intel_crtc->cursor_y;
-       u32 base, pos;
+       u32 base = 0, pos = 0;
        bool visible;
  
-       pos = 0;
-       if (on && crtc->enabled && crtc->fb) {
+       if (on)
                base = intel_crtc->cursor_addr;
-               if (x > (int) crtc->fb->width)
-                       base = 0;
  
-               if (y > (int) crtc->fb->height)
-                       base = 0;
-       } else
+       if (x >= intel_crtc->config.pipe_src_w)
+               base = 0;
+       if (y >= intel_crtc->config.pipe_src_h)
                base = 0;
  
        if (x < 0) {
-               if (x + intel_crtc->cursor_width < 0)
+               if (x + intel_crtc->cursor_width <= 0)
                        base = 0;
  
                pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT;
        pos |= x << CURSOR_X_SHIFT;
  
        if (y < 0) {
-               if (y + intel_crtc->cursor_height < 0)
+               if (y + intel_crtc->cursor_height <= 0)
                        base = 0;
  
                pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT;
@@@ -6988,27 -7236,6 +7232,6 @@@ static int intel_crtc_cursor_move(struc
        return 0;
  }
  
- /** Sets the color ramps on behalf of RandR */
- void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
-                                u16 blue, int regno)
- {
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       intel_crtc->lut_r[regno] = red >> 8;
-       intel_crtc->lut_g[regno] = green >> 8;
-       intel_crtc->lut_b[regno] = blue >> 8;
- }
- void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
-                            u16 *blue, int regno)
- {
-       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       *red = intel_crtc->lut_r[regno] << 8;
-       *green = intel_crtc->lut_g[regno] << 8;
-       *blue = intel_crtc->lut_b[regno] << 8;
- }
  static void intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
                                 u16 *blue, uint32_t start, uint32_t size)
  {
@@@ -7257,6 -7484,22 +7480,22 @@@ void intel_release_load_detect_pipe(str
        mutex_unlock(&crtc->mutex);
  }
  
+ static int i9xx_pll_refclk(struct drm_device *dev,
+                          const struct intel_crtc_config *pipe_config)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 dpll = pipe_config->dpll_hw_state.dpll;
+       if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN)
+               return dev_priv->vbt.lvds_ssc_freq * 1000;
+       else if (HAS_PCH_SPLIT(dev))
+               return 120000;
+       else if (!IS_GEN2(dev))
+               return 96000;
+       else
+               return 48000;
+ }
  /* Returns the clock of the currently programmed mode of the given pipe. */
  static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
                                struct intel_crtc_config *pipe_config)
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe = pipe_config->cpu_transcoder;
-       u32 dpll = I915_READ(DPLL(pipe));
+       u32 dpll = pipe_config->dpll_hw_state.dpll;
        u32 fp;
        intel_clock_t clock;
+       int refclk = i9xx_pll_refclk(dev, pipe_config);
  
        if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
-               fp = I915_READ(FP0(pipe));
+               fp = pipe_config->dpll_hw_state.fp0;
        else
-               fp = I915_READ(FP1(pipe));
+               fp = pipe_config->dpll_hw_state.fp1;
  
        clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
        if (IS_PINEVIEW(dev)) {
                default:
                        DRM_DEBUG_KMS("Unknown DPLL mode %08x in programmed "
                                  "mode\n", (int)(dpll & DPLL_MODE_MASK));
-                       pipe_config->adjusted_mode.clock = 0;
                        return;
                }
  
                if (IS_PINEVIEW(dev))
-                       pineview_clock(96000, &clock);
+                       pineview_clock(refclk, &clock);
                else
-                       i9xx_clock(96000, &clock);
+                       i9xx_clock(refclk, &clock);
        } else {
                bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN);
  
                        clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
                                       DPLL_FPA01_P1_POST_DIV_SHIFT);
                        clock.p2 = 14;
-                       if ((dpll & PLL_REF_INPUT_MASK) ==
-                           PLLB_REF_INPUT_SPREADSPECTRUMIN) {
-                               /* XXX: might not be 66MHz */
-                               i9xx_clock(66000, &clock);
-                       } else
-                               i9xx_clock(48000, &clock);
                } else {
                        if (dpll & PLL_P1_DIVIDE_BY_TWO)
                                clock.p1 = 2;
                                clock.p2 = 4;
                        else
                                clock.p2 = 2;
-                       i9xx_clock(48000, &clock);
                }
+               i9xx_clock(refclk, &clock);
        }
  
-       pipe_config->adjusted_mode.clock = clock.dot;
+       /*
+        * This value includes pixel_multiplier. We will use
+        * port_clock to compute adjusted_mode.crtc_clock in the
+        * encoder's get_config() function.
+        */
+       pipe_config->port_clock = clock.dot;
  }
  
static void ironlake_crtc_clock_get(struct intel_crtc *crtc,
-                                   struct intel_crtc_config *pipe_config)
int intel_dotclock_calculate(int link_freq,
+                            const struct intel_link_m_n *m_n)
  {
-       struct drm_device *dev = crtc->base.dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
-       int link_freq, repeat;
-       u64 clock;
-       u32 link_m, link_n;
-       repeat = pipe_config->pixel_multiplier;
        /*
         * The calculation for the data clock is:
-        * pixel_clock = ((m/n)*(link_clock * nr_lanes * repeat))/bpp
+        * pixel_clock = ((m/n)*(link_clock * nr_lanes))/bpp
         * But we want to avoid losing precison if possible, so:
-        * pixel_clock = ((m * link_clock * nr_lanes * repeat)/(n*bpp))
+        * pixel_clock = ((m * link_clock * nr_lanes)/(n*bpp))
         *
         * and the link clock is simpler:
-        * link_clock = (m * link_clock * repeat) / n
+        * link_clock = (m * link_clock) / n
         */
  
-       /*
-        * We need to get the FDI or DP link clock here to derive
-        * the M/N dividers.
-        *
-        * For FDI, we read it from the BIOS or use a fixed 2.7GHz.
-        * For DP, it's either 1.62GHz or 2.7GHz.
-        * We do our calculations in 10*MHz since we don't need much precison.
-        */
-       if (pipe_config->has_pch_encoder)
-               link_freq = intel_fdi_link_freq(dev) * 10000;
-       else
-               link_freq = pipe_config->port_clock;
+       if (!m_n->link_n)
+               return 0;
  
-       link_m = I915_READ(PIPE_LINK_M1(cpu_transcoder));
-       link_n = I915_READ(PIPE_LINK_N1(cpu_transcoder));
+       return div_u64((u64)m_n->link_m * link_freq, m_n->link_n);
+ }
  
-       if (!link_m || !link_n)
-               return;
+ static void ironlake_pch_clock_get(struct intel_crtc *crtc,
+                                  struct intel_crtc_config *pipe_config)
+ {
+       struct drm_device *dev = crtc->base.dev;
  
-       clock = ((u64)link_m * (u64)link_freq * (u64)repeat);
-       do_div(clock, link_n);
+       /* read out port_clock from the DPLL */
+       i9xx_crtc_clock_get(crtc, pipe_config);
  
-       pipe_config->adjusted_mode.clock = clock;
+       /*
+        * This value does not include pixel_multiplier.
+        * We will check that port_clock and adjusted_mode.crtc_clock
+        * agree once we know their relationship in the encoder's
+        * get_config() function.
+        */
+       pipe_config->adjusted_mode.crtc_clock =
+               intel_dotclock_calculate(intel_fdi_link_freq(dev) * 10000,
+                                        &pipe_config->fdi_m_n);
  }
  
  /** Returns the currently programmed mode of the given pipe. */
@@@ -7403,6 -7635,7 +7631,7 @@@ struct drm_display_mode *intel_crtc_mod
        int hsync = I915_READ(HSYNC(cpu_transcoder));
        int vtot = I915_READ(VTOTAL(cpu_transcoder));
        int vsync = I915_READ(VSYNC(cpu_transcoder));
+       enum pipe pipe = intel_crtc->pipe;
  
        mode = kzalloc(sizeof(*mode), GFP_KERNEL);
        if (!mode)
         * Note, if LVDS ever uses a non-1 pixel multiplier, we'll need
         * to use a real value here instead.
         */
-       pipe_config.cpu_transcoder = (enum transcoder) intel_crtc->pipe;
+       pipe_config.cpu_transcoder = (enum transcoder) pipe;
        pipe_config.pixel_multiplier = 1;
+       pipe_config.dpll_hw_state.dpll = I915_READ(DPLL(pipe));
+       pipe_config.dpll_hw_state.fp0 = I915_READ(FP0(pipe));
+       pipe_config.dpll_hw_state.fp1 = I915_READ(FP1(pipe));
        i9xx_crtc_clock_get(intel_crtc, &pipe_config);
  
-       mode->clock = pipe_config.adjusted_mode.clock;
+       mode->clock = pipe_config.port_clock / pipe_config.pixel_multiplier;
        mode->hdisplay = (htot & 0xffff) + 1;
        mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
        mode->hsync_start = (hsync & 0xffff) + 1;
@@@ -7525,6 -7761,9 +7757,9 @@@ void intel_mark_idle(struct drm_device 
  
                intel_decrease_pllclock(crtc);
        }
+       if (dev_priv->info->gen >= 6)
+               gen6_rps_idle(dev->dev_private);
  }
  
  void intel_mark_fb_busy(struct drm_i915_gem_object *obj,
@@@ -7713,7 -7952,7 +7948,7 @@@ static int intel_gen2_queue_flip(struc
        intel_ring_emit(ring, 0); /* aux display base address, unused */
  
        intel_mark_page_flip_active(intel_crtc);
-       intel_ring_advance(ring);
+       __intel_ring_advance(ring);
        return 0;
  
  err_unpin:
@@@ -7755,7 -7994,7 +7990,7 @@@ static int intel_gen3_queue_flip(struc
        intel_ring_emit(ring, MI_NOOP);
  
        intel_mark_page_flip_active(intel_crtc);
-       intel_ring_advance(ring);
+       __intel_ring_advance(ring);
        return 0;
  
  err_unpin:
@@@ -7804,7 -8043,7 +8039,7 @@@ static int intel_gen4_queue_flip(struc
        intel_ring_emit(ring, pf | pipesrc);
  
        intel_mark_page_flip_active(intel_crtc);
-       intel_ring_advance(ring);
+       __intel_ring_advance(ring);
        return 0;
  
  err_unpin:
@@@ -7849,7 -8088,7 +8084,7 @@@ static int intel_gen6_queue_flip(struc
        intel_ring_emit(ring, pf | pipesrc);
  
        intel_mark_page_flip_active(intel_crtc);
-       intel_ring_advance(ring);
+       __intel_ring_advance(ring);
        return 0;
  
  err_unpin:
@@@ -7928,7 -8167,7 +8163,7 @@@ static int intel_gen7_queue_flip(struc
        intel_ring_emit(ring, (MI_NOOP));
  
        intel_mark_page_flip_active(intel_crtc);
-       intel_ring_advance(ring);
+       __intel_ring_advance(ring);
        return 0;
  
  err_unpin:
@@@ -7973,7 -8212,7 +8208,7 @@@ static int intel_crtc_page_flip(struct 
             fb->pitches[0] != crtc->fb->pitches[0]))
                return -EINVAL;
  
-       work = kzalloc(sizeof *work, GFP_KERNEL);
+       work = kzalloc(sizeof(*work), GFP_KERNEL);
        if (work == NULL)
                return -ENOMEM;
  
@@@ -8208,6 -8447,17 +8443,17 @@@ compute_baseline_pipe_bpp(struct intel_
        return bpp;
  }
  
+ static void intel_dump_crtc_timings(const struct drm_display_mode *mode)
+ {
+       DRM_DEBUG_KMS("crtc timings: %d %d %d %d %d %d %d %d %d, "
+                       "type: 0x%x flags: 0x%x\n",
+               mode->crtc_clock,
+               mode->crtc_hdisplay, mode->crtc_hsync_start,
+               mode->crtc_hsync_end, mode->crtc_htotal,
+               mode->crtc_vdisplay, mode->crtc_vsync_start,
+               mode->crtc_vsync_end, mode->crtc_vtotal, mode->type, mode->flags);
+ }
  static void intel_dump_pipe_config(struct intel_crtc *crtc,
                                   struct intel_crtc_config *pipe_config,
                                   const char *context)
                      pipe_config->fdi_m_n.gmch_m, pipe_config->fdi_m_n.gmch_n,
                      pipe_config->fdi_m_n.link_m, pipe_config->fdi_m_n.link_n,
                      pipe_config->fdi_m_n.tu);
+       DRM_DEBUG_KMS("dp: %i, gmch_m: %u, gmch_n: %u, link_m: %u, link_n: %u, tu: %u\n",
+                     pipe_config->has_dp_encoder,
+                     pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n,
+                     pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n,
+                     pipe_config->dp_m_n.tu);
        DRM_DEBUG_KMS("requested mode:\n");
        drm_mode_debug_printmodeline(&pipe_config->requested_mode);
        DRM_DEBUG_KMS("adjusted mode:\n");
        drm_mode_debug_printmodeline(&pipe_config->adjusted_mode);
+       intel_dump_crtc_timings(&pipe_config->adjusted_mode);
+       DRM_DEBUG_KMS("port clock: %d\n", pipe_config->port_clock);
+       DRM_DEBUG_KMS("pipe src size: %dx%d\n",
+                     pipe_config->pipe_src_w, pipe_config->pipe_src_h);
        DRM_DEBUG_KMS("gmch pfit: control: 0x%08x, ratios: 0x%08x, lvds border: 0x%08x\n",
                      pipe_config->gmch_pfit.control,
                      pipe_config->gmch_pfit.pgm_ratios,
                      pipe_config->pch_pfit.size,
                      pipe_config->pch_pfit.enabled ? "enabled" : "disabled");
        DRM_DEBUG_KMS("ips: %i\n", pipe_config->ips_enabled);
+       DRM_DEBUG_KMS("double wide: %i\n", pipe_config->double_wide);
  }
  
  static bool check_encoder_cloning(struct drm_crtc *crtc)
@@@ -8280,6 -8540,7 +8536,7 @@@ intel_modeset_pipe_config(struct drm_cr
  
        drm_mode_copy(&pipe_config->adjusted_mode, mode);
        drm_mode_copy(&pipe_config->requested_mode, mode);
        pipe_config->cpu_transcoder =
                (enum transcoder) to_intel_crtc(crtc)->pipe;
        pipe_config->shared_dpll = DPLL_ID_PRIVATE;
        if (plane_bpp < 0)
                goto fail;
  
+       /*
+        * Determine the real pipe dimensions. Note that stereo modes can
+        * increase the actual pipe size due to the frame doubling and
+        * insertion of additional space for blanks between the frame. This
+        * is stored in the crtc timings. We use the requested mode to do this
+        * computation to clearly distinguish it from the adjusted mode, which
+        * can be changed by the connectors in the below retry loop.
+        */
+       drm_mode_set_crtcinfo(&pipe_config->requested_mode, CRTC_STEREO_DOUBLE);
+       pipe_config->pipe_src_w = pipe_config->requested_mode.crtc_hdisplay;
+       pipe_config->pipe_src_h = pipe_config->requested_mode.crtc_vdisplay;
  encoder_retry:
        /* Ensure the port clock defaults are reset when retrying. */
        pipe_config->port_clock = 0;
        pipe_config->pixel_multiplier = 1;
  
        /* Fill in default crtc timings, allow encoders to overwrite them. */
-       drm_mode_set_crtcinfo(&pipe_config->adjusted_mode, 0);
+       drm_mode_set_crtcinfo(&pipe_config->adjusted_mode, CRTC_STEREO_DOUBLE);
  
        /* Pass our mode to the connectors and the CRTC to give them a chance to
         * adjust it according to limitations or connector properties, and also
        /* Set default port clock if not overwritten by the encoder. Needs to be
         * done afterwards in case the encoder adjusts the mode. */
        if (!pipe_config->port_clock)
-               pipe_config->port_clock = pipe_config->adjusted_mode.clock;
+               pipe_config->port_clock = pipe_config->adjusted_mode.crtc_clock
+                       * pipe_config->pixel_multiplier;
  
        ret = intel_crtc_compute_config(to_intel_crtc(crtc), pipe_config);
        if (ret < 0) {
@@@ -8520,13 -8794,9 +8790,9 @@@ intel_modeset_update_state(struct drm_d
  
  }
  
- static bool intel_fuzzy_clock_check(struct intel_crtc_config *cur,
-                                   struct intel_crtc_config *new)
+ static bool intel_fuzzy_clock_check(int clock1, int clock2)
  {
-       int clock1, clock2, diff;
-       clock1 = cur->adjusted_mode.clock;
-       clock2 = new->adjusted_mode.clock;
+       int diff;
  
        if (clock1 == clock2)
                return true;
@@@ -8580,6 -8850,15 +8846,15 @@@ intel_pipe_config_compare(struct drm_de
                return false; \
        }
  
+ #define PIPE_CONF_CHECK_CLOCK_FUZZY(name) \
+       if (!intel_fuzzy_clock_check(current_config->name, pipe_config->name)) { \
+               DRM_ERROR("mismatch in " #name " " \
+                         "(expected %i, found %i)\n", \
+                         current_config->name, \
+                         pipe_config->name); \
+               return false; \
+       }
  #define PIPE_CONF_QUIRK(quirk)        \
        ((current_config->quirks | pipe_config->quirks) & (quirk))
  
        PIPE_CONF_CHECK_I(fdi_m_n.link_n);
        PIPE_CONF_CHECK_I(fdi_m_n.tu);
  
+       PIPE_CONF_CHECK_I(has_dp_encoder);
+       PIPE_CONF_CHECK_I(dp_m_n.gmch_m);
+       PIPE_CONF_CHECK_I(dp_m_n.gmch_n);
+       PIPE_CONF_CHECK_I(dp_m_n.link_m);
+       PIPE_CONF_CHECK_I(dp_m_n.link_n);
+       PIPE_CONF_CHECK_I(dp_m_n.tu);
        PIPE_CONF_CHECK_I(adjusted_mode.crtc_hdisplay);
        PIPE_CONF_CHECK_I(adjusted_mode.crtc_htotal);
        PIPE_CONF_CHECK_I(adjusted_mode.crtc_hblank_start);
                                      DRM_MODE_FLAG_NVSYNC);
        }
  
-       PIPE_CONF_CHECK_I(requested_mode.hdisplay);
-       PIPE_CONF_CHECK_I(requested_mode.vdisplay);
+       PIPE_CONF_CHECK_I(pipe_src_w);
+       PIPE_CONF_CHECK_I(pipe_src_h);
  
        PIPE_CONF_CHECK_I(gmch_pfit.control);
        /* pfit ratios are autocomputed by the hw on gen4+ */
  
        PIPE_CONF_CHECK_I(ips_enabled);
  
+       PIPE_CONF_CHECK_I(double_wide);
        PIPE_CONF_CHECK_I(shared_dpll);
        PIPE_CONF_CHECK_X(dpll_hw_state.dpll);
        PIPE_CONF_CHECK_X(dpll_hw_state.dpll_md);
        if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5)
                PIPE_CONF_CHECK_I(pipe_bpp);
  
+       if (!IS_HASWELL(dev)) {
+               PIPE_CONF_CHECK_CLOCK_FUZZY(adjusted_mode.crtc_clock);
+               PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock);
+       }
  #undef PIPE_CONF_CHECK_X
  #undef PIPE_CONF_CHECK_I
  #undef PIPE_CONF_CHECK_FLAGS
+ #undef PIPE_CONF_CHECK_CLOCK_FUZZY
  #undef PIPE_CONF_QUIRK
  
-       if (!IS_HASWELL(dev)) {
-               if (!intel_fuzzy_clock_check(current_config, pipe_config)) {
-                       DRM_ERROR("mismatch in clock (expected %d, found %d)\n",
-                                 current_config->adjusted_mode.clock,
-                                 pipe_config->adjusted_mode.clock);
-                       return false;
-               }
-       }
        return true;
  }
  
@@@ -8793,9 -9078,6 +9074,6 @@@ check_crtc_state(struct drm_device *dev
                                encoder->get_config(encoder, &pipe_config);
                }
  
-               if (dev_priv->display.get_clock)
-                       dev_priv->display.get_clock(crtc, &pipe_config);
                WARN(crtc->active != active,
                     "crtc active state doesn't match with hw state "
                     "(expected %i, found %i)\n", crtc->active, active);
@@@ -8870,6 -9152,18 +9148,18 @@@ intel_modeset_check_state(struct drm_de
        check_shared_dpll_state(dev);
  }
  
+ void ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config,
+                                    int dotclock)
+ {
+       /*
+        * FDI already provided one idea for the dotclock.
+        * Yell if the encoder disagrees.
+        */
+       WARN(!intel_fuzzy_clock_check(pipe_config->adjusted_mode.crtc_clock, dotclock),
+            "FDI dotclock and encoder dotclock mismatch, fdi: %i, encoder: %i\n",
+            pipe_config->adjusted_mode.crtc_clock, dotclock);
+ }
  static int __intel_set_mode(struct drm_crtc *crtc,
                            struct drm_display_mode *mode,
                            int x, int y, struct drm_framebuffer *fb)
        unsigned disable_pipes, prepare_pipes, modeset_pipes;
        int ret = 0;
  
-       saved_mode = kmalloc(2 * sizeof(*saved_mode), GFP_KERNEL);
+       saved_mode = kcalloc(2, sizeof(*saved_mode), GFP_KERNEL);
        if (!saved_mode)
                return -ENOMEM;
        saved_hwmode = saved_mode + 1;
@@@ -9421,7 -9715,7 +9711,7 @@@ static void intel_crtc_init(struct drm_
        struct intel_crtc *intel_crtc;
        int i;
  
-       intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
+       intel_crtc = kzalloc(sizeof(*intel_crtc), GFP_KERNEL);
        if (intel_crtc == NULL)
                return;
  
@@@ -9587,6 -9881,8 +9877,8 @@@ static void intel_setup_outputs(struct 
                        if (I915_READ(VLV_DISPLAY_BASE + DP_B) & DP_DETECTED)
                                intel_dp_init(dev, VLV_DISPLAY_BASE + DP_B, PORT_B);
                }
+               intel_dsi_init(dev);
        } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) {
                bool found = false;
  
@@@ -9819,7 -10115,6 +10111,6 @@@ static void intel_init_display(struct d
                dev_priv->display.update_plane = ironlake_update_plane;
        } else if (HAS_PCH_SPLIT(dev)) {
                dev_priv->display.get_pipe_config = ironlake_get_pipe_config;
-               dev_priv->display.get_clock = ironlake_crtc_clock_get;
                dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
                dev_priv->display.crtc_enable = ironlake_crtc_enable;
                dev_priv->display.crtc_disable = ironlake_crtc_disable;
                dev_priv->display.update_plane = ironlake_update_plane;
        } else if (IS_VALLEYVIEW(dev)) {
                dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
-               dev_priv->display.get_clock = i9xx_crtc_clock_get;
                dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
                dev_priv->display.crtc_enable = valleyview_crtc_enable;
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
                dev_priv->display.update_plane = i9xx_update_plane;
        } else {
                dev_priv->display.get_pipe_config = i9xx_get_pipe_config;
-               dev_priv->display.get_clock = i9xx_crtc_clock_get;
                dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
                dev_priv->display.crtc_enable = i9xx_crtc_enable;
                dev_priv->display.crtc_disable = i9xx_crtc_disable;
@@@ -10021,20 -10314,11 +10310,11 @@@ static struct intel_quirk intel_quirks[
        /* Sony Vaio Y cannot use SSC on LVDS */
        { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable },
  
-       /* Acer Aspire 5734Z must invert backlight brightness */
-       { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness },
-       /* Acer/eMachines G725 */
-       { 0x2a42, 0x1025, 0x0210, quirk_invert_brightness },
-       /* Acer/eMachines e725 */
-       { 0x2a42, 0x1025, 0x0212, quirk_invert_brightness },
-       /* Acer/Packard Bell NCL20 */
-       { 0x2a42, 0x1025, 0x034b, quirk_invert_brightness },
-       /* Acer Aspire 4736Z */
-       { 0x2a42, 0x1025, 0x0260, quirk_invert_brightness },
+       /*
+        * All GM45 Acer (and its brands eMachines and Packard Bell) laptops
+        * seem to use inverted backlight PWM.
+        */
+       { 0x2a42, 0x1025, PCI_ANY_ID, quirk_invert_brightness },
  
        /* Dell XPS13 HD Sandy Bridge */
        { 0x0116, 0x1028, 0x052e, quirk_no_pcm_pwm_enable },
@@@ -10081,14 -10365,48 +10361,21 @@@ static void i915_disable_vga(struct drm
        POSTING_READ(vga_reg);
  }
  
 -static void i915_enable_vga_mem(struct drm_device *dev)
 -{
 -      /* Enable VGA memory on Intel HD */
 -      if (HAS_PCH_SPLIT(dev)) {
 -              vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
 -              outb(inb(VGA_MSR_READ) | VGA_MSR_MEM_EN, VGA_MSR_WRITE);
 -              vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO |
 -                                                 VGA_RSRC_LEGACY_MEM |
 -                                                 VGA_RSRC_NORMAL_IO |
 -                                                 VGA_RSRC_NORMAL_MEM);
 -              vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 -      }
 -}
 -
 -void i915_disable_vga_mem(struct drm_device *dev)
 -{
 -      /* Disable VGA memory on Intel HD */
 -      if (HAS_PCH_SPLIT(dev)) {
 -              vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO);
 -              outb(inb(VGA_MSR_READ) & ~VGA_MSR_MEM_EN, VGA_MSR_WRITE);
 -              vga_set_legacy_decoding(dev->pdev, VGA_RSRC_LEGACY_IO |
 -                                                 VGA_RSRC_NORMAL_IO |
 -                                                 VGA_RSRC_NORMAL_MEM);
 -              vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
 -      }
 -}
 -
  void intel_modeset_init_hw(struct drm_device *dev)
  {
-       intel_init_power_well(dev);
+       struct drm_i915_private *dev_priv = dev->dev_private;
  
        intel_prepare_ddi(dev);
  
        intel_init_clock_gating(dev);
  
+       /* Enable the CRI clock source so we can get at the display */
+       if (IS_VALLEYVIEW(dev))
+               I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
+                          DPLL_INTEGRATED_CRI_CLK_VLV);
+       intel_init_dpio(dev);
        mutex_lock(&dev->struct_mutex);
        intel_enable_gt_powersave(dev);
        mutex_unlock(&dev->struct_mutex);
@@@ -10359,6 -10677,7 +10646,6 @@@ void i915_redisable_vga(struct drm_devi
        if (I915_READ(vga_reg) != VGA_DISP_DISABLE) {
                DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n");
                i915_disable_vga(dev);
 -              i915_disable_vga_mem(dev);
        }
  }
  
@@@ -10426,15 -10745,6 +10713,6 @@@ static void intel_modeset_readout_hw_st
                              pipe);
        }
  
-       list_for_each_entry(crtc, &dev->mode_config.crtc_list,
-                           base.head) {
-               if (!crtc->active)
-                       continue;
-               if (dev_priv->display.get_clock)
-                       dev_priv->display.get_clock(crtc,
-                                                   &crtc->config);
-       }
        list_for_each_entry(connector, &dev->mode_config.connector_list,
                            base.head) {
                if (connector->get_hw_state(connector)) {
@@@ -10459,7 -10769,6 +10737,6 @@@ void intel_modeset_setup_hw_state(struc
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum pipe pipe;
-       struct drm_plane *plane;
        struct intel_crtc *crtc;
        struct intel_encoder *encoder;
        int i;
        }
  
        if (force_restore) {
+               i915_redisable_vga(dev);
                /*
                 * We need to use raw interfaces for restoring state to avoid
                 * checking (bogus) intermediate states.
                        __intel_set_mode(crtc, &crtc->mode, crtc->x, crtc->y,
                                         crtc->fb);
                }
-               list_for_each_entry(plane, &dev->mode_config.plane_list, head)
-                       intel_plane_restore(plane);
-               i915_redisable_vga(dev);
        } else {
                intel_modeset_update_staged_output_state(dev);
        }
@@@ -10544,6 -10851,7 +10819,7 @@@ void intel_modeset_cleanup(struct drm_d
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc;
+       struct drm_connector *connector;
  
        /*
         * Interrupts and polling as the first thing to avoid creating havoc.
  
        intel_disable_fbc(dev);
  
 -      i915_enable_vga_mem(dev);
 -
        intel_disable_gt_powersave(dev);
  
        ironlake_teardown_rc6(dev);
        /* destroy backlight, if any, before the connectors */
        intel_panel_destroy_backlight(dev);
  
+       /* destroy the sysfs files before encoders/connectors */
+       list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+               drm_sysfs_connector_remove(connector);
        drm_mode_config_cleanup(dev);
  
        intel_cleanup_overlay(dev);
index 1a431377d83b76ad22bccf795db770ab3b40bd3e,d5bd349105e5ef86033e401efc882f654c50d1d1..2a4bcc829f3f66c68f7c78f76fbae30027c738cd
  
  #define DP_LINK_CHECK_TIMEOUT (10 * 1000)
  
+ struct dp_link_dpll {
+       int link_bw;
+       struct dpll dpll;
+ };
+ static const struct dp_link_dpll gen4_dpll[] = {
+       { DP_LINK_BW_1_62,
+               { .p1 = 2, .p2 = 10, .n = 2, .m1 = 23, .m2 = 8 } },
+       { DP_LINK_BW_2_7,
+               { .p1 = 1, .p2 = 10, .n = 1, .m1 = 14, .m2 = 2 } }
+ };
+ static const struct dp_link_dpll pch_dpll[] = {
+       { DP_LINK_BW_1_62,
+               { .p1 = 2, .p2 = 10, .n = 1, .m1 = 12, .m2 = 9 } },
+       { DP_LINK_BW_2_7,
+               { .p1 = 1, .p2 = 10, .n = 2, .m1 = 14, .m2 = 8 } }
+ };
+ static const struct dp_link_dpll vlv_dpll[] = {
+       { DP_LINK_BW_1_62,
+               { .p1 = 3, .p2 = 2, .n = 5, .m1 = 3, .m2 = 81 } },
+       { DP_LINK_BW_2_7,
+               { .p1 = 2, .p2 = 2, .n = 1, .m1 = 2, .m2 = 27 } }
+ };
  /**
   * is_edp - is the given port attached to an eDP panel (either CPU or PCH)
   * @intel_dp: DP struct
@@@ -211,24 -237,77 +237,77 @@@ intel_hrawclk(struct drm_device *dev
        }
  }
  
+ static void
+ intel_dp_init_panel_power_sequencer(struct drm_device *dev,
+                                   struct intel_dp *intel_dp,
+                                   struct edp_power_seq *out);
+ static void
+ intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev,
+                                             struct intel_dp *intel_dp,
+                                             struct edp_power_seq *out);
+ static enum pipe
+ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
+ {
+       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+       struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
+       struct drm_device *dev = intel_dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       enum port port = intel_dig_port->port;
+       enum pipe pipe;
+       /* modeset should have pipe */
+       if (crtc)
+               return to_intel_crtc(crtc)->pipe;
+       /* init time, try to find a pipe with this port selected */
+       for (pipe = PIPE_A; pipe <= PIPE_B; pipe++) {
+               u32 port_sel = I915_READ(VLV_PIPE_PP_ON_DELAYS(pipe)) &
+                       PANEL_PORT_SELECT_MASK;
+               if (port_sel == PANEL_PORT_SELECT_DPB_VLV && port == PORT_B)
+                       return pipe;
+               if (port_sel == PANEL_PORT_SELECT_DPC_VLV && port == PORT_C)
+                       return pipe;
+       }
+       /* shrug */
+       return PIPE_A;
+ }
+ static u32 _pp_ctrl_reg(struct intel_dp *intel_dp)
+ {
+       struct drm_device *dev = intel_dp_to_dev(intel_dp);
+       if (HAS_PCH_SPLIT(dev))
+               return PCH_PP_CONTROL;
+       else
+               return VLV_PIPE_PP_CONTROL(vlv_power_sequencer_pipe(intel_dp));
+ }
+ static u32 _pp_stat_reg(struct intel_dp *intel_dp)
+ {
+       struct drm_device *dev = intel_dp_to_dev(intel_dp);
+       if (HAS_PCH_SPLIT(dev))
+               return PCH_PP_STATUS;
+       else
+               return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp));
+ }
  static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp)
  {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 pp_stat_reg;
  
-       pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-       return (I915_READ(pp_stat_reg) & PP_ON) != 0;
+       return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0;
  }
  
  static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp)
  {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 pp_ctrl_reg;
  
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
-       return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0;
+       return (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0;
  }
  
  static void
@@@ -236,19 -315,15 +315,15 @@@ intel_dp_check_edp(struct intel_dp *int
  {
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 pp_stat_reg, pp_ctrl_reg;
  
        if (!is_edp(intel_dp))
                return;
  
-       pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
        if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) {
                WARN(1, "eDP powered off while attempting aux channel communication.\n");
                DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n",
-                               I915_READ(pp_stat_reg),
-                               I915_READ(pp_ctrl_reg));
+                             I915_READ(_pp_stat_reg(intel_dp)),
+                             I915_READ(_pp_ctrl_reg(intel_dp)));
        }
  }
  
@@@ -361,6 -436,12 +436,12 @@@ intel_dp_aux_ch(struct intel_dp *intel_
                goto out;
        }
  
+       /* Only 5 data registers! */
+       if (WARN_ON(send_bytes > 20 || recv_size > 20)) {
+               ret = -E2BIG;
+               goto out;
+       }
        while ((aux_clock_divider = get_aux_clock_divider(intel_dp, clock++))) {
                /* Must try at least 3 times according to DP spec */
                for (try = 0; try < 5; try++) {
@@@ -451,9 -532,10 +532,10 @@@ intel_dp_aux_native_write(struct intel_
        int msg_bytes;
        uint8_t ack;
  
+       if (WARN_ON(send_bytes > 16))
+               return -E2BIG;
        intel_dp_check_edp(intel_dp);
-       if (send_bytes > 16)
-               return -1;
        msg[0] = AUX_NATIVE_WRITE << 4;
        msg[1] = address >> 8;
        msg[2] = address & 0xff;
@@@ -494,6 -576,9 +576,9 @@@ intel_dp_aux_native_read(struct intel_d
        uint8_t ack;
        int ret;
  
+       if (WARN_ON(recv_bytes > 19))
+               return -E2BIG;
        intel_dp_check_edp(intel_dp);
        msg[0] = AUX_NATIVE_READ << 4;
        msg[1] = address >> 8;
@@@ -569,7 -654,12 +654,12 @@@ intel_dp_i2c_aux_ch(struct i2c_adapter 
                break;
        }
  
-       for (retry = 0; retry < 5; retry++) {
+       /*
+        * DP1.2 sections 2.7.7.1.5.6.1 and 2.7.7.1.6.6.1: A DP Source device is
+        * required to retry at least seven times upon receiving AUX_DEFER
+        * before giving up the AUX transaction.
+        */
+       for (retry = 0; retry < 7; retry++) {
                ret = intel_dp_aux_ch(intel_dp,
                                      msg, msg_bytes,
                                      reply, reply_bytes);
@@@ -647,7 -737,7 +737,7 @@@ intel_dp_i2c_init(struct intel_dp *inte
        strncpy(intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1);
        intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0';
        intel_dp->adapter.algo_data = &intel_dp->algo;
-       intel_dp->adapter.dev.parent = &intel_connector->base.kdev;
+       intel_dp->adapter.dev.parent = intel_connector->base.kdev;
  
        ironlake_edp_panel_vdd_on(intel_dp);
        ret = i2c_dp_aux_add_bus(&intel_dp->adapter);
@@@ -660,41 -750,30 +750,30 @@@ intel_dp_set_clock(struct intel_encode
                   struct intel_crtc_config *pipe_config, int link_bw)
  {
        struct drm_device *dev = encoder->base.dev;
+       const struct dp_link_dpll *divisor = NULL;
+       int i, count = 0;
  
        if (IS_G4X(dev)) {
-               if (link_bw == DP_LINK_BW_1_62) {
-                       pipe_config->dpll.p1 = 2;
-                       pipe_config->dpll.p2 = 10;
-                       pipe_config->dpll.n = 2;
-                       pipe_config->dpll.m1 = 23;
-                       pipe_config->dpll.m2 = 8;
-               } else {
-                       pipe_config->dpll.p1 = 1;
-                       pipe_config->dpll.p2 = 10;
-                       pipe_config->dpll.n = 1;
-                       pipe_config->dpll.m1 = 14;
-                       pipe_config->dpll.m2 = 2;
-               }
-               pipe_config->clock_set = true;
+               divisor = gen4_dpll;
+               count = ARRAY_SIZE(gen4_dpll);
        } else if (IS_HASWELL(dev)) {
                /* Haswell has special-purpose DP DDI clocks. */
        } else if (HAS_PCH_SPLIT(dev)) {
-               if (link_bw == DP_LINK_BW_1_62) {
-                       pipe_config->dpll.n = 1;
-                       pipe_config->dpll.p1 = 2;
-                       pipe_config->dpll.p2 = 10;
-                       pipe_config->dpll.m1 = 12;
-                       pipe_config->dpll.m2 = 9;
-               } else {
-                       pipe_config->dpll.n = 2;
-                       pipe_config->dpll.p1 = 1;
-                       pipe_config->dpll.p2 = 10;
-                       pipe_config->dpll.m1 = 14;
-                       pipe_config->dpll.m2 = 8;
-               }
-               pipe_config->clock_set = true;
+               divisor = pch_dpll;
+               count = ARRAY_SIZE(pch_dpll);
        } else if (IS_VALLEYVIEW(dev)) {
-               /* FIXME: Need to figure out optimized DP clocks for vlv. */
+               divisor = vlv_dpll;
+               count = ARRAY_SIZE(vlv_dpll);
+       }
+       if (divisor && count) {
+               for (i = 0; i < count; i++) {
+                       if (link_bw == divisor[i].link_bw) {
+                               pipe_config->dpll = divisor[i].dpll;
+                               pipe_config->clock_set = true;
+                               break;
+                       }
+               }
        }
  }
  
@@@ -737,7 -816,8 +816,8 @@@ intel_dp_compute_config(struct intel_en
  
        DRM_DEBUG_KMS("DP link computation with max lane count %i "
                      "max bw %02x pixel clock %iKHz\n",
-                     max_lane_count, bws[max_clock], adjusted_mode->clock);
+                     max_lane_count, bws[max_clock],
+                     adjusted_mode->crtc_clock);
  
        /* Walk through all bpp values. Luckily they're all nicely spaced with 2
         * bpc in between. */
        }
  
        for (; bpp >= 6*3; bpp -= 2*3) {
-               mode_rate = intel_dp_link_required(adjusted_mode->clock, bpp);
+               mode_rate = intel_dp_link_required(adjusted_mode->crtc_clock,
+                                                  bpp);
  
                for (clock = 0; clock <= max_clock; clock++) {
                        for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) {
@@@ -794,7 -875,8 +875,8 @@@ found
                      mode_rate, link_avail);
  
        intel_link_compute_m_n(bpp, lane_count,
-                              adjusted_mode->clock, pipe_config->port_clock,
+                              adjusted_mode->crtc_clock,
+                              pipe_config->port_clock,
                               &pipe_config->dp_m_n);
  
        intel_dp_set_clock(encoder, pipe_config, intel_dp->link_bw);
        return true;
  }
  
- void intel_dp_init_link_config(struct intel_dp *intel_dp)
- {
-       memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
-       intel_dp->link_configuration[0] = intel_dp->link_bw;
-       intel_dp->link_configuration[1] = intel_dp->lane_count;
-       intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B;
-       /*
-        * Check for DPCD version > 1.1 and enhanced framing support
-        */
-       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
-           (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) {
-               intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
-       }
- }
  static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp)
  {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
@@@ -889,8 -956,6 +956,6 @@@ static void intel_dp_mode_set(struct in
                intel_write_eld(&encoder->base, adjusted_mode);
        }
  
-       intel_dp_init_link_config(intel_dp);
        /* Split out the IBX/CPU vs CPT settings */
  
        if (port == PORT_A && IS_GEN7(dev) && !IS_VALLEYVIEW(dev)) {
                        intel_dp->DP |= DP_SYNC_VS_HIGH;
                intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT;
  
-               if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
+               if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
  
                intel_dp->DP |= crtc->pipe << 29;
                        intel_dp->DP |= DP_SYNC_VS_HIGH;
                intel_dp->DP |= DP_LINK_TRAIN_OFF;
  
-               if (intel_dp->link_configuration[1] & DP_LANE_COUNT_ENHANCED_FRAME_EN)
+               if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
  
                if (crtc->pipe == 1)
@@@ -944,8 -1009,8 +1009,8 @@@ static void ironlake_wait_panel_status(
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 pp_stat_reg, pp_ctrl_reg;
  
-       pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+       pp_stat_reg = _pp_stat_reg(intel_dp);
+       pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
  
        DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n",
                        mask, value,
@@@ -987,11 -1052,8 +1052,8 @@@ static  u32 ironlake_get_pp_control(str
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 control;
-       u32 pp_ctrl_reg;
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
-       control = I915_READ(pp_ctrl_reg);
  
+       control = I915_READ(_pp_ctrl_reg(intel_dp));
        control &= ~PANEL_UNLOCK_MASK;
        control |= PANEL_UNLOCK_REGS;
        return control;
@@@ -1024,8 -1086,8 +1086,8 @@@ void ironlake_edp_panel_vdd_on(struct i
        pp = ironlake_get_pp_control(intel_dp);
        pp |= EDP_FORCE_VDD;
  
-       pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+       pp_stat_reg = _pp_stat_reg(intel_dp);
+       pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
  
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
@@@ -1053,8 -1115,8 +1115,8 @@@ static void ironlake_panel_vdd_off_sync
                pp = ironlake_get_pp_control(intel_dp);
                pp &= ~EDP_FORCE_VDD;
  
-               pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS;
-               pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+               pp_stat_reg = _pp_ctrl_reg(intel_dp);
+               pp_ctrl_reg = _pp_stat_reg(intel_dp);
  
                I915_WRITE(pp_ctrl_reg, pp);
                POSTING_READ(pp_ctrl_reg);
@@@ -1119,20 -1181,19 +1181,19 @@@ void ironlake_edp_panel_on(struct intel
  
        ironlake_wait_panel_power_cycle(intel_dp);
  
+       pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
        pp = ironlake_get_pp_control(intel_dp);
        if (IS_GEN5(dev)) {
                /* ILK workaround: disable reset around power sequence */
                pp &= ~PANEL_POWER_RESET;
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
+               I915_WRITE(pp_ctrl_reg, pp);
+               POSTING_READ(pp_ctrl_reg);
        }
  
        pp |= POWER_TARGET_ON;
        if (!IS_GEN5(dev))
                pp |= PANEL_POWER_RESET;
  
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
  
  
        if (IS_GEN5(dev)) {
                pp |= PANEL_POWER_RESET; /* restore panel reset bit */
-               I915_WRITE(PCH_PP_CONTROL, pp);
-               POSTING_READ(PCH_PP_CONTROL);
+               I915_WRITE(pp_ctrl_reg, pp);
+               POSTING_READ(pp_ctrl_reg);
        }
  }
  
@@@ -1164,7 -1225,7 +1225,7 @@@ void ironlake_edp_panel_off(struct inte
         * panels get very unhappy and cease to work. */
        pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
  
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+       pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
  
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
@@@ -1197,7 -1258,7 +1258,7 @@@ void ironlake_edp_backlight_on(struct i
        pp = ironlake_get_pp_control(intel_dp);
        pp |= EDP_BLC_ENABLE;
  
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+       pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
  
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
@@@ -1221,7 -1282,7 +1282,7 @@@ void ironlake_edp_backlight_off(struct 
        pp = ironlake_get_pp_control(intel_dp);
        pp &= ~EDP_BLC_ENABLE;
  
-       pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL;
+       pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
  
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
@@@ -1368,6 -1429,7 +1429,7 @@@ static void intel_dp_get_config(struct 
        struct drm_i915_private *dev_priv = dev->dev_private;
        enum port port = dp_to_dig_port(intel_dp)->port;
        struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
+       int dotclock;
  
        if ((port == PORT_A) || !HAS_PCH_CPT(dev)) {
                tmp = I915_READ(intel_dp->output_reg);
  
        pipe_config->adjusted_mode.flags |= flags;
  
-       if (dp_to_dig_port(intel_dp)->port == PORT_A) {
+       pipe_config->has_dp_encoder = true;
+       intel_dp_get_m_n(crtc, pipe_config);
+       if (port == PORT_A) {
                if ((I915_READ(DP_A) & DP_PLL_FREQ_MASK) == DP_PLL_FREQ_160MHZ)
                        pipe_config->port_clock = 162000;
                else
                        pipe_config->port_clock = 270000;
        }
  
 +      if (is_edp(intel_dp) && dev_priv->vbt.edp_bpp &&
 +          pipe_config->pipe_bpp > dev_priv->vbt.edp_bpp) {
 +              /*
 +               * This is a big fat ugly hack.
 +               *
 +               * Some machines in UEFI boot mode provide us a VBT that has 18
 +               * bpp and 1.62 GHz link bandwidth for eDP, which for reasons
 +               * unknown we fail to light up. Yet the same BIOS boots up with
 +               * 24 bpp and 2.7 GHz link. Use the same bpp as the BIOS uses as
 +               * max, not what it tells us to use.
 +               *
 +               * Note: This will still be broken if the eDP panel is not lit
 +               * up by the BIOS, and thus we can't get the mode at module
 +               * load.
 +               */
 +              DRM_DEBUG_KMS("pipe has %d bpp for eDP panel, overriding BIOS-provided max %d bpp\n",
 +                            pipe_config->pipe_bpp, dev_priv->vbt.edp_bpp);
 +              dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp;
 +      }
++
+       dotclock = intel_dotclock_calculate(pipe_config->port_clock,
+                                           &pipe_config->dp_m_n);
+       if (HAS_PCH_SPLIT(dev_priv->dev) && port != PORT_A)
+               ironlake_check_encoder_dotclock(pipe_config, dotclock);
+       pipe_config->adjusted_mode.crtc_clock = dotclock;
  }
  
- static bool is_edp_psr(struct intel_dp *intel_dp)
+ static bool is_edp_psr(struct drm_device *dev)
  {
-       return is_edp(intel_dp) &&
-               intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       return dev_priv->psr.sink_support;
  }
  
  static bool intel_edp_is_psr_enabled(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
  
-       if (!IS_HASWELL(dev))
+       if (!HAS_PSR(dev))
                return false;
  
-       return I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE;
+       return I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE;
  }
  
  static void intel_edp_psr_write_vsc(struct intel_dp *intel_dp,
@@@ -1486,8 -1541,8 +1561,8 @@@ static void intel_edp_psr_setup(struct 
        intel_edp_psr_write_vsc(intel_dp, &psr_vsc);
  
        /* Avoid continuous PSR exit by masking memup and hpd */
-       I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP |
+       I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP |
 -                 EDP_PSR_DEBUG_MASK_HPD);
 +                 EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
  
        intel_dp->psr_setup_done = true;
  }
@@@ -1511,9 -1566,9 +1586,9 @@@ static void intel_edp_psr_enable_sink(s
                                            DP_PSR_MAIN_LINK_ACTIVE);
  
        /* Setup AUX registers */
-       I915_WRITE(EDP_PSR_AUX_DATA1, EDP_PSR_DPCD_COMMAND);
-       I915_WRITE(EDP_PSR_AUX_DATA2, EDP_PSR_DPCD_NORMAL_OPERATION);
-       I915_WRITE(EDP_PSR_AUX_CTL,
+       I915_WRITE(EDP_PSR_AUX_DATA1(dev), EDP_PSR_DPCD_COMMAND);
+       I915_WRITE(EDP_PSR_AUX_DATA2(dev), EDP_PSR_DPCD_NORMAL_OPERATION);
+       I915_WRITE(EDP_PSR_AUX_CTL(dev),
                   DP_AUX_CH_CTL_TIME_OUT_400us |
                   (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) |
                   (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) |
@@@ -1536,7 -1591,7 +1611,7 @@@ static void intel_edp_psr_enable_source
        } else
                val |= EDP_PSR_LINK_DISABLE;
  
-       I915_WRITE(EDP_PSR_CTL, val |
+       I915_WRITE(EDP_PSR_CTL(dev), val |
                   EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES |
                   max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT |
                   idle_frames << EDP_PSR_IDLE_FRAME_SHIFT |
@@@ -1553,42 -1608,33 +1628,33 @@@ static bool intel_edp_psr_match_conditi
        struct drm_i915_gem_object *obj = to_intel_framebuffer(crtc->fb)->obj;
        struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base;
  
-       if (!IS_HASWELL(dev)) {
+       dev_priv->psr.source_ok = false;
+       if (!HAS_PSR(dev)) {
                DRM_DEBUG_KMS("PSR not supported on this platform\n");
-               dev_priv->no_psr_reason = PSR_NO_SOURCE;
                return false;
        }
  
        if ((intel_encoder->type != INTEL_OUTPUT_EDP) ||
            (dig_port->port != PORT_A)) {
                DRM_DEBUG_KMS("HSW ties PSR to DDI A (eDP)\n");
-               dev_priv->no_psr_reason = PSR_HSW_NOT_DDIA;
-               return false;
-       }
-       if (!is_edp_psr(intel_dp)) {
-               DRM_DEBUG_KMS("PSR not supported by this panel\n");
-               dev_priv->no_psr_reason = PSR_NO_SINK;
                return false;
        }
  
        if (!i915_enable_psr) {
                DRM_DEBUG_KMS("PSR disable by flag\n");
-               dev_priv->no_psr_reason = PSR_MODULE_PARAM;
                return false;
        }
  
        crtc = dig_port->base.base.crtc;
        if (crtc == NULL) {
                DRM_DEBUG_KMS("crtc not active for PSR\n");
-               dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE;
                return false;
        }
  
        intel_crtc = to_intel_crtc(crtc);
-       if (!intel_crtc->active || !crtc->fb || !crtc->mode.clock) {
+       if (!intel_crtc_active(crtc)) {
                DRM_DEBUG_KMS("crtc not active for PSR\n");
-               dev_priv->no_psr_reason = PSR_CRTC_NOT_ACTIVE;
                return false;
        }
  
        if (obj->tiling_mode != I915_TILING_X ||
            obj->fence_reg == I915_FENCE_REG_NONE) {
                DRM_DEBUG_KMS("PSR condition failed: fb not tiled or fenced\n");
-               dev_priv->no_psr_reason = PSR_NOT_TILED;
                return false;
        }
  
        if (I915_READ(SPRCTL(intel_crtc->pipe)) & SPRITE_ENABLE) {
                DRM_DEBUG_KMS("PSR condition failed: Sprite is Enabled\n");
-               dev_priv->no_psr_reason = PSR_SPRITE_ENABLED;
                return false;
        }
  
        if (I915_READ(HSW_STEREO_3D_CTL(intel_crtc->config.cpu_transcoder)) &
            S3D_ENABLE) {
                DRM_DEBUG_KMS("PSR condition failed: Stereo 3D is Enabled\n");
-               dev_priv->no_psr_reason = PSR_S3D_ENABLED;
                return false;
        }
  
-       if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) {
+       if (intel_crtc->config.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE) {
                DRM_DEBUG_KMS("PSR condition failed: Interlaced is Enabled\n");
-               dev_priv->no_psr_reason = PSR_INTERLACED_ENABLED;
                return false;
        }
  
+       dev_priv->psr.source_ok = true;
        return true;
  }
  
@@@ -1657,10 -1700,11 +1720,11 @@@ void intel_edp_psr_disable(struct intel
        if (!intel_edp_is_psr_enabled(dev))
                return;
  
-       I915_WRITE(EDP_PSR_CTL, I915_READ(EDP_PSR_CTL) & ~EDP_PSR_ENABLE);
+       I915_WRITE(EDP_PSR_CTL(dev),
+                  I915_READ(EDP_PSR_CTL(dev)) & ~EDP_PSR_ENABLE);
  
        /* Wait till PSR is idle */
-       if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL) &
+       if (_wait_for((I915_READ(EDP_PSR_STATUS_CTL(dev)) &
                       EDP_PSR_STATUS_STATE_MASK) == 0, 2000, 10))
                DRM_ERROR("Timed out waiting for PSR Idle State\n");
  }
@@@ -1674,7 -1718,7 +1738,7 @@@ void intel_edp_psr_update(struct drm_de
                if (encoder->type == INTEL_OUTPUT_EDP) {
                        intel_dp = enc_to_intel_dp(&encoder->base);
  
-                       if (!is_edp_psr(intel_dp))
+                       if (!is_edp_psr(dev))
                                return;
  
                        if (!intel_edp_psr_match_conditions(intel_dp))
@@@ -1733,14 -1777,24 +1797,24 @@@ static void intel_enable_dp(struct inte
        ironlake_edp_panel_vdd_off(intel_dp, true);
        intel_dp_complete_link_train(intel_dp);
        intel_dp_stop_link_train(intel_dp);
+ }
+ static void g4x_enable_dp(struct intel_encoder *encoder)
+ {
+       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+       intel_enable_dp(encoder);
        ironlake_edp_backlight_on(intel_dp);
  }
  
  static void vlv_enable_dp(struct intel_encoder *encoder)
  {
+       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+       ironlake_edp_backlight_on(intel_dp);
  }
  
- static void intel_pre_enable_dp(struct intel_encoder *encoder)
+ static void g4x_pre_enable_dp(struct intel_encoder *encoder)
  {
        struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
        struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
@@@ -1758,53 -1812,59 +1832,59 @@@ static void vlv_pre_enable_dp(struct in
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
        int port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
+       struct edp_power_seq power_seq;
        u32 val;
  
        mutex_lock(&dev_priv->dpio_lock);
  
-       val = vlv_dpio_read(dev_priv, DPIO_DATA_LANE_A(port));
+       val = vlv_dpio_read(dev_priv, pipe, DPIO_DATA_LANE_A(port));
        val = 0;
        if (pipe)
                val |= (1<<21);
        else
                val &= ~(1<<21);
        val |= 0x001000c4;
-       vlv_dpio_write(dev_priv, DPIO_DATA_CHANNEL(port), val);
-       vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(port), 0x00760018);
-       vlv_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(port), 0x00400888);
+       vlv_dpio_write(dev_priv, pipe, DPIO_DATA_CHANNEL(port), val);
+       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF0(port), 0x00760018);
+       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF8(port), 0x00400888);
  
        mutex_unlock(&dev_priv->dpio_lock);
  
+       /* init power sequencer on this pipe and port */
+       intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);
+       intel_dp_init_panel_power_sequencer_registers(dev, intel_dp,
+                                                     &power_seq);
        intel_enable_dp(encoder);
  
        vlv_wait_port_ready(dev_priv, port);
  }
  
- static void intel_dp_pre_pll_enable(struct intel_encoder *encoder)
+ static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
  {
        struct intel_digital_port *dport = enc_to_dig_port(&encoder->base);
        struct drm_device *dev = encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_crtc *intel_crtc =
+               to_intel_crtc(encoder->base.crtc);
        int port = vlv_dport_to_channel(dport);
-       if (!IS_VALLEYVIEW(dev))
-               return;
+       int pipe = intel_crtc->pipe;
  
        /* Program Tx lane resets to default */
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, DPIO_PCS_TX(port),
+       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
                         DPIO_PCS_TX_LANE2_RESET |
                         DPIO_PCS_TX_LANE1_RESET);
-       vlv_dpio_write(dev_priv, DPIO_PCS_CLK(port),
+       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
                         DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
                         DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
                         (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
                                 DPIO_PCS_CLK_SOFT_RESET);
  
        /* Fix up inter-pair skew failure */
-       vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER1(port), 0x00750f00);
-       vlv_dpio_write(dev_priv, DPIO_TX_CTL(port), 0x00001500);
-       vlv_dpio_write(dev_priv, DPIO_TX_LANE(port), 0x40400000);
+       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
+       vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
+       vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);
        mutex_unlock(&dev_priv->dpio_lock);
  }
  
@@@ -1939,10 -1999,13 +2019,13 @@@ static uint32_t intel_vlv_signal_levels
        struct drm_device *dev = intel_dp_to_dev(intel_dp);
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_digital_port *dport = dp_to_dig_port(intel_dp);
+       struct intel_crtc *intel_crtc =
+               to_intel_crtc(dport->base.base.crtc);
        unsigned long demph_reg_value, preemph_reg_value,
                uniqtranscale_reg_value;
        uint8_t train_set = intel_dp->train_set[0];
        int port = vlv_dport_to_channel(dport);
+       int pipe = intel_crtc->pipe;
  
        switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
        case DP_TRAIN_PRE_EMPHASIS_0:
        }
  
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x00000000);
-       vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(port), demph_reg_value);
-       vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(port),
+       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x00000000);
+       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL4(port), demph_reg_value);
+       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL2(port),
                         uniqtranscale_reg_value);
-       vlv_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(port), 0x0C782040);
-       vlv_dpio_write(dev_priv, DPIO_PCS_STAGGER0(port), 0x00030000);
-       vlv_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
-       vlv_dpio_write(dev_priv, DPIO_TX_OCALINIT(port), 0x80000000);
+       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL3(port), 0x0C782040);
+       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER0(port), 0x00030000);
+       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
+       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x80000000);
        mutex_unlock(&dev_priv->dpio_lock);
  
        return 0;
@@@ -2227,7 -2290,7 +2310,7 @@@ intel_dp_set_signal_levels(struct intel
  
  static bool
  intel_dp_set_link_train(struct intel_dp *intel_dp,
-                       uint32_t dp_reg_value,
+                       uint32_t *DP,
                        uint8_t dp_train_pat)
  {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
                I915_WRITE(DP_TP_CTL(port), temp);
  
        } else if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) {
-               dp_reg_value &= ~DP_LINK_TRAIN_MASK_CPT;
+               *DP &= ~DP_LINK_TRAIN_MASK_CPT;
  
                switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
                case DP_TRAINING_PATTERN_DISABLE:
-                       dp_reg_value |= DP_LINK_TRAIN_OFF_CPT;
+                       *DP |= DP_LINK_TRAIN_OFF_CPT;
                        break;
                case DP_TRAINING_PATTERN_1:
-                       dp_reg_value |= DP_LINK_TRAIN_PAT_1_CPT;
+                       *DP |= DP_LINK_TRAIN_PAT_1_CPT;
                        break;
                case DP_TRAINING_PATTERN_2:
-                       dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
+                       *DP |= DP_LINK_TRAIN_PAT_2_CPT;
                        break;
                case DP_TRAINING_PATTERN_3:
                        DRM_ERROR("DP training pattern 3 not supported\n");
-                       dp_reg_value |= DP_LINK_TRAIN_PAT_2_CPT;
+                       *DP |= DP_LINK_TRAIN_PAT_2_CPT;
                        break;
                }
  
        } else {
-               dp_reg_value &= ~DP_LINK_TRAIN_MASK;
+               *DP &= ~DP_LINK_TRAIN_MASK;
  
                switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) {
                case DP_TRAINING_PATTERN_DISABLE:
-                       dp_reg_value |= DP_LINK_TRAIN_OFF;
+                       *DP |= DP_LINK_TRAIN_OFF;
                        break;
                case DP_TRAINING_PATTERN_1:
-                       dp_reg_value |= DP_LINK_TRAIN_PAT_1;
+                       *DP |= DP_LINK_TRAIN_PAT_1;
                        break;
                case DP_TRAINING_PATTERN_2:
-                       dp_reg_value |= DP_LINK_TRAIN_PAT_2;
+                       *DP |= DP_LINK_TRAIN_PAT_2;
                        break;
                case DP_TRAINING_PATTERN_3:
                        DRM_ERROR("DP training pattern 3 not supported\n");
-                       dp_reg_value |= DP_LINK_TRAIN_PAT_2;
+                       *DP |= DP_LINK_TRAIN_PAT_2;
                        break;
                }
        }
  
-       I915_WRITE(intel_dp->output_reg, dp_reg_value);
+       I915_WRITE(intel_dp->output_reg, *DP);
        POSTING_READ(intel_dp->output_reg);
  
-       intel_dp_aux_native_write_1(intel_dp,
-                                   DP_TRAINING_PATTERN_SET,
-                                   dp_train_pat);
+       ret = intel_dp_aux_native_write_1(intel_dp, DP_TRAINING_PATTERN_SET,
+                                         dp_train_pat);
+       if (ret != 1)
+               return false;
  
        if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) !=
            DP_TRAINING_PATTERN_DISABLE) {
        return true;
  }
  
+ static bool
+ intel_dp_reset_link_train(struct intel_dp *intel_dp, uint32_t *DP,
+                       uint8_t dp_train_pat)
+ {
+       memset(intel_dp->train_set, 0, 4);
+       intel_dp_set_signal_levels(intel_dp, DP);
+       return intel_dp_set_link_train(intel_dp, DP, dp_train_pat);
+ }
+ static bool
+ intel_dp_update_link_train(struct intel_dp *intel_dp, uint32_t *DP,
+                          uint8_t link_status[DP_LINK_STATUS_SIZE])
+ {
+       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+       struct drm_device *dev = intel_dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       int ret;
+       intel_get_adjust_train(intel_dp, link_status);
+       intel_dp_set_signal_levels(intel_dp, DP);
+       I915_WRITE(intel_dp->output_reg, *DP);
+       POSTING_READ(intel_dp->output_reg);
+       ret = intel_dp_aux_native_write(intel_dp, DP_TRAINING_LANE0_SET,
+                                       intel_dp->train_set,
+                                       intel_dp->lane_count);
+       return ret == intel_dp->lane_count;
+ }
  static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp)
  {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
@@@ -2362,32 -2457,37 +2477,37 @@@ intel_dp_start_link_train(struct intel_
        uint8_t voltage;
        int voltage_tries, loop_tries;
        uint32_t DP = intel_dp->DP;
+       uint8_t link_config[2];
  
        if (HAS_DDI(dev))
                intel_ddi_prepare_link_retrain(encoder);
  
        /* Write the link configuration data */
-       intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
-                                 intel_dp->link_configuration,
-                                 DP_LINK_CONFIGURATION_SIZE);
+       link_config[0] = intel_dp->link_bw;
+       link_config[1] = intel_dp->lane_count;
+       if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
+               link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+       intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, link_config, 2);
+       link_config[0] = 0;
+       link_config[1] = DP_SET_ANSI_8B10B;
+       intel_dp_aux_native_write(intel_dp, DP_DOWNSPREAD_CTRL, link_config, 2);
  
        DP |= DP_PORT_EN;
  
-       memset(intel_dp->train_set, 0, 4);
+       /* clock recovery */
+       if (!intel_dp_reset_link_train(intel_dp, &DP,
+                                      DP_TRAINING_PATTERN_1 |
+                                      DP_LINK_SCRAMBLING_DISABLE)) {
+               DRM_ERROR("failed to enable link training\n");
+               return;
+       }
        voltage = 0xff;
        voltage_tries = 0;
        loop_tries = 0;
        for (;;) {
-               /* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
-               uint8_t     link_status[DP_LINK_STATUS_SIZE];
-               intel_dp_set_signal_levels(intel_dp, &DP);
-               /* Set training pattern 1 */
-               if (!intel_dp_set_link_train(intel_dp, DP,
-                                            DP_TRAINING_PATTERN_1 |
-                                            DP_LINK_SCRAMBLING_DISABLE))
-                       break;
+               uint8_t link_status[DP_LINK_STATUS_SIZE];
  
                drm_dp_link_train_clock_recovery_delay(intel_dp->dpcd);
                if (!intel_dp_get_link_status(intel_dp, link_status)) {
                                DRM_DEBUG_KMS("too many full retries, give up\n");
                                break;
                        }
-                       memset(intel_dp->train_set, 0, 4);
+                       intel_dp_reset_link_train(intel_dp, &DP,
+                                                 DP_TRAINING_PATTERN_1 |
+                                                 DP_LINK_SCRAMBLING_DISABLE);
                        voltage_tries = 0;
                        continue;
                }
                        voltage_tries = 0;
                voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
  
-               /* Compute new intel_dp->train_set as requested by target */
-               intel_get_adjust_train(intel_dp, link_status);
+               /* Update training set as requested by target */
+               if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
+                       DRM_ERROR("failed to update link training\n");
+                       break;
+               }
        }
  
        intel_dp->DP = DP;
@@@ -2441,11 -2546,18 +2566,18 @@@ intel_dp_complete_link_train(struct int
        uint32_t DP = intel_dp->DP;
  
        /* channel equalization */
+       if (!intel_dp_set_link_train(intel_dp, &DP,
+                                    DP_TRAINING_PATTERN_2 |
+                                    DP_LINK_SCRAMBLING_DISABLE)) {
+               DRM_ERROR("failed to start channel equalization\n");
+               return;
+       }
        tries = 0;
        cr_tries = 0;
        channel_eq = false;
        for (;;) {
-               uint8_t     link_status[DP_LINK_STATUS_SIZE];
+               uint8_t link_status[DP_LINK_STATUS_SIZE];
  
                if (cr_tries > 5) {
                        DRM_ERROR("failed to train DP, aborting\n");
                        break;
                }
  
-               intel_dp_set_signal_levels(intel_dp, &DP);
-               /* channel eq pattern */
-               if (!intel_dp_set_link_train(intel_dp, DP,
-                                            DP_TRAINING_PATTERN_2 |
-                                            DP_LINK_SCRAMBLING_DISABLE))
-                       break;
                drm_dp_link_train_channel_eq_delay(intel_dp->dpcd);
-               if (!intel_dp_get_link_status(intel_dp, link_status))
+               if (!intel_dp_get_link_status(intel_dp, link_status)) {
+                       DRM_ERROR("failed to get link status\n");
                        break;
+               }
  
                /* Make sure clock is still ok */
                if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) {
                        intel_dp_start_link_train(intel_dp);
+                       intel_dp_set_link_train(intel_dp, &DP,
+                                               DP_TRAINING_PATTERN_2 |
+                                               DP_LINK_SCRAMBLING_DISABLE);
                        cr_tries++;
                        continue;
                }
                if (tries > 5) {
                        intel_dp_link_down(intel_dp);
                        intel_dp_start_link_train(intel_dp);
+                       intel_dp_set_link_train(intel_dp, &DP,
+                                               DP_TRAINING_PATTERN_2 |
+                                               DP_LINK_SCRAMBLING_DISABLE);
                        tries = 0;
                        cr_tries++;
                        continue;
                }
  
-               /* Compute new intel_dp->train_set as requested by target */
-               intel_get_adjust_train(intel_dp, link_status);
+               /* Update training set as requested by target */
+               if (!intel_dp_update_link_train(intel_dp, &DP, link_status)) {
+                       DRM_ERROR("failed to update link training\n");
+                       break;
+               }
                ++tries;
        }
  
  
  void intel_dp_stop_link_train(struct intel_dp *intel_dp)
  {
-       intel_dp_set_link_train(intel_dp, intel_dp->DP,
+       intel_dp_set_link_train(intel_dp, &intel_dp->DP,
                                DP_TRAINING_PATTERN_DISABLE);
  }
  
@@@ -2589,6 -2704,10 +2724,10 @@@ intel_dp_link_down(struct intel_dp *int
  static bool
  intel_dp_get_dpcd(struct intel_dp *intel_dp)
  {
+       struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
+       struct drm_device *dev = dig_port->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        char dpcd_hex_dump[sizeof(intel_dp->dpcd) * 3];
  
        if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd,
  
        /* Check if the panel supports PSR */
        memset(intel_dp->psr_dpcd, 0, sizeof(intel_dp->psr_dpcd));
-       intel_dp_aux_native_read_retry(intel_dp, DP_PSR_SUPPORT,
-                                      intel_dp->psr_dpcd,
-                                      sizeof(intel_dp->psr_dpcd));
-       if (is_edp_psr(intel_dp))
-               DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
+       if (is_edp(intel_dp)) {
+               intel_dp_aux_native_read_retry(intel_dp, DP_PSR_SUPPORT,
+                                              intel_dp->psr_dpcd,
+                                              sizeof(intel_dp->psr_dpcd));
+               if (intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED) {
+                       dev_priv->psr.sink_support = true;
+                       DRM_DEBUG_KMS("Detected EDP PSR Panel.\n");
+               }
+       }
        if (!(intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
              DP_DWN_STRM_PORT_PRESENT))
                return true; /* native DP sink */
@@@ -2728,7 -2852,6 +2872,6 @@@ static enum drm_connector_statu
  intel_dp_detect_dpcd(struct intel_dp *intel_dp)
  {
        uint8_t *dpcd = intel_dp->dpcd;
-       bool hpd;
        uint8_t type;
  
        if (!intel_dp_get_dpcd(intel_dp))
                return connector_status_connected;
  
        /* If we're HPD-aware, SINK_COUNT changes dynamically */
-       hpd = !!(intel_dp->downstream_ports[0] & DP_DS_PORT_HPD);
-       if (hpd) {
+       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 &&
+           intel_dp->downstream_ports[0] & DP_DS_PORT_HPD) {
                uint8_t reg;
                if (!intel_dp_aux_native_read_retry(intel_dp, DP_SINK_COUNT,
                                                    &reg, 1))
                return connector_status_connected;
  
        /* Well we tried, say unknown for unreliable port types */
-       type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
-       if (type == DP_DS_PORT_TYPE_VGA || type == DP_DS_PORT_TYPE_NON_EDID)
-               return connector_status_unknown;
+       if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) {
+               type = intel_dp->downstream_ports[0] & DP_DS_PORT_TYPE_MASK;
+               if (type == DP_DS_PORT_TYPE_VGA ||
+                   type == DP_DS_PORT_TYPE_NON_EDID)
+                       return connector_status_unknown;
+       } else {
+               type = intel_dp->dpcd[DP_DOWNSTREAMPORT_PRESENT] &
+                       DP_DWN_STRM_PORT_TYPE_MASK;
+               if (type == DP_DWN_STRM_PORT_TYPE_ANALOG ||
+                   type == DP_DWN_STRM_PORT_TYPE_OTHER)
+                       return connector_status_unknown;
+       }
  
        /* Anything else is out of spec, warn and ignore */
        DRM_DEBUG_KMS("Broken DP branch device, ignoring\n");
@@@ -2830,19 -2962,11 +2982,11 @@@ intel_dp_get_edid(struct drm_connector 
  
        /* use cached edid if we have one */
        if (intel_connector->edid) {
-               struct edid *edid;
-               int size;
                /* invalid edid */
                if (IS_ERR(intel_connector->edid))
                        return NULL;
  
-               size = (intel_connector->edid->extensions + 1) * EDID_LENGTH;
-               edid = kmemdup(intel_connector->edid, size, GFP_KERNEL);
-               if (!edid)
-                       return NULL;
-               return edid;
+               return drm_edid_duplicate(intel_connector->edid);
        }
  
        return drm_get_edid(connector, adapter);
@@@ -3050,7 -3174,6 +3194,6 @@@ intel_dp_connector_destroy(struct drm_c
        if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
                intel_panel_fini(&intel_connector->panel);
  
-       drm_sysfs_connector_remove(connector);
        drm_connector_cleanup(connector);
        kfree(connector);
  }
@@@ -3121,7 -3244,7 +3264,7 @@@ intel_trans_dp_port_sel(struct drm_crt
  bool intel_dpd_is_edp(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct child_device_config *p_child;
+       union child_device_config *p_child;
        int i;
  
        if (!dev_priv->vbt.child_dev_num)
        for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
                p_child = dev_priv->vbt.child_dev + i;
  
-               if (p_child->dvo_port == PORT_IDPD &&
-                   p_child->device_type == DEVICE_TYPE_eDP)
+               if (p_child->common.dvo_port == PORT_IDPD &&
+                   p_child->common.device_type == DEVICE_TYPE_eDP)
                        return true;
        }
        return false;
@@@ -3164,24 -3287,26 +3307,26 @@@ intel_dp_init_panel_power_sequencer(str
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct edp_power_seq cur, vbt, spec, final;
        u32 pp_on, pp_off, pp_div, pp;
-       int pp_control_reg, pp_on_reg, pp_off_reg, pp_div_reg;
+       int pp_ctrl_reg, pp_on_reg, pp_off_reg, pp_div_reg;
  
        if (HAS_PCH_SPLIT(dev)) {
-               pp_control_reg = PCH_PP_CONTROL;
+               pp_ctrl_reg = PCH_PP_CONTROL;
                pp_on_reg = PCH_PP_ON_DELAYS;
                pp_off_reg = PCH_PP_OFF_DELAYS;
                pp_div_reg = PCH_PP_DIVISOR;
        } else {
-               pp_control_reg = PIPEA_PP_CONTROL;
-               pp_on_reg = PIPEA_PP_ON_DELAYS;
-               pp_off_reg = PIPEA_PP_OFF_DELAYS;
-               pp_div_reg = PIPEA_PP_DIVISOR;
+               enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+               pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe);
+               pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
+               pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
+               pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
        }
  
        /* Workaround: Need to write PP_CONTROL with the unlock key as
         * the very first thing. */
        pp = ironlake_get_pp_control(intel_dp);
-       I915_WRITE(pp_control_reg, pp);
+       I915_WRITE(pp_ctrl_reg, pp);
  
        pp_on = I915_READ(pp_on_reg);
        pp_off = I915_READ(pp_off_reg);
@@@ -3269,9 -3394,11 +3414,11 @@@ intel_dp_init_panel_power_sequencer_reg
                pp_off_reg = PCH_PP_OFF_DELAYS;
                pp_div_reg = PCH_PP_DIVISOR;
        } else {
-               pp_on_reg = PIPEA_PP_ON_DELAYS;
-               pp_off_reg = PIPEA_PP_OFF_DELAYS;
-               pp_div_reg = PIPEA_PP_DIVISOR;
+               enum pipe pipe = vlv_power_sequencer_pipe(intel_dp);
+               pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
+               pp_off_reg = VLV_PIPE_PP_OFF_DELAYS(pipe);
+               pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe);
        }
  
        /* And finally store the new values in the power sequencer. */
        /* Haswell doesn't have any port selection bits for the panel
         * power sequencer any more. */
        if (IS_VALLEYVIEW(dev)) {
-               port_sel = I915_READ(pp_on_reg) & 0xc0000000;
+               if (dp_to_dig_port(intel_dp)->port == PORT_B)
+                       port_sel = PANEL_PORT_SELECT_DPB_VLV;
+               else
+                       port_sel = PANEL_PORT_SELECT_DPC_VLV;
        } else if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
                if (dp_to_dig_port(intel_dp)->port == PORT_A)
-                       port_sel = PANEL_POWER_PORT_DP_A;
+                       port_sel = PANEL_PORT_SELECT_DPA;
                else
-                       port_sel = PANEL_POWER_PORT_DP_D;
+                       port_sel = PANEL_PORT_SELECT_DPD;
        }
  
        pp_on |= port_sel;
@@@ -3536,11 -3666,11 +3686,11 @@@ intel_dp_init(struct drm_device *dev, i
        struct drm_encoder *encoder;
        struct intel_connector *intel_connector;
  
-       intel_dig_port = kzalloc(sizeof(struct intel_digital_port), GFP_KERNEL);
+       intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
        if (!intel_dig_port)
                return;
  
-       intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
+       intel_connector = kzalloc(sizeof(*intel_connector), GFP_KERNEL);
        if (!intel_connector) {
                kfree(intel_dig_port);
                return;
        intel_encoder->get_hw_state = intel_dp_get_hw_state;
        intel_encoder->get_config = intel_dp_get_config;
        if (IS_VALLEYVIEW(dev)) {
-               intel_encoder->pre_pll_enable = intel_dp_pre_pll_enable;
+               intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable;
                intel_encoder->pre_enable = vlv_pre_enable_dp;
                intel_encoder->enable = vlv_enable_dp;
        } else {
-               intel_encoder->pre_enable = intel_pre_enable_dp;
-               intel_encoder->enable = intel_enable_dp;
+               intel_encoder->pre_enable = g4x_pre_enable_dp;
+               intel_encoder->enable = g4x_enable_dp;
        }
  
        intel_dig_port->port = port;
index 26c2ea3e985c22d7011e68f3e73d14fa8e896131,008ec0bb017fb479c58dc4ae39ac920c351e1669..8f57394d6f996ae6a821cc8a4c8bf07a7496f388
   * i915.i915_enable_fbc parameter
   */
  
- static bool intel_crtc_active(struct drm_crtc *crtc)
- {
-       /* Be paranoid as we can arrive here with only partial
-        * state retrieved from the hardware during setup.
-        */
-       return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock;
- }
  static void i8xx_disable_fbc(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@@ -378,7 -370,7 +370,7 @@@ static void intel_enable_fbc(struct drm
  
        intel_cancel_fbc_work(dev_priv);
  
-       work = kzalloc(sizeof *work, GFP_KERNEL);
+       work = kzalloc(sizeof(*work), GFP_KERNEL);
        if (work == NULL) {
                DRM_ERROR("Failed to allocate FBC work structure\n");
                dev_priv->display.enable_fbc(crtc, interval);
@@@ -458,7 -450,8 +450,8 @@@ void intel_update_fbc(struct drm_devic
        struct drm_framebuffer *fb;
        struct intel_framebuffer *intel_fb;
        struct drm_i915_gem_object *obj;
-       unsigned int max_hdisplay, max_vdisplay;
+       const struct drm_display_mode *adjusted_mode;
+       unsigned int max_width, max_height;
  
        if (!I915_HAS_FBC(dev)) {
                set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED);
        fb = crtc->fb;
        intel_fb = to_intel_framebuffer(fb);
        obj = intel_fb->obj;
+       adjusted_mode = &intel_crtc->config.adjusted_mode;
  
        if (i915_enable_fbc < 0 &&
            INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) {
                        DRM_DEBUG_KMS("fbc disabled per module param\n");
                goto out_disable;
        }
-       if ((crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) ||
-           (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)) {
+       if ((adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) ||
+           (adjusted_mode->flags & DRM_MODE_FLAG_DBLSCAN)) {
                if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
                        DRM_DEBUG_KMS("mode incompatible with compression, "
                                      "disabling\n");
        }
  
        if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) {
-               max_hdisplay = 4096;
-               max_vdisplay = 2048;
+               max_width = 4096;
+               max_height = 2048;
        } else {
-               max_hdisplay = 2048;
-               max_vdisplay = 1536;
+               max_width = 2048;
+               max_height = 1536;
        }
-       if ((crtc->mode.hdisplay > max_hdisplay) ||
-           (crtc->mode.vdisplay > max_vdisplay)) {
+       if (intel_crtc->config.pipe_src_w > max_width ||
+           intel_crtc->config.pipe_src_h > max_height) {
                if (set_no_fbc_reason(dev_priv, FBC_MODE_TOO_LARGE))
                        DRM_DEBUG_KMS("mode too large for compression, disabling\n");
                goto out_disable;
@@@ -1087,8 -1081,9 +1081,9 @@@ static struct drm_crtc *single_enabled_
        return enabled;
  }
  
- static void pineview_update_wm(struct drm_device *dev)
+ static void pineview_update_wm(struct drm_crtc *unused_crtc)
  {
+       struct drm_device *dev = unused_crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc;
        const struct cxsr_latency *latency;
  
        crtc = single_enabled_crtc(dev);
        if (crtc) {
-               int clock = crtc->mode.clock;
+               const struct drm_display_mode *adjusted_mode;
                int pixel_size = crtc->fb->bits_per_pixel / 8;
+               int clock;
+               adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+               clock = adjusted_mode->crtc_clock;
  
                /* Display SR */
                wm = intel_calculate_wm(clock, &pineview_display_wm,
@@@ -1166,6 -1165,7 +1165,7 @@@ static bool g4x_compute_wm0(struct drm_
                            int *cursor_wm)
  {
        struct drm_crtc *crtc;
+       const struct drm_display_mode *adjusted_mode;
        int htotal, hdisplay, clock, pixel_size;
        int line_time_us, line_count;
        int entries, tlb_miss;
                return false;
        }
  
-       htotal = crtc->mode.htotal;
-       hdisplay = crtc->mode.hdisplay;
-       clock = crtc->mode.clock;
+       adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+       clock = adjusted_mode->crtc_clock;
+       htotal = adjusted_mode->htotal;
+       hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
        pixel_size = crtc->fb->bits_per_pixel / 8;
  
        /* Use the small buffer method to calculate plane watermark */
@@@ -1250,6 -1251,7 +1251,7 @@@ static bool g4x_compute_srwm(struct drm
                             int *display_wm, int *cursor_wm)
  {
        struct drm_crtc *crtc;
+       const struct drm_display_mode *adjusted_mode;
        int hdisplay, htotal, pixel_size, clock;
        unsigned long line_time_us;
        int line_count, line_size;
        }
  
        crtc = intel_get_crtc_for_plane(dev, plane);
-       hdisplay = crtc->mode.hdisplay;
-       htotal = crtc->mode.htotal;
-       clock = crtc->mode.clock;
+       adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+       clock = adjusted_mode->crtc_clock;
+       htotal = adjusted_mode->htotal;
+       hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
        pixel_size = crtc->fb->bits_per_pixel / 8;
  
        line_time_us = (htotal * 1000) / clock;
@@@ -1303,7 -1306,7 +1306,7 @@@ static bool vlv_compute_drain_latency(s
        if (!intel_crtc_active(crtc))
                return false;
  
-       clock = crtc->mode.clock;       /* VESA DOT Clock */
+       clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
        pixel_size = crtc->fb->bits_per_pixel / 8;      /* BPP */
  
        entries = (clock / 1000) * pixel_size;
@@@ -1365,8 -1368,9 +1368,9 @@@ static void vlv_update_drain_latency(st
  
  #define single_plane_enabled(mask) is_power_of_2(mask)
  
- static void valleyview_update_wm(struct drm_device *dev)
+ static void valleyview_update_wm(struct drm_crtc *crtc)
  {
+       struct drm_device *dev = crtc->dev;
        static const int sr_latency_ns = 12000;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
                   (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
  }
  
- static void g4x_update_wm(struct drm_device *dev)
+ static void g4x_update_wm(struct drm_crtc *crtc)
  {
+       struct drm_device *dev = crtc->dev;
        static const int sr_latency_ns = 12000;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
                   (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
  }
  
- static void i965_update_wm(struct drm_device *dev)
+ static void i965_update_wm(struct drm_crtc *unused_crtc)
  {
+       struct drm_device *dev = unused_crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc;
        int srwm = 1;
        if (crtc) {
                /* self-refresh has much higher latency */
                static const int sr_latency_ns = 12000;
-               int clock = crtc->mode.clock;
-               int htotal = crtc->mode.htotal;
-               int hdisplay = crtc->mode.hdisplay;
+               const struct drm_display_mode *adjusted_mode =
+                       &to_intel_crtc(crtc)->config.adjusted_mode;
+               int clock = adjusted_mode->crtc_clock;
+               int htotal = adjusted_mode->htotal;
+               int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
                int pixel_size = crtc->fb->bits_per_pixel / 8;
                unsigned long line_time_us;
                int entries;
        I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT));
  }
  
- static void i9xx_update_wm(struct drm_device *dev)
+ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
  {
+       struct drm_device *dev = unused_crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        const struct intel_watermark_params *wm_info;
        uint32_t fwater_lo;
        fifo_size = dev_priv->display.get_fifo_size(dev, 0);
        crtc = intel_get_crtc_for_plane(dev, 0);
        if (intel_crtc_active(crtc)) {
+               const struct drm_display_mode *adjusted_mode;
                int cpp = crtc->fb->bits_per_pixel / 8;
                if (IS_GEN2(dev))
                        cpp = 4;
  
-               planea_wm = intel_calculate_wm(crtc->mode.clock,
+               adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+               planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
                                               wm_info, fifo_size, cpp,
                                               latency_ns);
                enabled = crtc;
        fifo_size = dev_priv->display.get_fifo_size(dev, 1);
        crtc = intel_get_crtc_for_plane(dev, 1);
        if (intel_crtc_active(crtc)) {
+               const struct drm_display_mode *adjusted_mode;
                int cpp = crtc->fb->bits_per_pixel / 8;
                if (IS_GEN2(dev))
                        cpp = 4;
  
-               planeb_wm = intel_calculate_wm(crtc->mode.clock,
+               adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+               planeb_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
                                               wm_info, fifo_size, cpp,
                                               latency_ns);
                if (enabled == NULL)
        if (HAS_FW_BLC(dev) && enabled) {
                /* self-refresh has much higher latency */
                static const int sr_latency_ns = 6000;
-               int clock = enabled->mode.clock;
-               int htotal = enabled->mode.htotal;
-               int hdisplay = enabled->mode.hdisplay;
+               const struct drm_display_mode *adjusted_mode =
+                       &to_intel_crtc(enabled)->config.adjusted_mode;
+               int clock = adjusted_mode->crtc_clock;
+               int htotal = adjusted_mode->htotal;
+               int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
                int pixel_size = enabled->fb->bits_per_pixel / 8;
                unsigned long line_time_us;
                int entries;
        }
  }
  
- static void i830_update_wm(struct drm_device *dev)
+ static void i830_update_wm(struct drm_crtc *unused_crtc)
  {
+       struct drm_device *dev = unused_crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_crtc *crtc;
+       const struct drm_display_mode *adjusted_mode;
        uint32_t fwater_lo;
        int planea_wm;
  
        if (crtc == NULL)
                return;
  
-       planea_wm = intel_calculate_wm(crtc->mode.clock, &i830_wm_info,
+       adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+       planea_wm = intel_calculate_wm(adjusted_mode->crtc_clock,
+                                      &i830_wm_info,
                                       dev_priv->display.get_fifo_size(dev, 0),
                                       4, latency_ns);
        fwater_lo = I915_READ(FW_BLC) & ~0xfff;
@@@ -1741,6 -1760,7 +1760,7 @@@ static bool ironlake_compute_srwm(struc
                                  int *fbc_wm, int *display_wm, int *cursor_wm)
  {
        struct drm_crtc *crtc;
+       const struct drm_display_mode *adjusted_mode;
        unsigned long line_time_us;
        int hdisplay, htotal, pixel_size, clock;
        int line_count, line_size;
        }
  
        crtc = intel_get_crtc_for_plane(dev, plane);
-       hdisplay = crtc->mode.hdisplay;
-       htotal = crtc->mode.htotal;
-       clock = crtc->mode.clock;
+       adjusted_mode = &to_intel_crtc(crtc)->config.adjusted_mode;
+       clock = adjusted_mode->crtc_clock;
+       htotal = adjusted_mode->htotal;
+       hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
        pixel_size = crtc->fb->bits_per_pixel / 8;
  
        line_time_us = (htotal * 1000) / clock;
                                   display, cursor);
  }
  
- static void ironlake_update_wm(struct drm_device *dev)
+ static void ironlake_update_wm(struct drm_crtc *crtc)
  {
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int fbc_wm, plane_wm, cursor_wm;
        unsigned int enabled;
         */
  }
  
- static void sandybridge_update_wm(struct drm_device *dev)
+ static void sandybridge_update_wm(struct drm_crtc *crtc)
  {
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int latency = dev_priv->wm.pri_latency[0] * 100;        /* In unit 0.1us */
        u32 val;
                   cursor_wm);
  }
  
- static void ivybridge_update_wm(struct drm_device *dev)
+ static void ivybridge_update_wm(struct drm_crtc *crtc)
  {
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        int latency = dev_priv->wm.pri_latency[0] * 100;        /* In unit 0.1us */
        u32 val;
@@@ -2098,7 -2122,7 +2122,7 @@@ static uint32_t ilk_pipe_pixel_rate(str
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        uint32_t pixel_rate;
  
-       pixel_rate = intel_crtc->config.adjusted_mode.clock;
+       pixel_rate = intel_crtc->config.adjusted_mode.crtc_clock;
  
        /* We only use IF-ID interlacing. If we ever use PF-ID we'll need to
         * adjust the pixel_rate here. */
                uint64_t pipe_w, pipe_h, pfit_w, pfit_h;
                uint32_t pfit_size = intel_crtc->config.pch_pfit.size;
  
-               pipe_w = intel_crtc->config.requested_mode.hdisplay;
-               pipe_h = intel_crtc->config.requested_mode.vdisplay;
+               pipe_w = intel_crtc->config.pipe_src_w;
+               pipe_h = intel_crtc->config.pipe_src_h;
                pfit_w = (pfit_size >> 16) & 0xFFFF;
                pfit_h = pfit_size & 0xFFFF;
                if (pipe_w < pfit_w)
@@@ -2196,7 -2220,7 +2220,7 @@@ struct intel_wm_config 
   * For both WM_PIPE and WM_LP.
   * mem_value must be in 0.1us units.
   */
- static uint32_t ilk_compute_pri_wm(struct hsw_pipe_wm_parameters *params,
+ static uint32_t ilk_compute_pri_wm(const struct hsw_pipe_wm_parameters *params,
                                   uint32_t mem_value,
                                   bool is_lp)
  {
   * For both WM_PIPE and WM_LP.
   * mem_value must be in 0.1us units.
   */
- static uint32_t ilk_compute_spr_wm(struct hsw_pipe_wm_parameters *params,
+ static uint32_t ilk_compute_spr_wm(const struct hsw_pipe_wm_parameters *params,
                                   uint32_t mem_value)
  {
        uint32_t method1, method2;
   * For both WM_PIPE and WM_LP.
   * mem_value must be in 0.1us units.
   */
- static uint32_t ilk_compute_cur_wm(struct hsw_pipe_wm_parameters *params,
+ static uint32_t ilk_compute_cur_wm(const struct hsw_pipe_wm_parameters *params,
                                   uint32_t mem_value)
  {
        if (!params->active || !params->cur.enabled)
  }
  
  /* Only for WM_LP. */
- static uint32_t ilk_compute_fbc_wm(struct hsw_pipe_wm_parameters *params,
+ static uint32_t ilk_compute_fbc_wm(const struct hsw_pipe_wm_parameters *params,
                                   uint32_t pri_val)
  {
        if (!params->active || !params->pri.enabled)
@@@ -2413,7 -2437,7 +2437,7 @@@ static bool ilk_check_wm(int level
  
  static void ilk_compute_wm_level(struct drm_i915_private *dev_priv,
                                 int level,
-                                struct hsw_pipe_wm_parameters *p,
+                                const struct hsw_pipe_wm_parameters *p,
                                 struct intel_wm_level *result)
  {
        uint16_t pri_latency = dev_priv->wm.pri_latency[level];
  }
  
  static bool hsw_compute_lp_wm(struct drm_i915_private *dev_priv,
-                             int level, struct hsw_wm_maximums *max,
-                             struct hsw_pipe_wm_parameters *params,
+                             int level, const struct hsw_wm_maximums *max,
+                             const struct hsw_pipe_wm_parameters *params,
                              struct intel_wm_level *result)
  {
        enum pipe pipe;
        return ilk_check_wm(level, max, result);
  }
  
- static uint32_t hsw_compute_wm_pipe(struct drm_i915_private *dev_priv,
                                  enum pipe pipe,
-                                   struct hsw_pipe_wm_parameters *params)
static uint32_t hsw_compute_wm_pipe(struct drm_device *dev,
+                                   const struct hsw_pipe_wm_parameters *params)
  {
-       uint32_t pri_val, cur_val, spr_val;
-       /* WM0 latency values stored in 0.1us units */
-       uint16_t pri_latency = dev_priv->wm.pri_latency[0];
-       uint16_t spr_latency = dev_priv->wm.spr_latency[0];
-       uint16_t cur_latency = dev_priv->wm.cur_latency[0];
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct intel_wm_config config = {
+               .num_pipes_active = 1,
+               .sprites_enabled = params->spr.enabled,
+               .sprites_scaled = params->spr.scaled,
+       };
+       struct hsw_wm_maximums max;
+       struct intel_wm_level res;
+       if (!params->active)
+               return 0;
+       ilk_wm_max(dev, 0, &config, INTEL_DDB_PART_1_2, &max);
  
-       pri_val = ilk_compute_pri_wm(params, pri_latency, false);
-       spr_val = ilk_compute_spr_wm(params, spr_latency);
-       cur_val = ilk_compute_cur_wm(params, cur_latency);
+       ilk_compute_wm_level(dev_priv, 0, params, &res);
  
-       WARN(pri_val > 127,
-            "Primary WM error, mode not supported for pipe %c\n",
-            pipe_name(pipe));
-       WARN(spr_val > 127,
-            "Sprite WM error, mode not supported for pipe %c\n",
-            pipe_name(pipe));
-       WARN(cur_val > 63,
-            "Cursor WM error, mode not supported for pipe %c\n",
-            pipe_name(pipe));
+       ilk_check_wm(0, &max, &res);
  
-       return (pri_val << WM0_PIPE_PLANE_SHIFT) |
-              (spr_val << WM0_PIPE_SPRITE_SHIFT) |
-              cur_val;
+       return (res.pri_val << WM0_PIPE_PLANE_SHIFT) |
+              (res.spr_val << WM0_PIPE_SPRITE_SHIFT) |
+              res.cur_val;
  }
  
  static uint32_t
@@@ -2554,19 -2576,22 +2576,22 @@@ static void intel_fixup_cur_wm_latency(
                wm[3] *= 2;
  }
  
- static void intel_print_wm_latency(struct drm_device *dev,
-                                  const char *name,
-                                  const uint16_t wm[5])
+ static int ilk_wm_max_level(const struct drm_device *dev)
  {
-       int level, max_level;
        /* how many WM levels are we expecting */
        if (IS_HASWELL(dev))
-               max_level = 4;
+               return 4;
        else if (INTEL_INFO(dev)->gen >= 6)
-               max_level = 3;
+               return 3;
        else
-               max_level = 2;
+               return 2;
+ }
+ static void intel_print_wm_latency(struct drm_device *dev,
+                                  const char *name,
+                                  const uint16_t wm[5])
+ {
+       int level, max_level = ilk_wm_max_level(dev);
  
        for (level = 0; level <= max_level; level++) {
                unsigned int latency = wm[level];
@@@ -2633,8 -2658,7 +2658,7 @@@ static void hsw_compute_wm_parameters(s
                p->pixel_rate = ilk_pipe_pixel_rate(dev, crtc);
                p->pri.bytes_per_pixel = crtc->fb->bits_per_pixel / 8;
                p->cur.bytes_per_pixel = 4;
-               p->pri.horiz_pixels =
-                       intel_crtc->config.requested_mode.hdisplay;
+               p->pri.horiz_pixels = intel_crtc->config.pipe_src_w;
                p->cur.horiz_pixels = 64;
                /* TODO: for now, assume primary and cursor planes are always enabled. */
                p->pri.enabled = true;
  }
  
  static void hsw_compute_wm_results(struct drm_device *dev,
-                                  struct hsw_pipe_wm_parameters *params,
-                                  struct hsw_wm_maximums *lp_maximums,
+                                  const struct hsw_pipe_wm_parameters *params,
+                                  const struct hsw_wm_maximums *lp_maximums,
                                   struct hsw_wm_values *results)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        }
  
        for_each_pipe(pipe)
-               results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev_priv, pipe,
+               results->wm_pipe[pipe] = hsw_compute_wm_pipe(dev,
                                                             &params[pipe]);
  
        for_each_pipe(pipe) {
@@@ -2841,8 -2865,9 +2865,9 @@@ static void hsw_write_wm_values(struct 
                I915_WRITE(WM3_LP_ILK, results->wm_lp[2]);
  }
  
- static void haswell_update_wm(struct drm_device *dev)
+ static void haswell_update_wm(struct drm_crtc *crtc)
  {
+       struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct hsw_wm_maximums lp_max_1_2, lp_max_5_6;
        struct hsw_pipe_wm_parameters params[3];
@@@ -2879,7 -2904,7 +2904,7 @@@ static void haswell_update_sprite_wm(st
        intel_plane->wm.horiz_pixels = sprite_width;
        intel_plane->wm.bytes_per_pixel = pixel_size;
  
-       haswell_update_wm(plane->dev);
+       haswell_update_wm(crtc);
  }
  
  static bool
@@@ -2898,7 -2923,7 +2923,7 @@@ sandybridge_compute_sprite_wm(struct dr
                return false;
        }
  
-       clock = crtc->mode.clock;
+       clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
  
        /* Use the small buffer method to calculate the sprite watermark */
        entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
@@@ -2933,7 -2958,7 +2958,7 @@@ sandybridge_compute_sprite_srwm(struct 
        }
  
        crtc = intel_get_crtc_for_plane(dev, plane);
-       clock = crtc->mode.clock;
+       clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock;
        if (!clock) {
                *sprite_wm = 0;
                return false;
@@@ -3076,12 -3101,12 +3101,12 @@@ static void sandybridge_update_sprite_w
   * We don't use the sprite, so we can ignore that.  And on Crestline we have
   * to set the non-SR watermarks to 8.
   */
- void intel_update_watermarks(struct drm_device *dev)
+ void intel_update_watermarks(struct drm_crtc *crtc)
  {
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct drm_i915_private *dev_priv = crtc->dev->dev_private;
  
        if (dev_priv->display.update_wm)
-               dev_priv->display.update_wm(dev);
+               dev_priv->display.update_wm(crtc);
  }
  
  void intel_update_sprite_watermarks(struct drm_plane *plane,
@@@ -3287,6 -3312,98 +3312,98 @@@ static u32 gen6_rps_limits(struct drm_i
        return limits;
  }
  
+ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
+ {
+       int new_power;
+       new_power = dev_priv->rps.power;
+       switch (dev_priv->rps.power) {
+       case LOW_POWER:
+               if (val > dev_priv->rps.rpe_delay + 1 && val > dev_priv->rps.cur_delay)
+                       new_power = BETWEEN;
+               break;
+       case BETWEEN:
+               if (val <= dev_priv->rps.rpe_delay && val < dev_priv->rps.cur_delay)
+                       new_power = LOW_POWER;
+               else if (val >= dev_priv->rps.rp0_delay && val > dev_priv->rps.cur_delay)
+                       new_power = HIGH_POWER;
+               break;
+       case HIGH_POWER:
+               if (val < (dev_priv->rps.rp1_delay + dev_priv->rps.rp0_delay) >> 1 && val < dev_priv->rps.cur_delay)
+                       new_power = BETWEEN;
+               break;
+       }
+       /* Max/min bins are special */
+       if (val == dev_priv->rps.min_delay)
+               new_power = LOW_POWER;
+       if (val == dev_priv->rps.max_delay)
+               new_power = HIGH_POWER;
+       if (new_power == dev_priv->rps.power)
+               return;
+       /* Note the units here are not exactly 1us, but 1280ns. */
+       switch (new_power) {
+       case LOW_POWER:
+               /* Upclock if more than 95% busy over 16ms */
+               I915_WRITE(GEN6_RP_UP_EI, 12500);
+               I915_WRITE(GEN6_RP_UP_THRESHOLD, 11800);
+               /* Downclock if less than 85% busy over 32ms */
+               I915_WRITE(GEN6_RP_DOWN_EI, 25000);
+               I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 21250);
+               I915_WRITE(GEN6_RP_CONTROL,
+                          GEN6_RP_MEDIA_TURBO |
+                          GEN6_RP_MEDIA_HW_NORMAL_MODE |
+                          GEN6_RP_MEDIA_IS_GFX |
+                          GEN6_RP_ENABLE |
+                          GEN6_RP_UP_BUSY_AVG |
+                          GEN6_RP_DOWN_IDLE_AVG);
+               break;
+       case BETWEEN:
+               /* Upclock if more than 90% busy over 13ms */
+               I915_WRITE(GEN6_RP_UP_EI, 10250);
+               I915_WRITE(GEN6_RP_UP_THRESHOLD, 9225);
+               /* Downclock if less than 75% busy over 32ms */
+               I915_WRITE(GEN6_RP_DOWN_EI, 25000);
+               I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 18750);
+               I915_WRITE(GEN6_RP_CONTROL,
+                          GEN6_RP_MEDIA_TURBO |
+                          GEN6_RP_MEDIA_HW_NORMAL_MODE |
+                          GEN6_RP_MEDIA_IS_GFX |
+                          GEN6_RP_ENABLE |
+                          GEN6_RP_UP_BUSY_AVG |
+                          GEN6_RP_DOWN_IDLE_AVG);
+               break;
+       case HIGH_POWER:
+               /* Upclock if more than 85% busy over 10ms */
+               I915_WRITE(GEN6_RP_UP_EI, 8000);
+               I915_WRITE(GEN6_RP_UP_THRESHOLD, 6800);
+               /* Downclock if less than 60% busy over 32ms */
+               I915_WRITE(GEN6_RP_DOWN_EI, 25000);
+               I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 15000);
+               I915_WRITE(GEN6_RP_CONTROL,
+                          GEN6_RP_MEDIA_TURBO |
+                          GEN6_RP_MEDIA_HW_NORMAL_MODE |
+                          GEN6_RP_MEDIA_IS_GFX |
+                          GEN6_RP_ENABLE |
+                          GEN6_RP_UP_BUSY_AVG |
+                          GEN6_RP_DOWN_IDLE_AVG);
+               break;
+       }
+       dev_priv->rps.power = new_power;
+       dev_priv->rps.last_adj = 0;
+ }
  void gen6_set_rps(struct drm_device *dev, u8 val)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        if (val == dev_priv->rps.cur_delay)
                return;
  
+       gen6_set_rps_thresholds(dev_priv, val);
        if (IS_HASWELL(dev))
                I915_WRITE(GEN6_RPNSWREQ,
                           HSW_FREQUENCY(val));
        trace_intel_gpu_freq_change(val * 50);
  }
  
+ void gen6_rps_idle(struct drm_i915_private *dev_priv)
+ {
+       mutex_lock(&dev_priv->rps.hw_lock);
+       if (dev_priv->info->is_valleyview)
+               valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
+       else
+               gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
+       dev_priv->rps.last_adj = 0;
+       mutex_unlock(&dev_priv->rps.hw_lock);
+ }
+ void gen6_rps_boost(struct drm_i915_private *dev_priv)
+ {
+       mutex_lock(&dev_priv->rps.hw_lock);
+       if (dev_priv->info->is_valleyview)
+               valleyview_set_rps(dev_priv->dev, dev_priv->rps.max_delay);
+       else
+               gen6_set_rps(dev_priv->dev, dev_priv->rps.max_delay);
+       dev_priv->rps.last_adj = 0;
+       mutex_unlock(&dev_priv->rps.hw_lock);
+ }
  /*
   * Wait until the previous freq change has completed,
   * or the timeout elapsed, and then update our notion
@@@ -3501,7 -3642,10 +3642,10 @@@ static void gen6_enable_rps(struct drm_
  
        /* In units of 50MHz */
        dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff;
-       dev_priv->rps.min_delay = (rp_state_cap & 0xff0000) >> 16;
+       dev_priv->rps.min_delay = (rp_state_cap >> 16) & 0xff;
+       dev_priv->rps.rp1_delay = (rp_state_cap >>  8) & 0xff;
+       dev_priv->rps.rp0_delay = (rp_state_cap >>  0) & 0xff;
+       dev_priv->rps.rpe_delay = dev_priv->rps.rp1_delay;
        dev_priv->rps.cur_delay = 0;
  
        /* disable the counters and set deterministic thresholds */
                   GEN6_RC_CTL_EI_MODE(1) |
                   GEN6_RC_CTL_HW_ENABLE);
  
-       if (IS_HASWELL(dev)) {
-               I915_WRITE(GEN6_RPNSWREQ,
-                          HSW_FREQUENCY(10));
-               I915_WRITE(GEN6_RC_VIDEO_FREQ,
-                          HSW_FREQUENCY(12));
-       } else {
-               I915_WRITE(GEN6_RPNSWREQ,
-                          GEN6_FREQUENCY(10) |
-                          GEN6_OFFSET(0) |
-                          GEN6_AGGRESSIVE_TURBO);
-               I915_WRITE(GEN6_RC_VIDEO_FREQ,
-                          GEN6_FREQUENCY(12));
-       }
-       I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
-       I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
-                  dev_priv->rps.max_delay << 24 |
-                  dev_priv->rps.min_delay << 16);
-       I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
-       I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
-       I915_WRITE(GEN6_RP_UP_EI, 66000);
-       I915_WRITE(GEN6_RP_DOWN_EI, 350000);
+       /* Power down if completely idle for over 50ms */
+       I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 50000);
        I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
-       I915_WRITE(GEN6_RP_CONTROL,
-                  GEN6_RP_MEDIA_TURBO |
-                  GEN6_RP_MEDIA_HW_NORMAL_MODE |
-                  GEN6_RP_MEDIA_IS_GFX |
-                  GEN6_RP_ENABLE |
-                  GEN6_RP_UP_BUSY_AVG |
-                  (IS_HASWELL(dev) ? GEN7_RP_DOWN_IDLE_AVG : GEN6_RP_DOWN_IDLE_CONT));
  
        ret = sandybridge_pcode_write(dev_priv, GEN6_PCODE_WRITE_MIN_FREQ_TABLE, 0);
        if (!ret) {
                DRM_DEBUG_DRIVER("Failed to set the min frequency\n");
        }
  
-       gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8);
+       dev_priv->rps.power = HIGH_POWER; /* force a reset */
+       gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
  
        gen6_enable_rps_interrupts(dev);
  
@@@ -3638,9 -3754,9 +3754,9 @@@ void gen6_update_ring_freq(struct drm_d
        /* Convert from kHz to MHz */
        max_ia_freq /= 1000;
  
-       min_ring_freq = I915_READ(MCHBAR_MIRROR_BASE_SNB + DCLK);
-       /* convert DDR frequency from units of 133.3MHz to bandwidth */
-       min_ring_freq = (2 * 4 * min_ring_freq + 2) / 3;
+       min_ring_freq = I915_READ(MCHBAR_MIRROR_BASE_SNB + DCLK) & 0xf;
+       /* convert DDR frequency from units of 266.6MHz to bandwidth */
+       min_ring_freq = mult_frac(min_ring_freq, 8, 3);
  
        /*
         * For each potential GPU frequency, load a ring frequency we'd like
                unsigned int ia_freq = 0, ring_freq = 0;
  
                if (IS_HASWELL(dev)) {
-                       ring_freq = (gpu_freq * 5 + 3) / 4;
+                       ring_freq = mult_frac(gpu_freq, 5, 4);
                        ring_freq = max(min_ring_freq, ring_freq);
                        /* leave ia_freq as the default, chosen by cpufreq */
                } else {
@@@ -3709,24 -3825,6 +3825,6 @@@ int valleyview_rps_min_freq(struct drm_
        return vlv_punit_read(dev_priv, PUNIT_REG_GPU_LFM) & 0xff;
  }
  
- static void vlv_rps_timer_work(struct work_struct *work)
- {
-       drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
-                                                   rps.vlv_work.work);
-       /*
-        * Timer fired, we must be idle.  Drop to min voltage state.
-        * Note: we use RPe here since it should match the
-        * Vmin we were shooting for.  That should give us better
-        * perf when we come back out of RC6 than if we used the
-        * min freq available.
-        */
-       mutex_lock(&dev_priv->rps.hw_lock);
-       if (dev_priv->rps.cur_delay > dev_priv->rps.rpe_delay)
-               valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
-       mutex_unlock(&dev_priv->rps.hw_lock);
- }
  static void valleyview_setup_pctx(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@@ -3773,13 -3871,14 +3871,14 @@@ static void valleyview_enable_rps(struc
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring;
-       u32 gtfifodbg, val;
+       u32 gtfifodbg, val, rc6_mode = 0;
        int i;
  
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
  
        if ((gtfifodbg = I915_READ(GTFIFODBG))) {
-               DRM_ERROR("GT fifo had a previous error %x\n", gtfifodbg);
+               DRM_DEBUG_DRIVER("GT fifo had a previous error %x\n",
+                                gtfifodbg);
                I915_WRITE(GTFIFODBG, gtfifodbg);
        }
  
        I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350);
  
        /* allows RC6 residency counter to work */
-       I915_WRITE(0x138104, _MASKED_BIT_ENABLE(0x3));
-       I915_WRITE(GEN6_RC_CONTROL,
-                  GEN7_RC_CTL_TO_MODE);
+       I915_WRITE(VLV_COUNTER_CONTROL,
+                  _MASKED_BIT_ENABLE(VLV_COUNT_RANGE_HIGH |
+                                     VLV_MEDIA_RC6_COUNT_EN |
+                                     VLV_RENDER_RC6_COUNT_EN));
+       if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
+               rc6_mode = GEN7_RC_CTL_TO_MODE;
+       I915_WRITE(GEN6_RC_CONTROL, rc6_mode);
  
        val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
        switch ((val >> 6) & 3) {
@@@ -4603,8 -4706,6 +4706,6 @@@ void intel_disable_gt_powersave(struct 
        } else if (INTEL_INFO(dev)->gen >= 6) {
                cancel_delayed_work_sync(&dev_priv->rps.delayed_resume_work);
                cancel_work_sync(&dev_priv->rps.work);
-               if (IS_VALLEYVIEW(dev))
-                       cancel_delayed_work_sync(&dev_priv->rps.vlv_work);
                mutex_lock(&dev_priv->rps.hw_lock);
                if (IS_VALLEYVIEW(dev))
                        valleyview_disable_rps(dev);
@@@ -4759,9 -4860,7 +4860,9 @@@ static void cpt_init_clock_gating(struc
         * gating for the panel power sequencer or it will fail to
         * start up when no ports are active.
         */
 -      I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
 +      I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE |
 +                 PCH_DPLUNIT_CLOCK_GATE_DISABLE |
 +                 PCH_CPUNIT_CLOCK_GATE_DISABLE);
        I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
                   DPLS_EDP_PPS_FIX_DIS);
        /* The below fixes the weird display corruption, a few pixels shifted
@@@ -4955,11 -5054,6 +5056,11 @@@ static void haswell_init_clock_gating(s
        I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
                        GEN7_WA_L3_CHICKEN_MODE);
  
 +      /* L3 caching of data atomics doesn't work -- disable it. */
 +      I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
 +      I915_WRITE(HSW_ROW_CHICKEN3,
 +                 _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE));
 +
        /* This is required by WaCatErrorRejectionIssue:hsw */
        I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
                        I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
@@@ -5272,6 -5366,7 +5373,7 @@@ bool intel_display_power_enabled(struc
        case POWER_DOMAIN_PIPE_A:
        case POWER_DOMAIN_TRANSCODER_EDP:
                return true;
+       case POWER_DOMAIN_VGA:
        case POWER_DOMAIN_PIPE_B:
        case POWER_DOMAIN_PIPE_C:
        case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
@@@ -5328,12 -5423,87 +5430,87 @@@ static void __intel_set_power_well(stru
                        spin_lock_irqsave(&dev->vbl_lock, irqflags);
                        for_each_pipe(p)
                                if (p != PIPE_A)
-                                       dev->last_vblank[p] = 0;
+                                       dev->vblank[p].last = 0;
                        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
                }
        }
  }
  
+ static void __intel_power_well_get(struct i915_power_well *power_well)
+ {
+       if (!power_well->count++)
+               __intel_set_power_well(power_well->device, true);
+ }
+ static void __intel_power_well_put(struct i915_power_well *power_well)
+ {
+       WARN_ON(!power_well->count);
+       if (!--power_well->count)
+               __intel_set_power_well(power_well->device, false);
+ }
+ void intel_display_power_get(struct drm_device *dev,
+                            enum intel_display_power_domain domain)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_power_well *power_well = &dev_priv->power_well;
+       if (!HAS_POWER_WELL(dev))
+               return;
+       switch (domain) {
+       case POWER_DOMAIN_PIPE_A:
+       case POWER_DOMAIN_TRANSCODER_EDP:
+               return;
+       case POWER_DOMAIN_VGA:
+       case POWER_DOMAIN_PIPE_B:
+       case POWER_DOMAIN_PIPE_C:
+       case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
+       case POWER_DOMAIN_PIPE_B_PANEL_FITTER:
+       case POWER_DOMAIN_PIPE_C_PANEL_FITTER:
+       case POWER_DOMAIN_TRANSCODER_A:
+       case POWER_DOMAIN_TRANSCODER_B:
+       case POWER_DOMAIN_TRANSCODER_C:
+               spin_lock_irq(&power_well->lock);
+               __intel_power_well_get(power_well);
+               spin_unlock_irq(&power_well->lock);
+               return;
+       default:
+               BUG();
+       }
+ }
+ void intel_display_power_put(struct drm_device *dev,
+                            enum intel_display_power_domain domain)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_power_well *power_well = &dev_priv->power_well;
+       if (!HAS_POWER_WELL(dev))
+               return;
+       switch (domain) {
+       case POWER_DOMAIN_PIPE_A:
+       case POWER_DOMAIN_TRANSCODER_EDP:
+               return;
+       case POWER_DOMAIN_VGA:
+       case POWER_DOMAIN_PIPE_B:
+       case POWER_DOMAIN_PIPE_C:
+       case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
+       case POWER_DOMAIN_PIPE_B_PANEL_FITTER:
+       case POWER_DOMAIN_PIPE_C_PANEL_FITTER:
+       case POWER_DOMAIN_TRANSCODER_A:
+       case POWER_DOMAIN_TRANSCODER_B:
+       case POWER_DOMAIN_TRANSCODER_C:
+               spin_lock_irq(&power_well->lock);
+               __intel_power_well_put(power_well);
+               spin_unlock_irq(&power_well->lock);
+               return;
+       default:
+               BUG();
+       }
+ }
  static struct i915_power_well *hsw_pwr;
  
  /* Display audio driver power well request */
@@@ -5343,9 -5513,7 +5520,7 @@@ void i915_request_power_well(void
                return;
  
        spin_lock_irq(&hsw_pwr->lock);
-       if (!hsw_pwr->count++ &&
-                       !hsw_pwr->i915_request)
-               __intel_set_power_well(hsw_pwr->device, true);
+       __intel_power_well_get(hsw_pwr);
        spin_unlock_irq(&hsw_pwr->lock);
  }
  EXPORT_SYMBOL_GPL(i915_request_power_well);
@@@ -5357,10 -5525,7 +5532,7 @@@ void i915_release_power_well(void
                return;
  
        spin_lock_irq(&hsw_pwr->lock);
-       WARN_ON(!hsw_pwr->count);
-       if (!--hsw_pwr->count &&
-                      !hsw_pwr->i915_request)
-               __intel_set_power_well(hsw_pwr->device, false);
+       __intel_power_well_put(hsw_pwr);
        spin_unlock_irq(&hsw_pwr->lock);
  }
  EXPORT_SYMBOL_GPL(i915_release_power_well);
@@@ -5395,15 -5560,37 +5567,37 @@@ void intel_set_power_well(struct drm_de
                return;
  
        spin_lock_irq(&power_well->lock);
+       /*
+        * This function will only ever contribute one
+        * to the power well reference count. i915_request
+        * is what tracks whether we have or have not
+        * added the one to the reference count.
+        */
+       if (power_well->i915_request == enable)
+               goto out;
        power_well->i915_request = enable;
  
-       /* only reject "disable" power well request */
-       if (power_well->count && !enable) {
-               spin_unlock_irq(&power_well->lock);
+       if (enable)
+               __intel_power_well_get(power_well);
+       else
+               __intel_power_well_put(power_well);
+  out:
+       spin_unlock_irq(&power_well->lock);
+ }
+ static void intel_resume_power_well(struct drm_device *dev)
+ {
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_power_well *power_well = &dev_priv->power_well;
+       if (!HAS_POWER_WELL(dev))
                return;
-       }
  
-       __intel_set_power_well(dev, enable);
+       spin_lock_irq(&power_well->lock);
+       __intel_set_power_well(dev, power_well->count > 0);
        spin_unlock_irq(&power_well->lock);
  }
  
@@@ -5422,6 -5609,7 +5616,7 @@@ void intel_init_power_well(struct drm_d
  
        /* For now, we need the power well to be always enabled. */
        intel_set_power_well(dev, true);
+       intel_resume_power_well(dev);
  
        /* We're taking over the BIOS, so clear any requests made by it since
         * the driver is in charge now. */
@@@ -5686,7 -5874,5 +5881,7 @@@ void intel_pm_init(struct drm_device *d
  
        INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work,
                          intel_gen6_powersave_work);
 +
 +      INIT_DELAYED_WORK(&dev_priv->rps.vlv_work, vlv_rps_timer_work);
  }
  
index 5e891b226acf9cf60db309fc8b8c596660fe1d96,28e2dc48e01525a7c01965def343fc0398b541a6..2cb08f93236d9e68fc20a7ed28945983c512a019
@@@ -213,7 -213,7 +213,7 @@@ void radeon_atom_backlight_init(struct 
        props.type = BACKLIGHT_RAW;
        snprintf(bl_name, sizeof(bl_name),
                 "radeon_bl%d", dev->primary->index);
-       bd = backlight_device_register(bl_name, &drm_connector->kdev,
+       bd = backlight_device_register(bl_name, drm_connector->kdev,
                                       pdata, &radeon_atom_backlight_ops, &props);
        if (IS_ERR(bd)) {
                DRM_ERROR("Backlight registration failed\n");
@@@ -707,37 -707,24 +707,37 @@@ atombios_get_encoder_mode(struct drm_en
        switch (connector->connector_type) {
        case DRM_MODE_CONNECTOR_DVII:
        case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */
 -              if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) ||
 -                  (drm_detect_hdmi_monitor(radeon_connector->edid) &&
 -                   (radeon_connector->audio == RADEON_AUDIO_AUTO)))
 -                      return ATOM_ENCODER_MODE_HDMI;
 -              else if (radeon_connector->use_digital)
 +              if (radeon_audio != 0) {
 +                      if (radeon_connector->use_digital &&
 +                          (radeon_connector->audio == RADEON_AUDIO_ENABLE))
 +                              return ATOM_ENCODER_MODE_HDMI;
 +                      else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
 +                               (radeon_connector->audio == RADEON_AUDIO_AUTO))
 +                              return ATOM_ENCODER_MODE_HDMI;
 +                      else if (radeon_connector->use_digital)
 +                              return ATOM_ENCODER_MODE_DVI;
 +                      else
 +                              return ATOM_ENCODER_MODE_CRT;
 +              } else if (radeon_connector->use_digital) {
                        return ATOM_ENCODER_MODE_DVI;
 -              else
 +              } else {
                        return ATOM_ENCODER_MODE_CRT;
 +              }
                break;
        case DRM_MODE_CONNECTOR_DVID:
        case DRM_MODE_CONNECTOR_HDMIA:
        default:
 -              if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) ||
 -                  (drm_detect_hdmi_monitor(radeon_connector->edid) &&
 -                   (radeon_connector->audio == RADEON_AUDIO_AUTO)))
 -                      return ATOM_ENCODER_MODE_HDMI;
 -              else
 +              if (radeon_audio != 0) {
 +                      if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
 +                              return ATOM_ENCODER_MODE_HDMI;
 +                      else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
 +                               (radeon_connector->audio == RADEON_AUDIO_AUTO))
 +                              return ATOM_ENCODER_MODE_HDMI;
 +                      else
 +                              return ATOM_ENCODER_MODE_DVI;
 +              } else {
                        return ATOM_ENCODER_MODE_DVI;
 +              }
                break;
        case DRM_MODE_CONNECTOR_LVDS:
                return ATOM_ENCODER_MODE_LVDS;
        case DRM_MODE_CONNECTOR_DisplayPort:
                dig_connector = radeon_connector->con_priv;
                if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
 -                  (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
 +                  (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
                        return ATOM_ENCODER_MODE_DP;
 -              else if ((radeon_connector->audio == RADEON_AUDIO_ENABLE) ||
 -                       (drm_detect_hdmi_monitor(radeon_connector->edid) &&
 -                        (radeon_connector->audio == RADEON_AUDIO_AUTO)))
 -                      return ATOM_ENCODER_MODE_HDMI;
 -              else
 +              } else if (radeon_audio != 0) {
 +                      if (radeon_connector->audio == RADEON_AUDIO_ENABLE)
 +                              return ATOM_ENCODER_MODE_HDMI;
 +                      else if (drm_detect_hdmi_monitor(radeon_connector->edid) &&
 +                               (radeon_connector->audio == RADEON_AUDIO_AUTO))
 +                              return ATOM_ENCODER_MODE_HDMI;
 +                      else
 +                              return ATOM_ENCODER_MODE_DVI;
 +              } else {
                        return ATOM_ENCODER_MODE_DVI;
 +              }
                break;
        case DRM_MODE_CONNECTOR_eDP:
                return ATOM_ENCODER_MODE_DP;
@@@ -1673,7 -1655,7 +1673,7 @@@ radeon_atom_encoder_dpms_dig(struct drm
                         * does the same thing and more.
                         */
                        if ((rdev->family != CHIP_RV710) && (rdev->family != CHIP_RV730) &&
 -                          (rdev->family != CHIP_RS880))
 +                          (rdev->family != CHIP_RS780) && (rdev->family != CHIP_RS880))
                                atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
                }
                if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(encoder)) && connector) {
index 9c14a1ba1de43aa9086741fda75c9aba3cc96394,22f685827b7e526015201675b994768f67559809..b01f231c2f1994db73ca01fe1f56fd22801fa111
@@@ -100,7 -100,6 +100,6 @@@ void radeon_driver_irq_preinstall_kms(s
  int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
  void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
  irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS);
- int radeon_gem_object_init(struct drm_gem_object *obj);
  void radeon_gem_object_free(struct drm_gem_object *obj);
  int radeon_gem_object_open(struct drm_gem_object *obj,
                                struct drm_file *file_priv);
@@@ -153,7 -152,7 +152,7 @@@ int radeon_benchmarking = 0
  int radeon_testing = 0;
  int radeon_connector_table = 0;
  int radeon_tv = 1;
 -int radeon_audio = 1;
 +int radeon_audio = -1;
  int radeon_disp_priority = 0;
  int radeon_hw_i2c = 0;
  int radeon_pcie_gen2 = -1;
@@@ -196,7 -195,7 +195,7 @@@ module_param_named(connector_table, rad
  MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
  module_param_named(tv, radeon_tv, int, 0444);
  
 -MODULE_PARM_DESC(audio, "Audio enable (1 = enable)");
 +MODULE_PARM_DESC(audio, "Audio enable (-1 = auto, 0 = disable, 1 = enable)");
  module_param_named(audio, radeon_audio, int, 0444);
  
  MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
@@@ -408,7 -407,6 +407,6 @@@ static struct drm_driver kms_driver = 
        .irq_uninstall = radeon_driver_irq_uninstall_kms,
        .irq_handler = radeon_driver_irq_handler_kms,
        .ioctls = radeon_ioctls_kms,
-       .gem_init_object = radeon_gem_object_init,
        .gem_free_object = radeon_gem_object_free,
        .gem_open_object = radeon_gem_object_open,
        .gem_close_object = radeon_gem_object_close,
index a475b3e07c9c71481f78214812053d93f62bff83,c1014eb2907dc6bc802972ae27712cdeb8f86c82..ad135d3c3281f40f3d45b4148c0538cf05a7cc37
@@@ -396,14 -396,14 +396,14 @@@ static int imx_drm_driver_load(struct d
  
        /*
         * enable drm irq mode.
-        * - with irq_enabled = 1, we can use the vblank feature.
+        * - with irq_enabled = true, we can use the vblank feature.
         *
         * P.S. note that we wouldn't use drm irq handler but
         *      just specific driver own one instead because
         *      drm framework supports only one irq handler and
         *      drivers can well take care of their interrupts
         */
-       drm->irq_enabled = 1;
+       drm->irq_enabled = true;
  
        drm_mode_config_init(drm);
        imx_drm_mode_config_init(drm);
                goto err_init;
  
        /*
-        * with vblank_disable_allowed = 1, vblank interrupt will be disabled
+        * with vblank_disable_allowed = true, vblank interrupt will be disabled
         * by drm timer once a current process gives up ownership of
         * vblank event.(after drm_vblank_put function is called)
         */
-       imxdrm->drm->vblank_disable_allowed = 1;
+       imxdrm->drm->vblank_disable_allowed = true;
  
        if (!imx_drm_device_get())
                ret = -EINVAL;
@@@ -800,12 -800,6 +800,12 @@@ static struct drm_driver imx_drm_drive
  
  static int imx_drm_platform_probe(struct platform_device *pdev)
  {
 +      int ret;
 +
 +      ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
 +      if (ret)
 +              return ret;
 +
        imx_drm_device->dev = &pdev->dev;
  
        return drm_platform_init(&imx_drm_driver, pdev);
@@@ -848,6 -842,8 +848,6 @@@ static int __init imx_drm_init(void
                goto err_pdev;
        }
  
 -      imx_drm_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32),
 -
        ret = platform_driver_register(&imx_drm_pdrv);
        if (ret)
                goto err_pdrv;
index 28acbaf4a81ec091a54740c54adfd57ec2f9ad59,c2c4ace3db610abc481240031a396ca76eabcaec..f104c2603ebe44397d62a45c50e39e18c5ae2b2e
  
  /* Video mode flags */
  /* bit compatible with the xorg definitions. */
- #define DRM_MODE_FLAG_PHSYNC  (1<<0)
- #define DRM_MODE_FLAG_NHSYNC  (1<<1)
- #define DRM_MODE_FLAG_PVSYNC  (1<<2)
- #define DRM_MODE_FLAG_NVSYNC  (1<<3)
- #define DRM_MODE_FLAG_INTERLACE       (1<<4)
- #define DRM_MODE_FLAG_DBLSCAN (1<<5)
- #define DRM_MODE_FLAG_CSYNC   (1<<6)
- #define DRM_MODE_FLAG_PCSYNC  (1<<7)
- #define DRM_MODE_FLAG_NCSYNC  (1<<8)
- #define DRM_MODE_FLAG_HSKEW   (1<<9) /* hskew provided */
- #define DRM_MODE_FLAG_BCAST   (1<<10)
- #define DRM_MODE_FLAG_PIXMUX  (1<<11)
- #define DRM_MODE_FLAG_DBLCLK  (1<<12)
- #define DRM_MODE_FLAG_CLKDIV2 (1<<13)
+ #define DRM_MODE_FLAG_PHSYNC                  (1<<0)
+ #define DRM_MODE_FLAG_NHSYNC                  (1<<1)
+ #define DRM_MODE_FLAG_PVSYNC                  (1<<2)
+ #define DRM_MODE_FLAG_NVSYNC                  (1<<3)
+ #define DRM_MODE_FLAG_INTERLACE                       (1<<4)
+ #define DRM_MODE_FLAG_DBLSCAN                 (1<<5)
+ #define DRM_MODE_FLAG_CSYNC                   (1<<6)
+ #define DRM_MODE_FLAG_PCSYNC                  (1<<7)
+ #define DRM_MODE_FLAG_NCSYNC                  (1<<8)
+ #define DRM_MODE_FLAG_HSKEW                   (1<<9) /* hskew provided */
+ #define DRM_MODE_FLAG_BCAST                   (1<<10)
+ #define DRM_MODE_FLAG_PIXMUX                  (1<<11)
+ #define DRM_MODE_FLAG_DBLCLK                  (1<<12)
+ #define DRM_MODE_FLAG_CLKDIV2                 (1<<13)
+  /*
+   * When adding a new stereo mode don't forget to adjust DRM_MODE_FLAGS_3D_MAX
+   * (define not exposed to user space).
+   */
+ #define DRM_MODE_FLAG_3D_MASK                 (0x1f<<14)
+ #define  DRM_MODE_FLAG_3D_NONE                        (0<<14)
+ #define  DRM_MODE_FLAG_3D_FRAME_PACKING               (1<<14)
+ #define  DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE   (2<<14)
+ #define  DRM_MODE_FLAG_3D_LINE_ALTERNATIVE    (3<<14)
+ #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL   (4<<14)
+ #define  DRM_MODE_FLAG_3D_L_DEPTH             (5<<14)
+ #define  DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH       (6<<14)
+ #define  DRM_MODE_FLAG_3D_TOP_AND_BOTTOM      (7<<14)
+ #define  DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF   (8<<14)
  
  /* DPMS flags */
  /* bit compatible with the xorg definitions. */
@@@ -165,6 -180,7 +180,7 @@@ struct drm_mode_get_plane_res 
  #define DRM_MODE_ENCODER_LVDS 3
  #define DRM_MODE_ENCODER_TVDAC        4
  #define DRM_MODE_ENCODER_VIRTUAL 5
+ #define DRM_MODE_ENCODER_DSI  6
  
  struct drm_mode_get_encoder {
        __u32 encoder_id;
  #define DRM_MODE_CONNECTOR_TV         13
  #define DRM_MODE_CONNECTOR_eDP                14
  #define DRM_MODE_CONNECTOR_VIRTUAL      15
+ #define DRM_MODE_CONNECTOR_DSI                16
  
  struct drm_mode_get_connector {
  
        __u32 connection;
        __u32 mm_width, mm_height; /**< HxW in millimeters */
        __u32 subpixel;
 +
 +      __u32 pad;
  };
  
  #define DRM_MODE_PROP_PENDING (1<<0)