]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_uncore.c
Merge tag 'topic/designware-baytrail-2017-03-02' of git://anongit.freedesktop.org...
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_uncore.c
index b7ff592b14f5e00d68ff1cf6440dd45d6959606d..64222b8041c2f2743df164abc079ba4a8e7de31c 100644 (file)
@@ -25,6 +25,7 @@
 #include "intel_drv.h"
 #include "i915_vgpu.h"
 
+#include <asm/iosf_mbi.h>
 #include <linux/pm_runtime.h>
 
 #define FORCEWAKE_ACK_TIMEOUT_MS 50
@@ -252,8 +253,8 @@ intel_uncore_fw_release_timer(struct hrtimer *timer)
        return HRTIMER_NORESTART;
 }
 
-void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
-                                 bool restore)
+static void intel_uncore_forcewake_reset(struct drm_i915_private *dev_priv,
+                                        bool restore)
 {
        unsigned long irqflags;
        struct intel_uncore_forcewake_domain *domain;
@@ -429,10 +430,18 @@ static void __intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
        intel_uncore_forcewake_reset(dev_priv, restore_forcewake);
 }
 
-void intel_uncore_early_sanitize(struct drm_i915_private *dev_priv,
-                                bool restore_forcewake)
+void intel_uncore_suspend(struct drm_i915_private *dev_priv)
 {
-       __intel_uncore_early_sanitize(dev_priv, restore_forcewake);
+       iosf_mbi_unregister_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
+       intel_uncore_forcewake_reset(dev_priv, false);
+}
+
+void intel_uncore_resume_early(struct drm_i915_private *dev_priv)
+{
+       __intel_uncore_early_sanitize(dev_priv, true);
+       iosf_mbi_register_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
        i915_check_and_clear_faults(dev_priv);
 }
 
@@ -1385,6 +1394,32 @@ static void intel_uncore_fw_domains_init(struct drm_i915_private *dev_priv)
        dev_priv->uncore.fw_domains_table_entries = ARRAY_SIZE((d)); \
 }
 
+static int i915_pmic_bus_access_notifier(struct notifier_block *nb,
+                                        unsigned long action, void *data)
+{
+       struct drm_i915_private *dev_priv = container_of(nb,
+                       struct drm_i915_private, uncore.pmic_bus_access_nb);
+
+       switch (action) {
+       case MBI_PMIC_BUS_ACCESS_BEGIN:
+               /*
+                * forcewake all now to make sure that we don't need to do a
+                * forcewake later which on systems where this notifier gets
+                * called requires the punit to access to the shared pmic i2c
+                * bus, which will be busy after this notification, leading to:
+                * "render: timed out waiting for forcewake ack request."
+                * errors.
+                */
+               intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
+               break;
+       case MBI_PMIC_BUS_ACCESS_END:
+               intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
 void intel_uncore_init(struct drm_i915_private *dev_priv)
 {
        i915_check_vgpu(dev_priv);
@@ -1394,6 +1429,8 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
        __intel_uncore_early_sanitize(dev_priv, false);
 
        dev_priv->uncore.unclaimed_mmio_check = 1;
+       dev_priv->uncore.pmic_bus_access_nb.notifier_call =
+               i915_pmic_bus_access_notifier;
 
        switch (INTEL_INFO(dev_priv)->gen) {
        default:
@@ -1453,6 +1490,9 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
                ASSIGN_READ_MMIO_VFUNCS(vgpu);
        }
 
+       iosf_mbi_register_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
+
        i915_check_and_clear_faults(dev_priv);
 }
 #undef ASSIGN_WRITE_MMIO_VFUNCS
@@ -1460,6 +1500,9 @@ void intel_uncore_init(struct drm_i915_private *dev_priv)
 
 void intel_uncore_fini(struct drm_i915_private *dev_priv)
 {
+       iosf_mbi_unregister_pmic_bus_access_notifier(
+               &dev_priv->uncore.pmic_bus_access_nb);
+
        /* Paranoia: make sure we have disabled everything before we exit. */
        intel_uncore_sanitize(dev_priv);
        intel_uncore_forcewake_reset(dev_priv, false);