// SPDX-License-Identifier: MIT /* * Copyright © 2014-2019 Intel Corporation */ #include "gem/i915_gem_lmem.h" #include "gt/intel_gt.h" #include "gt/intel_gt_irq.h" #include "gt/intel_gt_pm_irq.h" #include "gt/intel_gt_regs.h" #include "intel_guc.h" #include "intel_guc_ads.h" #include "intel_guc_capture.h" #include "intel_guc_print.h" #include "intel_guc_slpc.h" #include "intel_guc_submission.h" #include "i915_drv.h" #include "i915_irq.h" #include "i915_reg.h" /** * DOC: GuC * * The GuC is a microcontroller inside the GT HW, introduced in gen9. The GuC is * designed to offload some of the functionality usually performed by the host * driver; currently the main operations it can take care of are: * * - Authentication of the HuC, which is required to fully enable HuC usage. * - Low latency graphics context scheduling (a.k.a. GuC submission). * - GT Power management. * * The enable_guc module parameter can be used to select which of those * operations to enable within GuC. Note that not all the operations are * supported on all gen9+ platforms. * * Enabling the GuC is not mandatory and therefore the firmware is only loaded * if at least one of the operations is selected. However, not loading the GuC * might result in the loss of some features that do require the GuC (currently * just the HuC, but more are expected to land in the future). */ void intel_guc_notify(struct intel_guc *guc) { … } static inline i915_reg_t guc_send_reg(struct intel_guc *guc, u32 i) { … } void intel_guc_init_send_regs(struct intel_guc *guc) { … } static void gen9_reset_guc_interrupts(struct intel_guc *guc) { … } static void gen9_enable_guc_interrupts(struct intel_guc *guc) { … } static void gen9_disable_guc_interrupts(struct intel_guc *guc) { … } static bool __gen11_reset_guc_interrupts(struct intel_gt *gt) { … } static void gen11_reset_guc_interrupts(struct intel_guc *guc) { … } static void gen11_enable_guc_interrupts(struct intel_guc *guc) { … } static void gen11_disable_guc_interrupts(struct intel_guc *guc) { … } static void guc_dead_worker_func(struct work_struct *w) { … } void intel_guc_init_early(struct intel_guc *guc) { … } void intel_guc_init_late(struct intel_guc *guc) { … } static u32 guc_ctl_debug_flags(struct intel_guc *guc) { … } static u32 guc_ctl_feature_flags(struct intel_guc *guc) { … } static u32 guc_ctl_log_params_flags(struct intel_guc *guc) { … } static u32 guc_ctl_ads_flags(struct intel_guc *guc) { … } static u32 guc_ctl_wa_flags(struct intel_guc *guc) { … } static u32 guc_ctl_devid(struct intel_guc *guc) { … } /* * Initialise the GuC parameter block before starting the firmware * transfer. These parameters are read by the firmware on startup * and cannot be changed thereafter. */ static void guc_init_params(struct intel_guc *guc) { … } /* * Initialise the GuC parameter block before starting the firmware * transfer. These parameters are read by the firmware on startup * and cannot be changed thereafter. */ void intel_guc_write_params(struct intel_guc *guc) { … } void intel_guc_dump_time_info(struct intel_guc *guc, struct drm_printer *p) { … } int intel_guc_init(struct intel_guc *guc) { … } void intel_guc_fini(struct intel_guc *guc) { … } /* * This function implements the MMIO based host to GuC interface. */ int intel_guc_send_mmio(struct intel_guc *guc, const u32 *request, u32 len, u32 *response_buf, u32 response_buf_size) { … } int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action) { … } int intel_guc_to_host_process_recv_msg(struct intel_guc *guc, const u32 *payload, u32 len) { … } /** * intel_guc_auth_huc() - Send action to GuC to authenticate HuC ucode * @guc: intel_guc structure * @rsa_offset: rsa offset w.r.t ggtt base of huc vma * * Triggers a HuC firmware authentication request to the GuC via intel_guc_send * INTEL_GUC_ACTION_AUTHENTICATE_HUC interface. This function is invoked by * intel_huc_auth(). * * Return: non-zero code on error */ int intel_guc_auth_huc(struct intel_guc *guc, u32 rsa_offset) { … } /** * intel_guc_suspend() - notify GuC entering suspend state * @guc: the guc */ int intel_guc_suspend(struct intel_guc *guc) { … } /** * intel_guc_resume() - notify GuC resuming from suspend state * @guc: the guc */ int intel_guc_resume(struct intel_guc *guc) { … } /** * DOC: GuC Memory Management * * GuC can't allocate any memory for its own usage, so all the allocations must * be handled by the host driver. GuC accesses the memory via the GGTT, with the * exception of the top and bottom parts of the 4GB address space, which are * instead re-mapped by the GuC HW to memory location of the FW itself (WOPCM) * or other parts of the HW. The driver must take care not to place objects that * the GuC is going to access in these reserved ranges. The layout of the GuC * address space is shown below: * * :: * * +===========> +====================+ <== FFFF_FFFF * ^ | Reserved | * | +====================+ <== GUC_GGTT_TOP * | | | * | | DRAM | * GuC | | * Address +===> +====================+ <== GuC ggtt_pin_bias * Space ^ | | * | | | | * | GuC | GuC | * | WOPCM | WOPCM | * | Size | | * | | | | * v v | | * +=======+===> +====================+ <== 0000_0000 * * The lower part of GuC Address Space [0, ggtt_pin_bias) is mapped to GuC WOPCM * while upper part of GuC Address Space [ggtt_pin_bias, GUC_GGTT_TOP) is mapped * to DRAM. The value of the GuC ggtt_pin_bias is the GuC WOPCM size. */ /** * intel_guc_allocate_vma() - Allocate a GGTT VMA for GuC usage * @guc: the guc * @size: size of area to allocate (both virtual space and memory) * * This is a wrapper to create an object for use with the GuC. In order to * use it inside the GuC, an object needs to be pinned lifetime, so we allocate * both some backing storage and a range inside the Global GTT. We must pin * it in the GGTT somewhere other than than [0, GUC ggtt_pin_bias) because that * range is reserved inside GuC. * * Return: A i915_vma if successful, otherwise an ERR_PTR. */ struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size) { … } /** * intel_guc_allocate_and_map_vma() - Allocate and map VMA for GuC usage * @guc: the guc * @size: size of area to allocate (both virtual space and memory) * @out_vma: return variable for the allocated vma pointer * @out_vaddr: return variable for the obj mapping * * This wrapper calls intel_guc_allocate_vma() and then maps the allocated * object with I915_MAP_WB. * * Return: 0 if successful, a negative errno code otherwise. */ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size, struct i915_vma **out_vma, void **out_vaddr) { … } static int __guc_action_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value) { … } static int __guc_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value) { … } int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value) { … } int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value) { … } /** * intel_guc_load_status - dump information about GuC load status * @guc: the GuC * @p: the &drm_printer * * Pretty printer for GuC load status. */ void intel_guc_load_status(struct intel_guc *guc, struct drm_printer *p) { … } void intel_guc_write_barrier(struct intel_guc *guc) { … }