]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/gpu/drm/i915/i915_dma.c
drm/switcheroo: track state of switch in drivers.
[mv-sheeva.git] / drivers / gpu / drm / i915 / i915_dma.c
index e9fb8953c6066494c58aaeb6e31a993125a8e93a..0568dbdc10efa364732d84aaddfcce50487a2042 100644 (file)
@@ -34,6 +34,7 @@
 #include "i915_drm.h"
 #include "i915_drv.h"
 #include "i915_trace.h"
+#include "../../../platform/x86/intel_ips.h"
 #include <linux/pci.h>
 #include <linux/vgaarb.h>
 #include <linux/acpi.h>
@@ -778,6 +779,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
        case I915_PARAM_HAS_COHERENT_RINGS:
                value = 1;
                break;
+       case I915_PARAM_HAS_EXEC_CONSTANTS:
+               value = INTEL_INFO(dev)->gen >= 4;
+               break;
        default:
                DRM_DEBUG_DRIVER("Unknown parameter %d\n",
                                 param->param);
@@ -1078,7 +1082,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
        if (!cfb_base)
                goto err_fb;
 
-       if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) {
+       if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) {
                compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen,
                                                    4096, 4096, 0);
                if (compressed_llb)
@@ -1096,7 +1100,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
 
        intel_disable_fbc(dev);
        dev_priv->compressed_fb = compressed_fb;
-       if (IS_IRONLAKE_M(dev))
+       if (HAS_PCH_SPLIT(dev))
                I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
        else if (IS_GM45(dev)) {
                I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
@@ -1147,12 +1151,16 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, enum vga_switcheroo_
        pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
        if (state == VGA_SWITCHEROO_ON) {
                printk(KERN_INFO "i915: switched on\n");
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                /* i915 resume handler doesn't set to D0 */
                pci_set_power_state(dev->pdev, PCI_D0);
                i915_resume(dev);
+               dev->switch_power_state = DRM_SWITCH_POWER_ON;
        } else {
                printk(KERN_ERR "i915: switched off\n");
+               dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
                i915_suspend(dev, pmm);
+               dev->switch_power_state = DRM_SWITCH_POWER_OFF;
        }
 }
 
@@ -1227,6 +1235,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
 
        ret = vga_switcheroo_register_client(dev->pdev,
                                             i915_switcheroo_set_state,
+                                            NULL,
                                             i915_switcheroo_can_switch);
        if (ret)
                goto cleanup_vga_client;
@@ -1830,6 +1839,26 @@ out_unlock:
 }
 EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable);
 
+/**
+ * Tells the intel_ips driver that the i915 driver is now loaded, if
+ * IPS got loaded first.
+ *
+ * This awkward dance is so that neither module has to depend on the
+ * other in order for IPS to do the appropriate communication of
+ * GPU turbo limits to i915.
+ */
+static void
+ips_ping_for_i915_load(void)
+{
+       void (*link)(void);
+
+       link = symbol_get(ips_link_to_i915_driver);
+       if (link) {
+               link();
+               symbol_put(ips_link_to_i915_driver);
+       }
+}
+
 /**
  * i915_driver_load - setup chip and create an initial config
  * @dev: DRM device
@@ -2016,6 +2045,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        dev_priv->mchdev_lock = &mchdev_lock;
        spin_unlock(&mchdev_lock);
 
+       ips_ping_for_i915_load();
+
        return 0;
 
 out_gem_unload: