[Intel-gfx] [PATCH 3/8] drm/i915/huc: Add HuC fw loading support
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Fri Dec 16 16:40:47 UTC 2016
On 16/12/2016 16:29, Arkadiusz Hiler wrote:
> On Fri, Dec 16, 2016 at 04:13:14PM +0000, Tvrtko Ursulin wrote:
>>
>> On 15/12/2016 22:29, anushasr wrote:
>>> From: Anusha Srivatsa <anusha.srivatsa at intel.com>
>>>
>>> The HuC loading process is similar to GuC. The intel_uc_fw_fetch()
>>> is used for both cases.
>>>
>>> HuC loading needs to be before GuC loading. The WOPCM setting must
>>> be done early before loading any of them.
>>>
>>> v2: rebased on-top of drm-intel-nightly.
>>> removed if(HAS_GUC()) before the guc call. (D.Gordon)
>>> update huc_version number of format.
>>> v3: rebased to drm-intel-nightly, changed the file name format to
>>> match the one in the huc package.
>>> Changed dev->dev_private to to_i915()
>>> v4: moved function back to where it was.
>>> change wait_for_atomic to wait_for.
>>> v5: rebased + comment changes.
>>> v7: rebased.
>>> v8: rebased.
>>> v9: rebased. Changed the year in the copyright message to reflect
>>> the right year.Correct the comments,remove the unwanted WARN message,
>>> replace drm_gem_object_unreference() with i915_gem_object_put().Make the
>>> prototypes in intel_huc.h non-extern.
>>> v10: rebased. Update the file construction done by HuC. It is similar to
>>> GuC.Adopted the approach used in-
>>> https://patchwork.freedesktop.org/patch/104355/ <Tvrtko Ursulin>
>>> v11: Fix warnings remove old declaration
>>> v12: Change dev to dev_priv in macro definition.
>>> Corrected comments.
>>> v13: rebased.
>>> v14: rebased on top of drm-tip
>>> v15: rebased. Updated functions intel_huc_load(),intel_huc_init() and
>>> intel_uc_fw_fetch() to accept dev_priv instead of dev. Moved contents
>>> of intel_huc.h to intel_uc.h
>>> v16: change SKL_FW_ to SKL_HUC_FW_. Add intel_ prefix to guc_wopcm_size().
>>> Remove unwanted checks in intel_uc.h. Rename huc_fw in struct intel_huc to
>>> simply fw to avoid redundency.
>>>
>>> Cc: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
>>> Tested-by: Xiang Haihao <haihao.xiang at intel.com>
>>> Signed-off-by: Anusha Srivatsa <anusha.srivatsa at intel.com>
>>> Signed-off-by: Alex Dai <yu.dai at intel.com>
>>> Signed-off-by: Peter Antoine <peter.antoine at intel.com>
>>> ---
>>> drivers/gpu/drm/i915/Makefile | 1 +
>>> drivers/gpu/drm/i915/i915_drv.c | 4 +-
>>> drivers/gpu/drm/i915/i915_drv.h | 3 +-
>>> drivers/gpu/drm/i915/i915_guc_reg.h | 3 +
>>> drivers/gpu/drm/i915/intel_guc_loader.c | 11 +-
>>> drivers/gpu/drm/i915/intel_huc_loader.c | 264 ++++++++++++++++++++++++++++++++
>>> drivers/gpu/drm/i915/intel_uc.h | 18 +++
>>> 7 files changed, 297 insertions(+), 7 deletions(-)
>>> create mode 100644 drivers/gpu/drm/i915/intel_huc_loader.c
>>>
>>> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
>>> index 5196509..45ae124 100644
>>> --- a/drivers/gpu/drm/i915/Makefile
>>> +++ b/drivers/gpu/drm/i915/Makefile
>>> @@ -57,6 +57,7 @@ i915-y += i915_cmd_parser.o \
>>> # general-purpose microcontroller (GuC) support
>>> i915-y += intel_uc.o \
>>> intel_guc_loader.o \
>>> + intel_huc_loader.o \
>>> i915_guc_submission.o
>>>
>>> # autogenerated null render state
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
>>> index 6428588..85a47c2 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.c
>>> +++ b/drivers/gpu/drm/i915/i915_drv.c
>>> @@ -600,6 +600,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
>>> if (ret)
>>> goto cleanup_irq;
>>>
>>> + intel_huc_init(dev_priv);
>>> intel_guc_init(dev_priv);
>>>
>>> ret = i915_gem_init(dev_priv);
>>> @@ -627,6 +628,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
>>> DRM_ERROR("failed to idle hardware; continuing to unload!\n");
>>> i915_gem_fini(dev_priv);
>>> cleanup_irq:
>>> + intel_huc_fini(dev);
>>> intel_guc_fini(dev_priv);
>>> drm_irq_uninstall(dev);
>>> intel_teardown_gmbus(dev_priv);
>>> @@ -1313,7 +1315,7 @@ void i915_driver_unload(struct drm_device *dev)
>>>
>>> /* Flush any outstanding unpin_work. */
>>> drain_workqueue(dev_priv->wq);
>>> -
>>> + intel_huc_fini(dev);
>>> intel_guc_fini(dev_priv);
>>> i915_gem_fini(dev_priv);
>>> intel_fbc_cleanup_cfb(dev_priv);
>>> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
>>> index 4199d26..bd5f235 100644
>>> --- a/drivers/gpu/drm/i915/i915_drv.h
>>> +++ b/drivers/gpu/drm/i915/i915_drv.h
>>> @@ -2134,6 +2134,7 @@ struct drm_i915_private {
>>>
>>> struct intel_gvt *gvt;
>>>
>>> + struct intel_huc huc;
>>> struct intel_guc guc;
>>>
>>> struct intel_csr csr;
>>> @@ -2908,7 +2909,7 @@ intel_info(const struct drm_i915_private *dev_priv)
>>> #define HAS_GUC(dev_priv) ((dev_priv)->info.has_guc)
>>> #define HAS_GUC_UCODE(dev_priv) (HAS_GUC(dev_priv))
>>> #define HAS_GUC_SCHED(dev_priv) (HAS_GUC(dev_priv))
>>> -
>>> +#define HAS_HUC_UCODE(dev_priv) (HAS_GUC(dev_priv))
>>> #define HAS_RESOURCE_STREAMER(dev_priv) ((dev_priv)->info.has_resource_streamer)
>>>
>>> #define HAS_POOLED_EU(dev_priv) ((dev_priv)->info.has_pooled_eu)
>>> diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h
>>> index 5e638fc..f9829f6 100644
>>> --- a/drivers/gpu/drm/i915/i915_guc_reg.h
>>> +++ b/drivers/gpu/drm/i915/i915_guc_reg.h
>>> @@ -61,9 +61,12 @@
>>> #define DMA_ADDRESS_SPACE_GTT (8 << 16)
>>> #define DMA_COPY_SIZE _MMIO(0xc310)
>>> #define DMA_CTRL _MMIO(0xc314)
>>> +#define HUC_UKERNEL (1<<9)
>>> #define UOS_MOVE (1<<4)
>>> #define START_DMA (1<<0)
>>> #define DMA_GUC_WOPCM_OFFSET _MMIO(0xc340)
>>> +#define HUC_LOADING_AGENT_VCR (0<<1)
>>> +#define HUC_LOADING_AGENT_GUC (1<<1)
>>> #define GUC_WOPCM_OFFSET_VALUE 0x80000 /* 512KB */
>>> #define GUC_MAX_IDLE_COUNT _MMIO(0xC3E4)
>>>
>>> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
>>> index 09e463b..2257495 100644
>>> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
>>> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
>>> @@ -309,8 +309,8 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
>>> I915_WRITE(DMA_ADDR_1_HIGH, DMA_ADDRESS_SPACE_WOPCM);
>>>
>>> /* Finally start the DMA */
>>> - I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA));
>>> -
>>> + I915_WRITE(DMA_CTRL, _MASKED_BIT_ENABLE(UOS_MOVE | START_DMA) |
>>> + _MASKED_BIT_DISABLE(HUC_UKERNEL));
>>> /*
>>> * Wait for the DMA to complete & the GuC to start up.
>>> * NB: Docs recommend not using the interrupt for completion.
>>> @@ -334,7 +334,7 @@ static int guc_ucode_xfer_dma(struct drm_i915_private *dev_priv,
>>> return ret;
>>> }
>>>
>>> -static u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
>>> +u32 intel_guc_wopcm_size(struct drm_i915_private *dev_priv)
>>> {
>>> u32 wopcm_size = GUC_WOPCM_TOP;
>>>
>>> @@ -372,7 +372,7 @@ static int guc_ucode_xfer(struct drm_i915_private *dev_priv)
>>> intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
>>>
>>> /* init WOPCM */
>>> - I915_WRITE(GUC_WOPCM_SIZE, guc_wopcm_size(dev_priv));
>>> + I915_WRITE(GUC_WOPCM_SIZE, intel_guc_wopcm_size(dev_priv));
>>> I915_WRITE(DMA_GUC_WOPCM_OFFSET, GUC_WOPCM_OFFSET_VALUE);
>>>
>>> /* Enable MIA caching. GuC clock gating is disabled. */
>>> @@ -511,6 +511,7 @@ int intel_guc_setup(struct drm_i915_private *dev_priv)
>>> if (err)
>>> goto fail;
>>>
>>> + intel_huc_load(dev_priv);
>>> err = guc_ucode_xfer(dev_priv);
>>
>> Out of curiosity - how come it is OK to load HuC before the GuC, if the HuC
>> needs the GuC?
>
> You just do the DMA transfer of the code to the memory and some initial
> setup, by any means it's not ready yet.
>
> Then, you have to load GuC, which picks up that HuC is there and handles
> it presence internally (has to do with the checksums and signing
> verification).
>
> From what I've seen this must be the exact ordering.
>
> Then, when you have both in place, you can trigger authentication of
> HuC. Only after GuC has authed HuC successfully it's ready - you can
> start issuing HUC_* CS instructions.
Cool, thanks for explaining it.
Regards,
Tvrtko
More information about the Intel-gfx
mailing list