[Intel-gfx] [PATCH 1/6] drm/i915/uc: Introduce GSC FW
Jani Nikula
jani.nikula at linux.intel.com
Tue Nov 22 09:03:30 UTC 2022
On Mon, 21 Nov 2022, Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com> wrote:
> On MTL the GSC FW needs to be loaded on the media GT by the graphics
> driver. We're going to treat it like a new uc_fw, so add the initial
> defs and init/fini functions for it.
>
> Similarly to the other FWs, the GSC FW path can be overriden via
> modparam. The modparam can also be used to disable the GSC FW loading by
> setting it to an empty string.
>
> Note that the new structure has been called intel_gsc_uc to avoid
> confusion with the existing intel_gsc, which instead represents the heci
> gsc interfaces.
>
> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio at intel.com>
> Cc: Alan Previn <alan.previn.teres.alexis at intel.com>
> Cc: John Harrison <John.C.Harrison at Intel.com>
> ---
> drivers/gpu/drm/i915/Makefile | 3 +-
> drivers/gpu/drm/i915/gt/intel_gt.h | 5 ++
> drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 70 +++++++++++++++++++++++
> drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h | 36 ++++++++++++
> drivers/gpu/drm/i915/gt/uc/intel_uc.c | 17 ++++++
> drivers/gpu/drm/i915/gt/uc/intel_uc.h | 3 +
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 25 +++++++-
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h | 7 ++-
> drivers/gpu/drm/i915/i915_params.c | 3 +
> drivers/gpu/drm/i915/i915_params.h | 1 +
> 10 files changed, 164 insertions(+), 6 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
> create mode 100644 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 01974b82d205..92d37cf71e16 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -205,7 +205,8 @@ i915-y += gt/uc/intel_uc.o \
> gt/uc/intel_guc_submission.o \
> gt/uc/intel_huc.o \
> gt/uc/intel_huc_debugfs.o \
> - gt/uc/intel_huc_fw.o
> + gt/uc/intel_huc_fw.o \
> + gt/uc/intel_gsc_uc.o
Comment near the top of the file:
# Please keep these build lists sorted!
>
> # graphics system controller (GSC) support
> i915-y += gt/intel_gsc.o
> diff --git a/drivers/gpu/drm/i915/gt/intel_gt.h b/drivers/gpu/drm/i915/gt/intel_gt.h
> index e0365d556248..d2f4fbde5f9f 100644
> --- a/drivers/gpu/drm/i915/gt/intel_gt.h
> +++ b/drivers/gpu/drm/i915/gt/intel_gt.h
> @@ -39,6 +39,11 @@ static inline struct intel_gt *huc_to_gt(struct intel_huc *huc)
> return container_of(huc, struct intel_gt, uc.huc);
> }
>
> +static inline struct intel_gt *gsc_uc_to_gt(struct intel_gsc_uc *gsc_uc)
> +{
> + return container_of(gsc_uc, struct intel_gt, uc.gsc);
> +}
> +
> static inline struct intel_gt *gsc_to_gt(struct intel_gsc *gsc)
> {
> return container_of(gsc, struct intel_gt, gsc);
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
> new file mode 100644
> index 000000000000..65cbf1ce9fa1
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
> @@ -0,0 +1,70 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2022 Intel Corporation
> + */
> +
> +#include <linux/types.h>
> +
> +#include "gt/intel_gt.h"
> +#include "intel_gsc_uc.h"
> +#include "i915_drv.h"
> +
> +static bool gsc_engine_supported(struct intel_gt *gt)
> +{
> + intel_engine_mask_t mask;
> +
> + /*
> + * We reach here from i915_driver_early_probe for the primary GT before
> + * its engine mask is set, so we use the device info engine mask for it.
> + * For other GTs we expect the GT-specific mask to be set before we
> + * call this function.
> + */
> + GEM_BUG_ON(!gt_is_root(gt) && !gt->info.engine_mask);
> +
> + if (gt_is_root(gt))
> + mask = RUNTIME_INFO(gt->i915)->platform_engine_mask;
> + else
> + mask = gt->info.engine_mask;
> +
> + return __HAS_ENGINE(mask, GSC0);
> +}
> +
> +void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc)
> +{
> + intel_uc_fw_init_early(&gsc->fw, INTEL_UC_FW_TYPE_GSC);
> +
> + /* we can arrive here from i915_driver_early_probe for primary
> + * GT with it being not fully setup hence check device info's
> + * engine mask
> + */
> + if (!gsc_engine_supported(gsc_uc_to_gt(gsc))){
> + intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_NOT_SUPPORTED);
> + return;
> + }
> +}
> +
> +int intel_gsc_uc_init(struct intel_gsc_uc *gsc)
> +{
> + struct drm_i915_private *i915 = gsc_uc_to_gt(gsc)->i915;
> + int err;
> +
> + err = intel_uc_fw_init(&gsc->fw);
> + if (err)
> + goto out;
> +
> + intel_uc_fw_change_status(&gsc->fw, INTEL_UC_FIRMWARE_LOADABLE);
> +
> + return 0;
> +
> +out:
> + i915_probe_error(i915, "failed with %d\n", err);
> + return err;
> +}
> +
> +void intel_gsc_uc_fini(struct intel_gsc_uc *gsc)
> +{
> + if (!intel_uc_fw_is_loadable(&gsc->fw))
> + return;
> +
> + intel_uc_fw_fini(&gsc->fw);
> +}
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
> new file mode 100644
> index 000000000000..ea2b1c0713b8
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.h
> @@ -0,0 +1,36 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2022 Intel Corporation
> + */
> +
> +#ifndef _INTEL_GSC_UC_H_
> +#define _INTEL_GSC_UC_H_
> +
> +#include "intel_uc_fw.h"
> +
> +struct intel_gsc_uc {
> + /* Generic uC firmware management */
> + struct intel_uc_fw fw;
> +};
> +
> +void intel_gsc_uc_init_early(struct intel_gsc_uc *gsc);
> +int intel_gsc_uc_init(struct intel_gsc_uc *gsc);
> +void intel_gsc_uc_fini(struct intel_gsc_uc *gsc);
> +
> +static inline bool intel_gsc_uc_is_supported(struct intel_gsc_uc *gsc)
> +{
> + return intel_uc_fw_is_supported(&gsc->fw);
> +}
> +
> +static inline bool intel_gsc_uc_is_wanted(struct intel_gsc_uc *gsc)
> +{
> + return intel_uc_fw_is_enabled(&gsc->fw);
> +}
> +
> +static inline bool intel_gsc_uc_is_used(struct intel_gsc_uc *gsc)
> +{
> + GEM_BUG_ON(__intel_uc_fw_status(&gsc->fw) == INTEL_UC_FIRMWARE_SELECTED);
> + return intel_uc_fw_is_available(&gsc->fw);
> +}
> +
> +#endif
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> index 1d28286e6f06..622935770aa1 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> @@ -7,6 +7,7 @@
>
> #include "gt/intel_gt.h"
> #include "gt/intel_reset.h"
> +#include "intel_gsc_uc.h"
> #include "intel_guc.h"
> #include "intel_guc_ads.h"
> #include "intel_guc_submission.h"
> @@ -126,6 +127,7 @@ void intel_uc_init_early(struct intel_uc *uc)
>
> intel_guc_init_early(&uc->guc);
> intel_huc_init_early(&uc->huc);
> + intel_gsc_uc_init_early(&uc->gsc);
>
> __confirm_options(uc);
>
> @@ -296,15 +298,26 @@ static void __uc_fetch_firmwares(struct intel_uc *uc)
> INTEL_UC_FIRMWARE_ERROR);
> }
>
> + if (intel_uc_wants_gsc_uc(uc)) {
> + drm_dbg(&uc_to_gt(uc)->i915->drm,
> + "Failed to fetch GuC: %d disabling GSC\n", err);
> + intel_uc_fw_change_status(&uc->gsc.fw,
> + INTEL_UC_FIRMWARE_ERROR);
> + }
> +
> return;
> }
>
> if (intel_uc_wants_huc(uc))
> intel_uc_fw_fetch(&uc->huc.fw);
> +
> + if (intel_uc_wants_gsc_uc(uc))
> + intel_uc_fw_fetch(&uc->gsc.fw);
> }
>
> static void __uc_cleanup_firmwares(struct intel_uc *uc)
> {
> + intel_uc_fw_cleanup_fetch(&uc->gsc.fw);
> intel_uc_fw_cleanup_fetch(&uc->huc.fw);
> intel_uc_fw_cleanup_fetch(&uc->guc.fw);
> }
> @@ -330,11 +343,15 @@ static int __uc_init(struct intel_uc *uc)
> if (intel_uc_uses_huc(uc))
> intel_huc_init(huc);
>
> + if (intel_uc_uses_gsc_uc(uc))
> + intel_gsc_uc_init(&uc->gsc);
> +
> return 0;
> }
>
> static void __uc_fini(struct intel_uc *uc)
> {
> + intel_gsc_uc_fini(&uc->gsc);
> intel_huc_fini(&uc->huc);
> intel_guc_fini(&uc->guc);
> }
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
> index a8f38c2c60e2..5d0f1bcc381e 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
> @@ -6,6 +6,7 @@
> #ifndef _INTEL_UC_H_
> #define _INTEL_UC_H_
>
> +#include "intel_gsc_uc.h"
And thus intel_gsc_uc.h becomes another file that causes the entire
driver to be rebuilt when modified.
*sad trombone*
> #include "intel_guc.h"
> #include "intel_guc_rc.h"
> #include "intel_guc_submission.h"
> @@ -27,6 +28,7 @@ struct intel_uc_ops {
>
> struct intel_uc {
> struct intel_uc_ops const *ops;
> + struct intel_gsc_uc gsc;
> struct intel_guc guc;
> struct intel_huc huc;
>
> @@ -87,6 +89,7 @@ uc_state_checkers(huc, huc);
> uc_state_checkers(guc, guc_submission);
> uc_state_checkers(guc, guc_slpc);
> uc_state_checkers(guc, guc_rc);
> +uc_state_checkers(gsc, gsc_uc);
>
> #undef uc_state_checkers
> #undef __uc_state_checker
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index 0c80ba51a4bd..5b2e4503aee7 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -19,11 +19,18 @@
> static inline struct intel_gt *
> ____uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
> {
> - if (type == INTEL_UC_FW_TYPE_GUC)
> + GEM_BUG_ON(type >= INTEL_UC_FW_NUM_TYPES);
> +
> + switch (type) {
> + case INTEL_UC_FW_TYPE_GUC:
> return container_of(uc_fw, struct intel_gt, uc.guc.fw);
> + case INTEL_UC_FW_TYPE_HUC:
> + return container_of(uc_fw, struct intel_gt, uc.huc.fw);
> + case INTEL_UC_FW_TYPE_GSC:
> + return container_of(uc_fw, struct intel_gt, uc.gsc.fw);
> + }
>
> - GEM_BUG_ON(type != INTEL_UC_FW_TYPE_HUC);
> - return container_of(uc_fw, struct intel_gt, uc.huc.fw);
> + return NULL;
> }
>
> static inline struct intel_gt *__uc_fw_to_gt(struct intel_uc_fw *uc_fw)
> @@ -246,6 +253,10 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
> int i;
> bool found;
>
> + /* FW is not defined until all the support is in place */
> + if (uc_fw->type == INTEL_UC_FW_TYPE_GSC)
> + return;
> +
> /*
> * The only difference between the ADL GuC FWs is the HWConfig support.
> * ADL-N does not support HWConfig, so we should use the same binary as
> @@ -374,6 +385,11 @@ static const char *__override_huc_firmware_path(struct drm_i915_private *i915)
> return "";
> }
>
> +static const char *__override_gsc_firmware_path(struct drm_i915_private *i915)
> +{
> + return i915->params.gsc_firmware_path;
> +}
> +
> static void __uc_fw_user_override(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
> {
> const char *path = NULL;
> @@ -385,6 +401,9 @@ static void __uc_fw_user_override(struct drm_i915_private *i915, struct intel_uc
> case INTEL_UC_FW_TYPE_HUC:
> path = __override_huc_firmware_path(i915);
> break;
> + case INTEL_UC_FW_TYPE_GSC:
> + path = __override_gsc_firmware_path(i915);
> + break;
> }
>
> if (unlikely(path)) {
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> index bc898ba5355d..5d2a8965a592 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h
> @@ -61,9 +61,10 @@ enum intel_uc_fw_status {
>
> enum intel_uc_fw_type {
> INTEL_UC_FW_TYPE_GUC = 0,
> - INTEL_UC_FW_TYPE_HUC
> + INTEL_UC_FW_TYPE_HUC,
> + INTEL_UC_FW_TYPE_GSC,
> };
> -#define INTEL_UC_FW_NUM_TYPES 2
> +#define INTEL_UC_FW_NUM_TYPES 3
>
> /*
> * The firmware build process will generate a version header file with major and
> @@ -205,6 +206,8 @@ static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type)
> return "GuC";
> case INTEL_UC_FW_TYPE_HUC:
> return "HuC";
> + case INTEL_UC_FW_TYPE_GSC:
> + return "GSC";
> }
> return "uC";
> }
> diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c
> index d1e4d528cb17..61578f2860cd 100644
> --- a/drivers/gpu/drm/i915/i915_params.c
> +++ b/drivers/gpu/drm/i915/i915_params.c
> @@ -192,6 +192,9 @@ i915_param_named_unsafe(huc_firmware_path, charp, 0400,
> i915_param_named_unsafe(dmc_firmware_path, charp, 0400,
> "DMC firmware path to use instead of the default one");
>
> +i915_param_named_unsafe(gsc_firmware_path, charp, 0400,
> + "GSC firmware path to use instead of the default one");
> +
> i915_param_named_unsafe(enable_dp_mst, bool, 0400,
> "Enable multi-stream transport (MST) for new DisplayPort sinks. (default: true)");
>
> diff --git a/drivers/gpu/drm/i915/i915_params.h b/drivers/gpu/drm/i915/i915_params.h
> index 2733cb6cfe09..3f51f90145b6 100644
> --- a/drivers/gpu/drm/i915/i915_params.h
> +++ b/drivers/gpu/drm/i915/i915_params.h
> @@ -64,6 +64,7 @@ struct drm_printer;
> param(char *, guc_firmware_path, NULL, 0400) \
> param(char *, huc_firmware_path, NULL, 0400) \
> param(char *, dmc_firmware_path, NULL, 0400) \
> + param(char *, gsc_firmware_path, NULL, 0400) \
> param(bool, memtest, false, 0400) \
> param(int, mmio_debug, -IS_ENABLED(CONFIG_DRM_I915_DEBUG_MMIO), 0600) \
> param(int, edp_vswing, 0, 0400) \
--
Jani Nikula, Intel Open Source Graphics Center
More information about the dri-devel
mailing list