[Intel-gfx] [PATCH 9/9] drm/i915/uc: Unify uC firmware upload
Chris Wilson
chris at chris-wilson.co.uk
Tue Jul 23 08:45:21 UTC 2019
Quoting Daniele Ceraolo Spurio (2019-07-23 00:20:48)
> The way we load the firmwares is the same for both GuC and HuC, the only
> difference is in the wopcm destination address and the dma flags, so we
> easily can move the logic to a common function and pass in offset and
> flags. The only other difference in the uplaod path are some the extra
> steps that guc does before and after the xfer, but those don't require
> the guc fw to be pinned in ggtt and can safely be performed before
> calling the uc_upload function.
>
> Note that this patch re-introduces the dma xfer wait for guc loading that
> was removed with "drm/i915/guc: Propagate the fw xfer timeout". This is
> not going to slow us down on a successful load (the dma has to complete
> before fw init can start), but could slightly increase the timeout in case
> of a fw init error.
Should not be a problem if all is well. And if not, picking up on an
error earlier is beneficial.
> +static int uc_fw_xfer(struct intel_uc_fw *uc_fw, struct intel_gt *gt,
> + u32 wopcm_offset, u32 dma_flags)
> +{
> + struct intel_uncore *uncore = gt->uncore;
> + u64 offset;
> + int ret;
> +
> + intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL);
> +
> + /* Set the source address for the uCode */
> + offset = uc_fw_ggtt_offset(uc_fw, gt->ggtt) + uc_fw->header_offset;
> + GEM_BUG_ON(upper_32_bits(offset) & 0xFFFF0000);
> + intel_uncore_write(uncore, DMA_ADDR_0_LOW, lower_32_bits(offset));
You've taken an explicit fw, so these can all be _fw.
> + intel_uncore_write(uncore, DMA_ADDR_0_HIGH, upper_32_bits(offset));
> +
> + /* Set the DMA destination */
> + intel_uncore_write(uncore, DMA_ADDR_1_LOW, wopcm_offset);
> + intel_uncore_write(uncore, DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
> +
> + /*
> + * Set the trasfer size. The header plus uCode will be copied to WOPCM
> + * via DMA, excluding any other components
> + */
> + intel_uncore_write(uncore, DMA_COPY_SIZE,
> + uc_fw->header_size + uc_fw->ucode_size);
> +
> + /* Start the DMA */
> + intel_uncore_write(uncore, DMA_CTRL,
> + _MASKED_BIT_ENABLE(dma_flags | START_DMA));
> +
> + /* Wait for DMA to finish */
> + ret = intel_wait_for_register_fw(uncore, DMA_CTRL, START_DMA, 0, 100);
> + if (ret)
> + DRM_ERROR("DMA for %s fw failed, err=%d\n",
> + intel_uc_fw_type_repr(uc_fw->type), ret);
> +
> + /* Disable the bits once DMA is over */
> + intel_uncore_write(uncore, DMA_CTRL, _MASKED_BIT_DISABLE(dma_flags));
> +
> + intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
> +
> + return ret;
> +}
More information about the Intel-gfx
mailing list