drm/i915/guc: Fix a bug in GuC status check
authorAlex Dai <yu.dai@intel.com>
Tue, 22 Sep 2015 20:48:40 +0000 (13:48 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 30 Sep 2015 08:20:00 +0000 (10:20 +0200)
Bit 16 of GuC status indicates resuming from RC6. The LAPIC_DONE
status is a reliable readiness flag only when resuming from RC6.
This fix a racing issue that allocation of doorbell fails whilst
GuC init is not finished.

Signed-off-by: Alex Dai <yu.dai@intel.com>
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_guc_reg.h
drivers/gpu/drm/i915/intel_guc_loader.c

index 9d79a6b7cc2fad0fd3023a1d0262469c985e1e5b..b35566164c4d9bfffa3e81d746b83ef7b8a7b6c4 100644 (file)
@@ -37,6 +37,7 @@
 #define   GS_UKERNEL_READY               (0xF0 << GS_UKERNEL_SHIFT)
 #define   GS_MIA_SHIFT                 16
 #define   GS_MIA_MASK                    (0x07 << GS_MIA_SHIFT)
+#define   GS_MIA_CORE_STATE              (1 << GS_MIA_SHIFT)
 
 #define SOFT_SCRATCH(n)                        (0xc180 + ((n) * 4))
 
index e0601cc5a7952e55117bd8f8e47265047c088390..40241f37e24b94bfe37f3de4e1cc799e6e4e98b4 100644 (file)
@@ -209,9 +209,10 @@ static inline bool guc_ucode_response(struct drm_i915_private *dev_priv,
                                      u32 *status)
 {
        u32 val = I915_READ(GUC_STATUS);
+       u32 uk_val = val & GS_UKERNEL_MASK;
        *status = val;
-       return ((val & GS_UKERNEL_MASK) == GS_UKERNEL_READY ||
-               (val & GS_UKERNEL_MASK) == GS_UKERNEL_LAPIC_DONE);
+       return (uk_val == GS_UKERNEL_READY ||
+               ((val & GS_MIA_CORE_STATE) && uk_val == GS_UKERNEL_LAPIC_DONE));
 }
 
 /*