__uc_sanitize(uc);
}
+/* Initialize and verify the uC regs related to uC positioning in WOPCM */
+static int uc_init_wopcm(struct intel_uc *uc)
+{
+ struct intel_gt *gt = uc_to_gt(uc);
+ struct intel_uncore *uncore = gt->uncore;
+ u32 base = intel_wopcm_guc_base(>->i915->wopcm);
+ u32 size = intel_wopcm_guc_size(>->i915->wopcm);
+ u32 huc_agent = intel_uc_is_using_huc(uc) ? HUC_LOADING_AGENT_GUC : 0;
+ u32 mask;
+ int err;
+
+ GEM_BUG_ON(!intel_uc_is_using_guc(uc));
+ GEM_BUG_ON(!(base & GUC_WOPCM_OFFSET_MASK));
+ GEM_BUG_ON(base & ~GUC_WOPCM_OFFSET_MASK);
+ GEM_BUG_ON(!(size & GUC_WOPCM_SIZE_MASK));
+ GEM_BUG_ON(size & ~GUC_WOPCM_SIZE_MASK);
+
+ mask = GUC_WOPCM_SIZE_MASK | GUC_WOPCM_SIZE_LOCKED;
+ err = intel_uncore_write_and_verify(uncore, GUC_WOPCM_SIZE, size, mask,
+ size | GUC_WOPCM_SIZE_LOCKED);
+ if (err)
+ goto err_out;
+
+ mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent;
+ err = intel_uncore_write_and_verify(uncore, DMA_GUC_WOPCM_OFFSET,
+ base | huc_agent, mask,
+ base | huc_agent |
+ GUC_WOPCM_OFFSET_VALID);
+ if (err)
+ goto err_out;
+
+ return 0;
+
+err_out:
+ DRM_ERROR("Failed to init uC WOPCM registers:\n");
+ DRM_ERROR("DMA_GUC_WOPCM_OFFSET=%#x\n",
+ intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
+ DRM_ERROR("GUC_WOPCM_SIZE=%#x\n",
+ intel_uncore_read(uncore, GUC_WOPCM_SIZE));
+
+ return err;
+}
+
int intel_uc_init_hw(struct intel_uc *uc)
{
struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
GEM_BUG_ON(!intel_uc_fw_supported(&guc->fw));
+ ret = uc_init_wopcm(uc);
+ if (ret)
+ goto err_out;
+
guc_reset_interrupts(guc);
/* WaEnableuKernelHeaderValidFix:skl */
#define HAS_GT_UC(dev_priv) (INTEL_INFO(dev_priv)->has_gt_uc)
-/* Having GuC/HuC is not the same as using GuC/HuC */
+/* Having GuC is not the same as using GuC */
#define USES_GUC(dev_priv) intel_uc_is_using_guc(&(dev_priv)->gt.uc)
#define USES_GUC_SUBMISSION(dev_priv) intel_uc_is_using_guc_submission(&(dev_priv)->gt.uc)
-#define USES_HUC(dev_priv) intel_uc_is_using_huc(&(dev_priv)->gt.uc)
#define HAS_POOLED_EU(dev_priv) (INTEL_INFO(dev_priv)->has_pooled_eu)
goto out;
}
- ret = intel_wopcm_init_hw(&i915->wopcm, gt);
- if (ret) {
- DRM_ERROR("Enabling WOPCM failed (%d)\n", ret);
- goto out;
- }
-
/* We can't enable contexts until all firmware is loaded */
- ret = intel_uc_init_hw(&i915->gt.uc);
+ ret = intel_uc_init_hw(>->uc);
if (ret) {
DRM_ERROR("Enabling uc failed (%d)\n", ret);
goto out;
intel_uncore_write_fw(uncore, reg, val);
}
+static inline int intel_uncore_write_and_verify(struct intel_uncore *uncore,
+ i915_reg_t reg, u32 val,
+ u32 mask, u32 expected_val)
+{
+ u32 reg_val;
+
+ intel_uncore_write(uncore, reg, val);
+ reg_val = intel_uncore_read(uncore, reg);
+
+ return (reg_val & mask) != expected_val ? -EINVAL : 0;
+}
+
#define raw_reg_read(base, reg) \
readl(base + i915_mmio_reg_offset(reg))
#define raw_reg_write(base, reg, value) \
return 0;
}
-
-static int
-write_and_verify(struct intel_gt *gt,
- i915_reg_t reg, u32 val, u32 mask, u32 locked_bit)
-{
- struct intel_uncore *uncore = gt->uncore;
- u32 reg_val;
-
- GEM_BUG_ON(val & ~mask);
-
- intel_uncore_write(uncore, reg, val);
-
- reg_val = intel_uncore_read(uncore, reg);
-
- return (reg_val & mask) != (val | locked_bit) ? -EIO : 0;
-}
-
-/**
- * intel_wopcm_init_hw() - Setup GuC WOPCM registers.
- * @wopcm: pointer to intel_wopcm.
- * @gt: pointer to the containing GT
- *
- * 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 intel_gt *gt)
-{
- struct drm_i915_private *i915 = wopcm_to_i915(wopcm);
- struct intel_uncore *uncore = gt->uncore;
- u32 huc_agent;
- u32 mask;
- int err;
-
- if (!USES_GUC(i915))
- return 0;
-
- GEM_BUG_ON(!HAS_GT_UC(i915));
- GEM_BUG_ON(!wopcm->guc.size);
- GEM_BUG_ON(!wopcm->guc.base);
-
- err = write_and_verify(gt, 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(i915) ? HUC_LOADING_AGENT_GUC : 0;
- mask = GUC_WOPCM_OFFSET_MASK | GUC_WOPCM_OFFSET_VALID | huc_agent;
- err = write_and_verify(gt, 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",
- intel_uncore_read(uncore, DMA_GUC_WOPCM_OFFSET));
- DRM_ERROR("GUC_WOPCM_SIZE=%#x\n",
- intel_uncore_read(uncore, GUC_WOPCM_SIZE));
-
- return err;
-}
#include <linux/types.h>
-struct intel_gt;
-
/**
* struct intel_wopcm - Overall WOPCM info and WOPCM regions.
* @size: Size of overall WOPCM.
};
/**
+ * intel_wopcm_guc_base()
+ * @wopcm: intel_wopcm structure
+ *
+ * Returns the base of the WOPCM shadowed region.
+ *
+ * Returns:
+ * 0 if GuC is not present or not in use.
+ * Otherwise, the GuC WOPCM base.
+ */
+static inline u32 intel_wopcm_guc_base(struct intel_wopcm *wopcm)
+{
+ return wopcm->guc.base;
+}
+
+/**
* intel_wopcm_guc_size()
* @wopcm: intel_wopcm structure
*
void intel_wopcm_init_early(struct intel_wopcm *wopcm);
int intel_wopcm_init(struct intel_wopcm *wopcm);
-int intel_wopcm_init_hw(struct intel_wopcm *wopcm, struct intel_gt *gt);
#endif