|
@@ -207,3 +207,67 @@ int intel_wopcm_init(struct intel_wopcm *wopcm)
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
+
|
|
|
+static inline int write_and_verify(struct drm_i915_private *dev_priv,
|
|
|
+ i915_reg_t reg, u32 val, u32 mask,
|
|
|
+ u32 locked_bit)
|
|
|
+{
|
|
|
+ u32 reg_val;
|
|
|
+
|
|
|
+ GEM_BUG_ON(val & ~mask);
|
|
|
+
|
|
|
+ I915_WRITE(reg, val);
|
|
|
+
|
|
|
+ reg_val = I915_READ(reg);
|
|
|
+
|
|
|
+ return (reg_val & mask) != (val | locked_bit) ? -EIO : 0;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * intel_wopcm_init_hw() - Setup GuC WOPCM registers.
|
|
|
+ * @wopcm: pointer to intel_wopcm.
|
|
|
+ *
|
|
|
+ * Setup the GuC WOPCM size and offset registers with the calculated values. It
|
|
|
+ * will verify the register values to make sure the registers are locked with
|
|
|
+ * correct values.
|
|
|
+ *
|
|
|
+ * Return: 0 on success. -EIO if registers were locked with incorrect values.
|
|
|
+ */
|
|
|
+int intel_wopcm_init_hw(struct intel_wopcm *wopcm)
|
|
|
+{
|
|
|
+ struct drm_i915_private *dev_priv = wopcm_to_i915(wopcm);
|
|
|
+ u32 huc_agent;
|
|
|
+ u32 mask;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ if (!USES_GUC(dev_priv))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ GEM_BUG_ON(!HAS_GUC(dev_priv));
|
|
|
+ GEM_BUG_ON(!wopcm->guc.size);
|
|
|
+ GEM_BUG_ON(!wopcm->guc.base);
|
|
|
+
|
|
|
+ err = write_and_verify(dev_priv, GUC_WOPCM_SIZE, wopcm->guc.size,
|
|
|
+ GUC_WOPCM_SIZE_MASK | GUC_WOPCM_SIZE_LOCKED,
|
|
|
+ GUC_WOPCM_SIZE_LOCKED);
|
|
|
+ if (err)
|
|
|
+ goto err_out;
|
|
|
+
|
|
|
+ huc_agent = USES_HUC(dev_priv) ? HUC_LOADING_AGENT_GUC : 0;
|
|
|
+ mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent;
|
|
|
+ err = write_and_verify(dev_priv, DMA_GUC_WOPCM_OFFSET,
|
|
|
+ wopcm->guc.base | huc_agent, mask,
|
|
|
+ GUC_WOPCM_OFFSET_VALID);
|
|
|
+ if (err)
|
|
|
+ goto err_out;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+
|
|
|
+err_out:
|
|
|
+ DRM_ERROR("Failed to init WOPCM registers:\n");
|
|
|
+ DRM_ERROR("DMA_GUC_WOPCM_OFFSET=%#x\n",
|
|
|
+ I915_READ(DMA_GUC_WOPCM_OFFSET));
|
|
|
+ DRM_ERROR("GUC_WOPCM_SIZE=%#x\n", I915_READ(GUC_WOPCM_SIZE));
|
|
|
+
|
|
|
+ return err;
|
|
|
+}
|