Re: [PATCH v3 3/6] drm/i915/huc: Add HuC fw loading support

Dave Gordon
2016-07-29T11:29:57Z

On 06/07/16 15:24, Peter Antoine wrote:
> 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_provate to to_i915()
>
> Signed-off-by: Alex Dai <yu.dai@intel.com>
> Signed-off-by: Peter Antoine <peter.antoine@intel.com>
> ---
> drivers/gpu/drm/i915/Makefile | 1 +
> drivers/gpu/drm/i915/i915_drv.c | 3 +
> drivers/gpu/drm/i915/i915_drv.h | 3 +
> drivers/gpu/drm/i915/i915_guc_reg.h | 3 +
> drivers/gpu/drm/i915/intel_guc.h | 1 +
> drivers/gpu/drm/i915/intel_guc_loader.c | 26 ++--
> drivers/gpu/drm/i915/intel_huc.h | 44 ++++++
> drivers/gpu/drm/i915/intel_huc_loader.c | 267 ++++++++++++++++++++++++++++++++
> 8 files changed, 336 insertions(+), 12 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/intel_huc.h
> 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 684fc1c..0939b90 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -47,6 +47,7 @@ i915-y += i915_cmd_parser.o \
>
> # general-purpose microcontroller (GuC) support
> i915-y += 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 694edac..72655bf 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -645,6 +645,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
> * working irqs for e.g. gmbus and dp aux transfers. */
> intel_modeset_init(dev);
>
> + intel_huc_init(dev);
> intel_guc_init(dev);
>
> ret = i915_gem_init(dev);
> @@ -670,6 +671,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
> cleanup_gem:
> i915_gem_fini(dev);
> cleanup_irq:
> + intel_huc_fini(dev);
> intel_guc_fini(dev);
> drm_irq_uninstall(dev);
> intel_teardown_gmbus(dev);
> @@ -1341,6 +1343,7 @@ void i915_driver_unload(struct drm_device *dev)
> /* Flush any outstanding unpin_work. */
> flush_workqueue(dev_priv->wq);
>
> + intel_huc_fini(dev);
> intel_guc_fini(dev);
> i915_gem_fini(dev);
> 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 d2c6099..77039b9 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -55,6 +55,7 @@
> #include "intel_bios.h"
> #include "intel_dpll_mgr.h"
> #include "intel_guc.h"
> +#include "intel_huc.h"
> #include "intel_lrc.h"
> #include "intel_ringbuffer.h"
>
> @@ -1739,6 +1740,7 @@ struct drm_i915_private {
>
> struct intel_gvt gvt;
>
> + struct intel_huc huc;
> struct intel_guc guc;
>
> struct intel_csr csr;
> @@ -2865,6 +2867,7 @@ struct drm_i915_cmd_table {
> #define HAS_GUC(dev) (IS_GEN9(dev))
> #define HAS_GUC_UCODE(dev) (HAS_GUC(dev))
> #define HAS_GUC_SCHED(dev) (HAS_GUC(dev))
> +#define HAS_HUC_UCODE(dev) (HAS_GUC(dev))
>
> #define HAS_RESOURCE_STREAMER(dev) (IS_HASWELL(dev) || \
> INTEL_INFO(dev)->gen >= 8)
> diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h
> index cf5a65b..51533f1 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.h b/drivers/gpu/drm/i915/intel_guc.h
> index ebf9c8d..c7b2745 100644
> --- a/drivers/gpu/drm/i915/intel_guc.h
> +++ b/drivers/gpu/drm/i915/intel_guc.h
> @@ -160,6 +160,7 @@ extern const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status);
> extern int intel_guc_suspend(struct drm_device *dev);
> extern int intel_guc_resume(struct drm_device *dev);
> void intel_uc_fw_fetch(struct drm_device *dev, struct intel_uc_fw *uc_fw);
> +u32 guc_wopcm_size(struct drm_i915_private *dev_priv);
>
> /* i915_guc_submission.c */
> int i915_guc_submission_init(struct drm_i915_private *dev_priv);
> diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c
> index 42b6509..d76451c 100644
> --- a/drivers/gpu/drm/i915/intel_guc_loader.c
> +++ b/drivers/gpu/drm/i915/intel_guc_loader.c
> @@ -85,6 +85,17 @@ const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
> }
> };
>
> +u32 guc_wopcm_size(struct drm_i915_private *dev_priv)
> +{
> + u32 wopcm_size = GUC_WOPCM_TOP;
> +
> + /* On BXT, the top of WOPCM is reserved for RC6 context */
> + if (IS_BROXTON(dev_priv))
> + wopcm_size -= BXT_GUC_WOPCM_RC6_RESERVED;
> +
> + return wopcm_size;
> +}

I know this function is being made visible externally, but I don't think
that requires it to be moved to the top of the file.

> static void direct_interrupts_to_host(struct drm_i915_private *dev_priv)
> {
> struct intel_engine_cs *engine;
> @@ -272,7 +283,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.
> @@ -297,17 +309,6 @@ 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 wopcm_size = GUC_WOPCM_TOP;
> -
> - /* On BXT, the top of WOPCM is reserved for RC6 context */
> - if (IS_BROXTON(dev_priv))
> - wopcm_size -= BXT_GUC_WOPCM_RC6_RESERVED;
> -
> - return wopcm_size;
> -}

This function was perfectly OK where it was.

Otherwise generally OK.

.Dave.