drm/rect: Round above 1 << 16 upwards to correct scale calculation functions.
[sfrench/cifs-2.6.git] / drivers / gpu / drm / i915 / intel_uc.c
index d82ca0f438f5296aebe208d5d50622cecb731a0c..e5bf0d37bf438931ccdb15d6ae218f715722e668 100644 (file)
@@ -27,6 +27,8 @@
 #include "intel_guc.h"
 #include "i915_drv.h"
 
+static void guc_free_load_err_log(struct intel_guc *guc);
+
 /* Reset GuC providing us with fresh state for both GuC and HuC.
  */
 static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
@@ -65,6 +67,21 @@ static int __get_platform_enable_guc(struct drm_i915_private *dev_priv)
        return enable_guc;
 }
 
+static int __get_default_guc_log_level(struct drm_i915_private *dev_priv)
+{
+       int guc_log_level = 0; /* disabled */
+
+       /* Enable if we're running on platform with GuC and debug config */
+       if (HAS_GUC(dev_priv) && intel_uc_is_using_guc() &&
+           (IS_ENABLED(CONFIG_DRM_I915_DEBUG) ||
+            IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)))
+               guc_log_level = 1 + GUC_LOG_VERBOSITY_MAX;
+
+       /* Any platform specific fine-tuning can be done here */
+
+       return guc_log_level;
+}
+
 /**
  * intel_uc_sanitize_options - sanitize uC related modparam options
  * @dev_priv: device private
@@ -74,6 +91,13 @@ static int __get_platform_enable_guc(struct drm_i915_private *dev_priv)
  * modparam varies between platforms and it is hardcoded in driver code.
  * Any other modparam value is only monitored against availability of the
  * related hardware or firmware definitions.
+ *
+ * In case of "guc_log_level" option this function will attempt to modify
+ * it only if it was initially set to "auto(-1)" or if initial value was
+ * "enable(1..4)" on platforms without the GuC. Default value for this
+ * modparam varies between platforms and is usually set to "disable(0)"
+ * unless GuC is enabled on given platform and the driver is compiled with
+ * debug config when this modparam will default to "enable(1..4)".
  */
 void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
 {
@@ -91,22 +115,48 @@ void intel_uc_sanitize_options(struct drm_i915_private *dev_priv)
 
        /* Verify GuC firmware availability */
        if (intel_uc_is_using_guc() && !intel_uc_fw_is_selected(guc_fw)) {
-               DRM_WARN("Incompatible option detected: enable_guc=%d, %s!\n",
-                        i915_modparams.enable_guc,
+               DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
+                        "enable_guc", i915_modparams.enable_guc,
                         !HAS_GUC(dev_priv) ? "no GuC hardware" :
                                              "no GuC firmware");
        }
 
        /* Verify HuC firmware availability */
        if (intel_uc_is_using_huc() && !intel_uc_fw_is_selected(huc_fw)) {
-               DRM_WARN("Incompatible option detected: enable_guc=%d, %s!\n",
-                        i915_modparams.enable_guc,
+               DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
+                        "enable_guc", i915_modparams.enable_guc,
                         !HAS_HUC(dev_priv) ? "no HuC hardware" :
                                              "no HuC firmware");
        }
 
+       /* A negative value means "use platform/config default" */
+       if (i915_modparams.guc_log_level < 0)
+               i915_modparams.guc_log_level =
+                       __get_default_guc_log_level(dev_priv);
+
+       if (i915_modparams.guc_log_level > 0 && !intel_uc_is_using_guc()) {
+               DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
+                        "guc_log_level", i915_modparams.guc_log_level,
+                        !HAS_GUC(dev_priv) ? "no GuC hardware" :
+                                             "GuC not enabled");
+               i915_modparams.guc_log_level = 0;
+       }
+
+       if (i915_modparams.guc_log_level > 1 + GUC_LOG_VERBOSITY_MAX) {
+               DRM_WARN("Incompatible option detected: %s=%d, %s!\n",
+                        "guc_log_level", i915_modparams.guc_log_level,
+                        "verbosity too high");
+               i915_modparams.guc_log_level = 1 + GUC_LOG_VERBOSITY_MAX;
+       }
+
+       DRM_DEBUG_DRIVER("guc_log_level=%d (enabled:%s verbosity:%d)\n",
+                        i915_modparams.guc_log_level,
+                        yesno(i915_modparams.guc_log_level),
+                        i915_modparams.guc_log_level - 1);
+
        /* Make sure that sanitization was done */
        GEM_BUG_ON(i915_modparams.enable_guc < 0);
+       GEM_BUG_ON(i915_modparams.guc_log_level < 0);
 }
 
 void intel_uc_init_early(struct drm_i915_private *dev_priv)
@@ -135,6 +185,8 @@ void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
 
        if (USES_HUC(dev_priv))
                intel_uc_fw_fini(&dev_priv->huc.fw);
+
+       guc_free_load_err_log(&dev_priv->guc);
 }
 
 /**
@@ -152,7 +204,7 @@ void intel_uc_init_mmio(struct drm_i915_private *dev_priv)
 
 static void guc_capture_load_err_log(struct intel_guc *guc)
 {
-       if (!guc->log.vma || i915_modparams.guc_log_level < 0)
+       if (!guc->log.vma || !i915_modparams.guc_log_level)
                return;
 
        if (!guc->load_err_log)
@@ -188,28 +240,44 @@ static void guc_disable_communication(struct intel_guc *guc)
        guc->send = intel_guc_send_nop;
 }
 
-int intel_uc_init_wq(struct drm_i915_private *dev_priv)
+int intel_uc_init_misc(struct drm_i915_private *dev_priv)
 {
+       struct intel_guc *guc = &dev_priv->guc;
        int ret;
 
        if (!USES_GUC(dev_priv))
                return 0;
 
-       ret = intel_guc_init_wq(&dev_priv->guc);
+       ret = intel_guc_init_wq(guc);
        if (ret) {
                DRM_ERROR("Couldn't allocate workqueues for GuC\n");
-               return ret;
+               goto err;
+       }
+
+       ret = intel_guc_log_relay_create(guc);
+       if (ret) {
+               DRM_ERROR("Couldn't allocate relay for GuC log\n");
+               goto err_relay;
        }
 
        return 0;
+
+err_relay:
+       intel_guc_fini_wq(guc);
+err:
+       return ret;
 }
 
-void intel_uc_fini_wq(struct drm_i915_private *dev_priv)
+void intel_uc_fini_misc(struct drm_i915_private *dev_priv)
 {
+       struct intel_guc *guc = &dev_priv->guc;
+
        if (!USES_GUC(dev_priv))
                return;
 
-       intel_guc_fini_wq(&dev_priv->guc);
+       intel_guc_fini_wq(guc);
+
+       intel_guc_log_relay_destroy(guc);
 }
 
 int intel_uc_init(struct drm_i915_private *dev_priv)
@@ -293,7 +361,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
                        goto err_out;
 
                if (USES_HUC(dev_priv)) {
-                       ret = intel_huc_init_hw(huc);
+                       ret = intel_huc_fw_upload(huc);
                        if (ret)
                                goto err_out;
                }
@@ -322,7 +390,7 @@ int intel_uc_init_hw(struct drm_i915_private *dev_priv)
        }
 
        if (USES_GUC_SUBMISSION(dev_priv)) {
-               if (i915_modparams.guc_log_level >= 0)
+               if (i915_modparams.guc_log_level)
                        gen9_enable_guc_interrupts(dev_priv);
 
                ret = intel_guc_submission_enable(guc);
@@ -364,8 +432,6 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
 {
        struct intel_guc *guc = &dev_priv->guc;
 
-       guc_free_load_err_log(guc);
-
        if (!USES_GUC(dev_priv))
                return;
 
@@ -379,3 +445,48 @@ void intel_uc_fini_hw(struct drm_i915_private *dev_priv)
        if (USES_GUC_SUBMISSION(dev_priv))
                gen9_disable_guc_interrupts(dev_priv);
 }
+
+int intel_uc_suspend(struct drm_i915_private *i915)
+{
+       struct intel_guc *guc = &i915->guc;
+       int err;
+
+       if (!USES_GUC(i915))
+               return 0;
+
+       if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
+               return 0;
+
+       err = intel_guc_suspend(guc);
+       if (err) {
+               DRM_DEBUG_DRIVER("Failed to suspend GuC, err=%d", err);
+               return err;
+       }
+
+       gen9_disable_guc_interrupts(i915);
+
+       return 0;
+}
+
+int intel_uc_resume(struct drm_i915_private *i915)
+{
+       struct intel_guc *guc = &i915->guc;
+       int err;
+
+       if (!USES_GUC(i915))
+               return 0;
+
+       if (guc->fw.load_status != INTEL_UC_FIRMWARE_SUCCESS)
+               return 0;
+
+       if (i915_modparams.guc_log_level)
+               gen9_enable_guc_interrupts(i915);
+
+       err = intel_guc_resume(guc);
+       if (err) {
+               DRM_DEBUG_DRIVER("Failed to resume GuC, err=%d", err);
+               return err;
+       }
+
+       return 0;
+}