Merge tag 'drm-for-v4.9' of git://people.freedesktop.org/~airlied/linux
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_guc_loader.c
index 605c696..6fd39ef 100644 (file)
  *
  */
 
-#define I915_SKL_GUC_UCODE "i915/skl_guc_ver6_1.bin"
+#define SKL_FW_MAJOR 6
+#define SKL_FW_MINOR 1
+
+#define BXT_FW_MAJOR 8
+#define BXT_FW_MINOR 7
+
+#define KBL_FW_MAJOR 9
+#define KBL_FW_MINOR 14
+
+#define GUC_FW_PATH(platform, major, minor) \
+       "i915/" __stringify(platform) "_guc_ver" __stringify(major) "_" __stringify(minor) ".bin"
+
+#define I915_SKL_GUC_UCODE GUC_FW_PATH(skl, SKL_FW_MAJOR, SKL_FW_MINOR)
 MODULE_FIRMWARE(I915_SKL_GUC_UCODE);
 
-#define I915_BXT_GUC_UCODE "i915/bxt_guc_ver8_7.bin"
+#define I915_BXT_GUC_UCODE GUC_FW_PATH(bxt, BXT_FW_MAJOR, BXT_FW_MINOR)
 MODULE_FIRMWARE(I915_BXT_GUC_UCODE);
 
-#define I915_KBL_GUC_UCODE "i915/kbl_guc_ver9_14.bin"
+#define I915_KBL_GUC_UCODE GUC_FW_PATH(kbl, KBL_FW_MAJOR, KBL_FW_MINOR)
 MODULE_FIRMWARE(I915_KBL_GUC_UCODE);
 
 /* User-friendly representation of an enum */
@@ -85,7 +97,7 @@ const char *intel_guc_fw_status_repr(enum intel_guc_fw_status status)
        }
 };
 
-static void direct_interrupts_to_host(struct drm_i915_private *dev_priv)
+static void guc_interrupts_release(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        int irqs;
@@ -102,7 +114,7 @@ static void direct_interrupts_to_host(struct drm_i915_private *dev_priv)
        I915_WRITE(GUC_WD_VECS_IER, 0);
 }
 
-static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv)
+static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
 {
        struct intel_engine_cs *engine;
        int irqs;
@@ -122,13 +134,28 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv)
        I915_WRITE(GUC_WD_VECS_IER, ~irqs);
 
        /*
-        * If GuC has routed PM interrupts to itself, don't keep it.
-        * and keep other interrupts those are unmasked by GuC.
-       */
+        * The REDIRECT_TO_GUC bit of the PMINTRMSK register directs all
+        * (unmasked) PM interrupts to the GuC. All other bits of this
+        * register *disable* generation of a specific interrupt.
+        *
+        * 'pm_intr_keep' indicates bits that are NOT to be set when
+        * writing to the PM interrupt mask register, i.e. interrupts
+        * that must not be disabled.
+        *
+        * If the GuC is handling these interrupts, then we must not let
+        * the PM code disable ANY interrupt that the GuC is expecting.
+        * So for each ENABLED (0) bit in this register, we must SET the
+        * bit in pm_intr_keep so that it's left enabled for the GuC.
+        *
+        * OTOH the REDIRECT_TO_GUC bit is initially SET in pm_intr_keep
+        * (so interrupts go to the DISPLAY unit at first); but here we
+        * need to CLEAR that bit, which will result in the register bit
+        * being left SET!
+        */
        tmp = I915_READ(GEN6_PMINTRMSK);
-       if (tmp & GEN8_PMINTR_REDIRECT_TO_NON_DISP) {
-               dev_priv->rps.pm_intr_keep |= ~(tmp & ~GEN8_PMINTR_REDIRECT_TO_NON_DISP);
-               dev_priv->rps.pm_intr_keep &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP;
+       if (tmp & GEN8_PMINTR_REDIRECT_TO_GUC) {
+               dev_priv->rps.pm_intr_keep |= ~tmp;
+               dev_priv->rps.pm_intr_keep &= ~GEN8_PMINTR_REDIRECT_TO_GUC;
        }
 }
 
@@ -140,17 +167,24 @@ static u32 get_gttype(struct drm_i915_private *dev_priv)
 
 static u32 get_core_family(struct drm_i915_private *dev_priv)
 {
-       switch (INTEL_INFO(dev_priv)->gen) {
+       u32 gen = INTEL_GEN(dev_priv);
+
+       switch (gen) {
        case 9:
                return GFXCORE_FAMILY_GEN9;
 
        default:
-               DRM_ERROR("GUC: unsupported core family\n");
+               WARN(1, "GEN%d does not support GuC operation!\n", gen);
                return GFXCORE_FAMILY_UNKNOWN;
        }
 }
 
-static void set_guc_init_params(struct drm_i915_private *dev_priv)
+/*
+ * Initialise the GuC parameter block before starting the firmware
+ * transfer. These parameters are read by the firmware on startup
+ * and cannot be changed thereafter.
+ */
+static void guc_params_init(struct drm_i915_private *dev_priv)
 {
        struct intel_guc *guc = &dev_priv->guc;
        u32 params[GUC_CTL_MAX_DWORDS];
@@ -181,16 +215,15 @@ static void set_guc_init_params(struct drm_i915_private *dev_priv)
                        i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT;
        }
 
-       if (guc->ads_obj) {
-               u32 ads = (u32)i915_gem_obj_ggtt_offset(guc->ads_obj)
-                               >> PAGE_SHIFT;
+       if (guc->ads_vma) {
+               u32 ads = i915_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT;
                params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT;
                params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED;
        }
 
        /* If GuC submission is enabled, set up additional parameters here */
        if (i915.enable_guc_submission) {
-               u32 pgs = i915_gem_obj_ggtt_offset(dev_priv->guc.ctx_pool_obj);
+               u32 pgs = i915_ggtt_offset(dev_priv->guc.ctx_pool_vma);
                u32 ctx_in_16 = GUC_MAX_GPU_CONTEXTS / 16;
 
                pgs >>= PAGE_SHIFT;
@@ -238,12 +271,12 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv,
  * Note that GuC needs the CSS header plus uKernel code to be copied by the
  * DMA engine in one operation, whereas the RSA signature is loaded via MMIO.
  */
-static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv)
+static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
+                             struct i915_vma *vma)
 {
        struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
-       struct drm_i915_gem_object *fw_obj = guc_fw->guc_fw_obj;
        unsigned long offset;
-       struct sg_table *sg = fw_obj->pages;
+       struct sg_table *sg = vma->pages;
        u32 status, rsa[UOS_RSA_SCRATCH_MAX_COUNT];
        int i, ret = 0;
 
@@ -260,7 +293,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv)
        I915_WRITE(DMA_COPY_SIZE, guc_fw->header_size + guc_fw->ucode_size);
 
        /* Set the source address for the new blob */
-       offset = i915_gem_obj_ggtt_offset(fw_obj) + guc_fw->header_offset;
+       offset = i915_ggtt_offset(vma) + guc_fw->header_offset;
        I915_WRITE(DMA_ADDR_0_LOW, lower_32_bits(offset));
        I915_WRITE(DMA_ADDR_0_HIGH, upper_32_bits(offset) & 0xFFFF);
 
@@ -315,6 +348,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
 {
        struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
        struct drm_device *dev = &dev_priv->drm;
+       struct i915_vma *vma;
        int ret;
 
        ret = i915_gem_object_set_to_gtt_domain(guc_fw->guc_fw_obj, false);
@@ -323,10 +357,10 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
                return ret;
        }
 
-       ret = i915_gem_obj_ggtt_pin(guc_fw->guc_fw_obj, 0, 0);
-       if (ret) {
-               DRM_DEBUG_DRIVER("pin failed %d\n", ret);
-               return ret;
+       vma = i915_gem_object_ggtt_pin(guc_fw->guc_fw_obj, NULL, 0, 0, 0);
+       if (IS_ERR(vma)) {
+               DRM_DEBUG_DRIVER("pin failed %d\n", (int)PTR_ERR(vma));
+               return PTR_ERR(vma);
        }
 
        /* Invalidate GuC TLB to let GuC take the latest updates to GTT. */
@@ -349,7 +383,9 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
        }
 
        /* WaC6DisallowByGfxPause*/
-       I915_WRITE(GEN6_GFXPAUSE, 0x30FFF);
+       if (IS_SKL_REVID(dev, 0, SKL_REVID_C0) ||
+           IS_BXT_REVID(dev, 0, BXT_REVID_B0))
+               I915_WRITE(GEN6_GFXPAUSE, 0x30FFF);
 
        if (IS_BROXTON(dev))
                I915_WRITE(GEN9LP_GT_PM_CONFIG, GT_DOORBELL_ENABLE);
@@ -361,13 +397,13 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
                I915_WRITE(GEN7_MISCCPCTL, (GEN8_DOP_CLOCK_GATE_GUC_ENABLE |
                                            I915_READ(GEN7_MISCCPCTL)));
 
-               /* allows for 5us before GT can go to RC6 */
+               /* allows for 5us (in 10ns units) before GT can go to RC6 */
                I915_WRITE(GUC_ARAT_C6DIS, 0x1FF);
        }
 
-       set_guc_init_params(dev_priv);
+       guc_params_init(dev_priv);
 
-       ret = guc_ucode_xfer_dma(dev_priv);
+       ret = guc_ucode_xfer_dma(dev_priv, vma);
 
        intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
 
@@ -375,12 +411,12 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
         * We keep the object pages for reuse during resume. But we can unpin it
         * now that DMA has completed, so it doesn't continue to take up space.
         */
-       i915_gem_object_ggtt_unpin(guc_fw->guc_fw_obj);
+       i915_vma_unpin(vma);
 
        return ret;
 }
 
-static int i915_reset_guc(struct drm_i915_private *dev_priv)
+static int guc_hw_reset(struct drm_i915_private *dev_priv)
 {
        int ret;
        u32 guc_status;
@@ -433,7 +469,7 @@ int intel_guc_setup(struct drm_device *dev)
                goto fail;
        } else if (*fw_path == '\0') {
                /* Device has a GuC but we don't know what f/w to load? */
-               DRM_INFO("No GuC firmware known for this platform\n");
+               WARN(1, "No GuC firmware known for this platform!\n");
                err = -ENODEV;
                goto fail;
        }
@@ -447,7 +483,7 @@ int intel_guc_setup(struct drm_device *dev)
                goto fail;
        }
 
-       direct_interrupts_to_host(dev_priv);
+       guc_interrupts_release(dev_priv);
 
        guc_fw->guc_fw_load_status = GUC_FIRMWARE_PENDING;
 
@@ -470,11 +506,9 @@ int intel_guc_setup(struct drm_device *dev)
                 * Always reset the GuC just before (re)loading, so
                 * that the state and timing are fairly predictable
                 */
-               err = i915_reset_guc(dev_priv);
-               if (err) {
-                       DRM_ERROR("GuC reset failed: %d\n", err);
+               err = guc_hw_reset(dev_priv);
+               if (err)
                        goto fail;
-               }
 
                err = guc_ucode_xfer(dev_priv);
                if (!err)
@@ -497,7 +531,7 @@ int intel_guc_setup(struct drm_device *dev)
                err = i915_guc_submission_enable(dev_priv);
                if (err)
                        goto fail;
-               direct_interrupts_to_guc(dev_priv);
+               guc_interrupts_capture(dev_priv);
        }
 
        return 0;
@@ -506,7 +540,7 @@ fail:
        if (guc_fw->guc_fw_load_status == GUC_FIRMWARE_PENDING)
                guc_fw->guc_fw_load_status = GUC_FIRMWARE_FAIL;
 
-       direct_interrupts_to_host(dev_priv);
+       guc_interrupts_release(dev_priv);
        i915_guc_submission_disable(dev_priv);
        i915_guc_submission_fini(dev_priv);
 
@@ -532,15 +566,15 @@ fail:
        else if (err == 0)
                DRM_INFO("GuC firmware load skipped\n");
        else if (ret != -EIO)
-               DRM_INFO("GuC firmware load failed: %d\n", err);
+               DRM_NOTE("GuC firmware load failed: %d\n", err);
        else
-               DRM_ERROR("GuC firmware load failed: %d\n", err);
+               DRM_WARN("GuC firmware load failed: %d\n", err);
 
        if (i915.enable_guc_submission) {
                if (fw_path == NULL)
                        DRM_INFO("GuC submission without firmware not supported\n");
                if (ret == 0)
-                       DRM_INFO("Falling back from GuC submission to execlist mode\n");
+                       DRM_NOTE("Falling back from GuC submission to execlist mode\n");
                else
                        DRM_ERROR("GuC init failed: %d\n", ret);
        }
@@ -551,6 +585,7 @@ fail:
 
 static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
 {
+       struct pci_dev *pdev = dev->pdev;
        struct drm_i915_gem_object *obj;
        const struct firmware *fw;
        struct guc_css_header *css;
@@ -560,7 +595,7 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
        DRM_DEBUG_DRIVER("before requesting firmware: GuC fw fetch status %s\n",
                intel_guc_fw_status_repr(guc_fw->guc_fw_fetch_status));
 
-       err = request_firmware(&fw, guc_fw->guc_fw_path, &dev->pdev->dev);
+       err = request_firmware(&fw, guc_fw->guc_fw_path, &pdev->dev);
        if (err)
                goto fail;
        if (!fw)
@@ -571,7 +606,7 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
 
        /* Check the size of the blob before examining buffer contents */
        if (fw->size < sizeof(struct guc_css_header)) {
-               DRM_ERROR("Firmware header is missing\n");
+               DRM_NOTE("Firmware header is missing\n");
                goto fail;
        }
 
@@ -583,7 +618,7 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
                css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
 
        if (guc_fw->header_size != sizeof(struct guc_css_header)) {
-               DRM_ERROR("CSS header definition mismatch\n");
+               DRM_NOTE("CSS header definition mismatch\n");
                goto fail;
        }
 
@@ -593,7 +628,7 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
 
        /* now RSA */
        if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
-               DRM_ERROR("RSA key size is bad\n");
+               DRM_NOTE("RSA key size is bad\n");
                goto fail;
        }
        guc_fw->rsa_offset = guc_fw->ucode_offset + guc_fw->ucode_size;
@@ -602,14 +637,14 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
        /* At least, it should have header, uCode and RSA. Size of all three. */
        size = guc_fw->header_size + guc_fw->ucode_size + guc_fw->rsa_size;
        if (fw->size < size) {
-               DRM_ERROR("Missing firmware components\n");
+               DRM_NOTE("Missing firmware components\n");
                goto fail;
        }
 
        /* Header and uCode will be loaded to WOPCM. Size of the two. */
        size = guc_fw->header_size + guc_fw->ucode_size;
        if (size > guc_wopcm_size(to_i915(dev))) {
-               DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+               DRM_NOTE("Firmware is too large to fit in WOPCM\n");
                goto fail;
        }
 
@@ -624,7 +659,7 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
 
        if (guc_fw->guc_fw_major_found != guc_fw->guc_fw_major_wanted ||
            guc_fw->guc_fw_minor_found < guc_fw->guc_fw_minor_wanted) {
-               DRM_ERROR("GuC firmware version %d.%d, required %d.%d\n",
+               DRM_NOTE("GuC firmware version %d.%d, required %d.%d\n",
                        guc_fw->guc_fw_major_found, guc_fw->guc_fw_minor_found,
                        guc_fw->guc_fw_major_wanted, guc_fw->guc_fw_minor_wanted);
                err = -ENOEXEC;
@@ -654,15 +689,15 @@ static void guc_fw_fetch(struct drm_device *dev, struct intel_guc_fw *guc_fw)
        return;
 
 fail:
+       DRM_WARN("Failed to fetch valid GuC firmware from %s (error %d)\n",
+                guc_fw->guc_fw_path, err);
        DRM_DEBUG_DRIVER("GuC fw fetch status FAIL; err %d, fw %p, obj %p\n",
                err, fw, guc_fw->guc_fw_obj);
-       DRM_ERROR("Failed to fetch GuC firmware from %s (error %d)\n",
-                 guc_fw->guc_fw_path, err);
 
        mutex_lock(&dev->struct_mutex);
        obj = guc_fw->guc_fw_obj;
        if (obj)
-               drm_gem_object_unreference(&obj->base);
+               i915_gem_object_put(obj);
        guc_fw->guc_fw_obj = NULL;
        mutex_unlock(&dev->struct_mutex);
 
@@ -695,16 +730,16 @@ void intel_guc_init(struct drm_device *dev)
                fw_path = NULL;
        } else if (IS_SKYLAKE(dev)) {
                fw_path = I915_SKL_GUC_UCODE;
-               guc_fw->guc_fw_major_wanted = 6;
-               guc_fw->guc_fw_minor_wanted = 1;
+               guc_fw->guc_fw_major_wanted = SKL_FW_MAJOR;
+               guc_fw->guc_fw_minor_wanted = SKL_FW_MINOR;
        } else if (IS_BROXTON(dev)) {
                fw_path = I915_BXT_GUC_UCODE;
-               guc_fw->guc_fw_major_wanted = 8;
-               guc_fw->guc_fw_minor_wanted = 7;
+               guc_fw->guc_fw_major_wanted = BXT_FW_MAJOR;
+               guc_fw->guc_fw_minor_wanted = BXT_FW_MINOR;
        } else if (IS_KABYLAKE(dev)) {
                fw_path = I915_KBL_GUC_UCODE;
-               guc_fw->guc_fw_major_wanted = 9;
-               guc_fw->guc_fw_minor_wanted = 14;
+               guc_fw->guc_fw_major_wanted = KBL_FW_MAJOR;
+               guc_fw->guc_fw_minor_wanted = KBL_FW_MINOR;
        } else {
                fw_path = "";   /* unknown device */
        }
@@ -738,12 +773,12 @@ void intel_guc_fini(struct drm_device *dev)
        struct intel_guc_fw *guc_fw = &dev_priv->guc.guc_fw;
 
        mutex_lock(&dev->struct_mutex);
-       direct_interrupts_to_host(dev_priv);
+       guc_interrupts_release(dev_priv);
        i915_guc_submission_disable(dev_priv);
        i915_guc_submission_fini(dev_priv);
 
        if (guc_fw->guc_fw_obj)
-               drm_gem_object_unreference(&guc_fw->guc_fw_obj->base);
+               i915_gem_object_put(guc_fw->guc_fw_obj);
        guc_fw->guc_fw_obj = NULL;
        mutex_unlock(&dev->struct_mutex);