drm/i915: cleanup rc6 code
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / i915_drv.c
index 64844e2e9f8668de80760079a06f7401bf9efa08..0de75a23f8e7d4ee147266d8f38f2e618281a8e6 100644 (file)
@@ -49,6 +49,9 @@ module_param_named(powersave, i915_powersave, int, 0600);
 unsigned int i915_lvds_downclock = 0;
 module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
 
+bool i915_try_reset = true;
+module_param_named(reset, i915_try_reset, bool, 0600);
+
 static struct drm_driver driver;
 extern int intel_agp_enabled;
 
@@ -111,7 +114,7 @@ static const struct intel_device_info intel_i965g_info = {
 
 static const struct intel_device_info intel_i965gm_info = {
        .gen = 4, .is_crestline = 1,
-       .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1,
+       .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
        .has_overlay = 1,
        .supports_tv = 1,
 };
@@ -130,7 +133,7 @@ static const struct intel_device_info intel_g45_info = {
 
 static const struct intel_device_info intel_gm45_info = {
        .gen = 4, .is_g4x = 1,
-       .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
+       .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
        .has_pipe_cxsr = 1, .has_hotplug = 1,
        .supports_tv = 1,
        .has_bsd_ring = 1,
@@ -150,7 +153,7 @@ static const struct intel_device_info intel_ironlake_d_info = {
 
 static const struct intel_device_info intel_ironlake_m_info = {
        .gen = 5, .is_mobile = 1,
-       .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1,
+       .need_gfx_hws = 1, .has_hotplug = 1,
        .has_fbc = 0, /* disabled due to buggy hardware */
        .has_bsd_ring = 1,
 };
@@ -165,6 +168,7 @@ static const struct intel_device_info intel_sandybridge_d_info = {
 static const struct intel_device_info intel_sandybridge_m_info = {
        .gen = 6, .is_mobile = 1,
        .need_gfx_hws = 1, .has_hotplug = 1,
+       .has_fbc = 1,
        .has_bsd_ring = 1,
        .has_blt_ring = 1,
 };
@@ -244,10 +248,34 @@ void intel_detect_pch (struct drm_device *dev)
        }
 }
 
+void __gen6_force_wake_get(struct drm_i915_private *dev_priv)
+{
+       int count;
+
+       count = 0;
+       while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
+               udelay(10);
+
+       I915_WRITE_NOTRACE(FORCEWAKE, 1);
+       POSTING_READ(FORCEWAKE);
+
+       count = 0;
+       while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
+               udelay(10);
+}
+
+void __gen6_force_wake_put(struct drm_i915_private *dev_priv)
+{
+       I915_WRITE_NOTRACE(FORCEWAKE, 0);
+       POSTING_READ(FORCEWAKE);
+}
+
 static int i915_drm_freeze(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
+       drm_kms_helper_poll_disable(dev);
+
        pci_save_state(dev->pdev);
 
        /* If KMS is active, we do the leavevt stuff here */
@@ -284,7 +312,9 @@ int i915_suspend(struct drm_device *dev, pm_message_t state)
        if (state.event == PM_EVENT_PRETHAW)
                return 0;
 
-       drm_kms_helper_poll_disable(dev);
+
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
 
        error = i915_drm_freeze(dev);
        if (error)
@@ -304,13 +334,18 @@ static int i915_drm_thaw(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int error = 0;
 
+       if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+               mutex_lock(&dev->struct_mutex);
+               i915_gem_restore_gtt_mappings(dev);
+               mutex_unlock(&dev->struct_mutex);
+       }
+
        i915_restore_state(dev);
        intel_opregion_setup(dev);
 
        /* KMS EnterVT equivalent */
        if (drm_core_check_feature(dev, DRIVER_MODESET)) {
                mutex_lock(&dev->struct_mutex);
-               i915_gem_restore_gtt_mappings(dev);
                dev_priv->mm.suspended = 0;
 
                error = i915_gem_init_ringbuffer(dev);
@@ -320,6 +355,9 @@ static int i915_drm_thaw(struct drm_device *dev)
 
                /* Resume the modeset for every activated CRTC */
                drm_helper_resume_force_mode(dev);
+
+               if (dev_priv->renderctx && dev_priv->pwrctx)
+                       ironlake_enable_rc6(dev);
        }
 
        intel_opregion_init(dev);
@@ -333,6 +371,9 @@ int i915_resume(struct drm_device *dev)
 {
        int ret;
 
+       if (dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
        if (pci_enable_device(dev->pdev))
                return -EIO;
 
@@ -440,6 +481,9 @@ int i915_reset(struct drm_device *dev, u8 flags)
        bool need_display = true;
        int ret;
 
+       if (!i915_try_reset)
+               return 0;
+
        if (!mutex_trylock(&dev->struct_mutex))
                return -EBUSY;
 
@@ -487,11 +531,11 @@ int i915_reset(struct drm_device *dev, u8 flags)
                        !dev_priv->mm.suspended) {
                dev_priv->mm.suspended = 0;
 
-               dev_priv->render_ring.init(&dev_priv->render_ring);
+               dev_priv->ring[RCS].init(&dev_priv->ring[RCS]);
                if (HAS_BSD(dev))
-                   dev_priv->bsd_ring.init(&dev_priv->bsd_ring);
+                   dev_priv->ring[VCS].init(&dev_priv->ring[VCS]);
                if (HAS_BLT(dev))
-                   dev_priv->blt_ring.init(&dev_priv->blt_ring);
+                   dev_priv->ring[BCS].init(&dev_priv->ring[BCS]);
 
                mutex_unlock(&dev->struct_mutex);
                drm_irq_uninstall(dev);
@@ -541,6 +585,9 @@ static int i915_pm_suspend(struct device *dev)
                return -ENODEV;
        }
 
+       if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF)
+               return 0;
+
        error = i915_drm_freeze(drm_dev);
        if (error)
                return error;
@@ -624,6 +671,8 @@ static struct drm_driver driver = {
        .device_is_agp = i915_driver_device_is_agp,
        .enable_vblank = i915_enable_vblank,
        .disable_vblank = i915_disable_vblank,
+       .get_vblank_timestamp = i915_get_vblank_timestamp,
+       .get_scanout_position = i915_get_crtc_scanoutpos,
        .irq_preinstall = i915_driver_irq_preinstall,
        .irq_postinstall = i915_driver_irq_postinstall,
        .irq_uninstall = i915_driver_irq_uninstall,
@@ -700,11 +749,6 @@ static int __init i915_init(void)
                driver.driver_features &= ~DRIVER_MODESET;
 #endif
 
-       if (!(driver.driver_features & DRIVER_MODESET)) {
-               driver.suspend = i915_suspend;
-               driver.resume = i915_resume;
-       }
-
        return drm_init(&driver);
 }