drm/i915: Rename dev_priv->gtt to dev_priv->ggtt
[cascardo/linux.git] / drivers / gpu / drm / i915 / i915_dma.c
index 142d59a..3565163 100644 (file)
 #include <linux/pm_runtime.h>
 #include <linux/oom.h>
 
+static unsigned int i915_load_fail_count;
+
+bool __i915_inject_load_failure(const char *func, int line)
+{
+       if (i915_load_fail_count >= i915.inject_load_failure)
+               return false;
+
+       if (++i915_load_fail_count == i915.inject_load_failure) {
+               DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n",
+                        i915.inject_load_failure, func, line);
+               return true;
+       }
+
+       return false;
+}
 
 static int i915_getparam(struct drm_device *dev, void *data,
                         struct drm_file *file_priv)
@@ -370,6 +385,9 @@ static int i915_load_modeset_init(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int ret;
 
+       if (i915_inject_load_failure())
+               return -ENODEV;
+
        ret = intel_bios_init(dev_priv);
        if (ret)
                DRM_INFO("failed to find VBIOS tables\n");
@@ -453,6 +471,7 @@ cleanup_irq:
        intel_teardown_gmbus(dev);
 cleanup_csr:
        intel_csr_ucode_fini(dev_priv);
+       intel_power_domains_fini(dev_priv);
        vga_switcheroo_unregister_client(dev->pdev);
 cleanup_vga_client:
        vga_client_register(dev->pdev, NULL, NULL, NULL);
@@ -472,8 +491,8 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
        if (!ap)
                return -ENOMEM;
 
-       ap->ranges[0].base = dev_priv->gtt.mappable_base;
-       ap->ranges[0].size = dev_priv->gtt.mappable_end;
+       ap->ranges[0].base = dev_priv->ggtt.mappable_base;
+       ap->ranges[0].size = dev_priv->ggtt.mappable_end;
 
        primary =
                pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
@@ -950,6 +969,9 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
        struct intel_device_info *device_info;
        int ret = 0;
 
+       if (i915_inject_load_failure())
+               return -ENODEV;
+
        dev_priv->dev = dev;
 
        /* Setup the write-once "constant" device info */
@@ -1064,6 +1086,9 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)
        struct drm_device *dev = dev_priv->dev;
        int ret;
 
+       if (i915_inject_load_failure())
+               return -ENODEV;
+
        if (i915_get_bridge_dev(dev))
                return -EIO;
 
@@ -1095,45 +1120,26 @@ static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv)
 }
 
 /**
- * i915_driver_load - setup chip and create an initial config
- * @dev: DRM device
- * @flags: startup flags
+ * i915_driver_init_hw - setup state requiring device access
+ * @dev_priv: device private
  *
- * The driver load routine has to do several things:
- *   - drive output discovery via intel_modeset_init()
- *   - initialize the memory manager
- *   - allocate initial config memory
- *   - setup the DRM framebuffer with the allocated memory
+ * Setup state that requires accessing the device, but doesn't require
+ * exposing the driver via kernel internal or userspace interfaces.
  */
-int i915_driver_load(struct drm_device *dev, unsigned long flags)
+static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv;
-       int ret = 0;
+       struct drm_device *dev = dev_priv->dev;
        uint32_t aperture_size;
+       int ret;
 
-       dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
-       if (dev_priv == NULL)
-               return -ENOMEM;
-
-       dev->dev_private = dev_priv;
-
-       ret = i915_driver_init_early(dev_priv, dev,
-                                    (struct intel_device_info *)flags);
-
-       if (ret < 0)
-               goto out_free_priv;
-
-       intel_runtime_pm_get(dev_priv);
-
-       ret = i915_driver_init_mmio(dev_priv);
-       if (ret < 0)
-               goto out_runtime_pm_put;
+       if (i915_inject_load_failure())
+               return -ENODEV;
 
        intel_device_info_runtime_init(dev);
 
        ret = i915_gem_gtt_init(dev);
        if (ret)
-               goto out_cleanup_mmio;
+               return ret;
 
        /* WARNING: Apparently we must kick fbdev drivers before vgacon,
         * otherwise the vga fbdev driver falls over. */
@@ -1166,17 +1172,17 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
        if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
                dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
 
-       aperture_size = dev_priv->gtt.mappable_end;
+       aperture_size = dev_priv->ggtt.mappable_end;
 
-       dev_priv->gtt.mappable =
-               io_mapping_create_wc(dev_priv->gtt.mappable_base,
+       dev_priv->ggtt.mappable =
+               io_mapping_create_wc(dev_priv->ggtt.mappable_base,
                                     aperture_size);
-       if (dev_priv->gtt.mappable == NULL) {
+       if (dev_priv->ggtt.mappable == NULL) {
                ret = -EIO;
                goto out_gtt;
        }
 
-       dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base,
+       dev_priv->ggtt.mtrr = arch_phys_wc_add(dev_priv->ggtt.mappable_base,
                                              aperture_size);
 
        pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY,
@@ -1204,17 +1210,41 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
                        DRM_DEBUG_DRIVER("can't enable MSI");
        }
 
-       if (INTEL_INFO(dev)->num_pipes) {
-               ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
-               if (ret)
-                       goto out_disable_msi;
-       }
+       return 0;
 
-       ret = i915_load_modeset_init(dev);
-       if (ret < 0) {
-               DRM_ERROR("failed to init modeset\n");
-               goto out_power_well;
-       }
+out_gtt:
+       i915_global_gtt_cleanup(dev);
+
+       return ret;
+}
+
+/**
+ * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw()
+ * @dev_priv: device private
+ */
+static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv)
+{
+       struct drm_device *dev = dev_priv->dev;
+
+       if (dev->pdev->msi_enabled)
+               pci_disable_msi(dev->pdev);
+
+       pm_qos_remove_request(&dev_priv->pm_qos);
+       arch_phys_wc_del(dev_priv->ggtt.mtrr);
+       io_mapping_free(dev_priv->ggtt.mappable);
+       i915_global_gtt_cleanup(dev);
+}
+
+/**
+ * i915_driver_register - register the driver with the rest of the system
+ * @dev_priv: device private
+ *
+ * Perform any steps necessary to make the driver available via kernel
+ * internal or userspace interfaces.
+ */
+static void i915_driver_register(struct drm_i915_private *dev_priv)
+{
+       struct drm_device *dev = dev_priv->dev;
 
        i915_gem_shrinker_init(dev_priv);
        /*
@@ -1226,16 +1256,88 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        i915_setup_sysfs(dev);
 
-       if (INTEL_INFO(dev)->num_pipes) {
+       if (INTEL_INFO(dev_priv)->num_pipes) {
                /* Must be done after probing outputs */
                intel_opregion_init(dev);
                acpi_video_register();
        }
 
-       if (IS_GEN5(dev))
+       if (IS_GEN5(dev_priv))
                intel_gpu_ips_init(dev_priv);
 
        i915_audio_component_init(dev_priv);
+}
+
+/**
+ * i915_driver_unregister - cleanup the registration done in i915_driver_regiser()
+ * @dev_priv: device private
+ */
+static void i915_driver_unregister(struct drm_i915_private *dev_priv)
+{
+       i915_audio_component_cleanup(dev_priv);
+       intel_gpu_ips_teardown();
+       acpi_video_unregister();
+       intel_opregion_fini(dev_priv->dev);
+       i915_teardown_sysfs(dev_priv->dev);
+       i915_gem_shrinker_cleanup(dev_priv);
+}
+
+/**
+ * i915_driver_load - setup chip and create an initial config
+ * @dev: DRM device
+ * @flags: startup flags
+ *
+ * The driver load routine has to do several things:
+ *   - drive output discovery via intel_modeset_init()
+ *   - initialize the memory manager
+ *   - allocate initial config memory
+ *   - setup the DRM framebuffer with the allocated memory
+ */
+int i915_driver_load(struct drm_device *dev, unsigned long flags)
+{
+       struct drm_i915_private *dev_priv;
+       int ret = 0;
+
+       dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
+       if (dev_priv == NULL)
+               return -ENOMEM;
+
+       dev->dev_private = dev_priv;
+
+       ret = i915_driver_init_early(dev_priv, dev,
+                                    (struct intel_device_info *)flags);
+
+       if (ret < 0)
+               goto out_free_priv;
+
+       intel_runtime_pm_get(dev_priv);
+
+       ret = i915_driver_init_mmio(dev_priv);
+       if (ret < 0)
+               goto out_runtime_pm_put;
+
+       ret = i915_driver_init_hw(dev_priv);
+       if (ret < 0)
+               goto out_cleanup_mmio;
+
+       /*
+        * TODO: move the vblank init and parts of modeset init steps into one
+        * of the i915_driver_init_/i915_driver_register functions according
+        * to the role/effect of the given init step.
+        */
+       if (INTEL_INFO(dev)->num_pipes) {
+               ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes);
+               if (ret)
+                       goto out_cleanup_hw;
+       }
+
+       ret = i915_load_modeset_init(dev);
+       if (ret < 0) {
+               DRM_ERROR("failed to init modeset\n");
+               goto out_cleanup_vblank;
+       }
+
+       i915_driver_register(dev_priv);
 
        intel_runtime_pm_enable(dev_priv);
 
@@ -1243,18 +1345,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        return 0;
 
-out_power_well:
-       intel_power_domains_fini(dev_priv);
+out_cleanup_vblank:
        drm_vblank_cleanup(dev);
-out_disable_msi:
-       if (dev->pdev->msi_enabled)
-               pci_disable_msi(dev->pdev);
-
-       pm_qos_remove_request(&dev_priv->pm_qos);
-       arch_phys_wc_del(dev_priv->gtt.mtrr);
-       io_mapping_free(dev_priv->gtt.mappable);
-out_gtt:
-       i915_global_gtt_cleanup(dev);
+out_cleanup_hw:
+       i915_driver_cleanup_hw(dev_priv);
 out_cleanup_mmio:
        i915_driver_cleanup_mmio(dev_priv);
 out_runtime_pm_put:
@@ -1281,15 +1375,7 @@ int i915_driver_unload(struct drm_device *dev)
 
        intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
 
-       i915_audio_component_cleanup(dev_priv);
-
-       intel_gpu_ips_teardown();
-
-       i915_teardown_sysfs(dev);
-
-       acpi_video_unregister();
-       intel_opregion_fini(dev);
-       i915_gem_shrinker_cleanup(dev_priv);
+       i915_driver_unregister(dev_priv);
 
        drm_vblank_cleanup(dev);
 
@@ -1330,13 +1416,7 @@ int i915_driver_unload(struct drm_device *dev)
 
        intel_power_domains_fini(dev_priv);
 
-       if (dev->pdev->msi_enabled)
-               pci_disable_msi(dev->pdev);
-       pm_qos_remove_request(&dev_priv->pm_qos);
-       arch_phys_wc_del(dev_priv->gtt.mtrr);
-       io_mapping_free(dev_priv->gtt.mappable);
-       i915_global_gtt_cleanup(dev);
-
+       i915_driver_cleanup_hw(dev_priv);
        i915_driver_cleanup_mmio(dev_priv);
 
        intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);