UAPI Changes:

- Debugfs multi-LRC engine info (Xin Wang, 2 commits)
   Expose multi-LRC engine classes in the debugfs engine info output
   and improve the output readability.
 
 - drm/drm_ras: Add clear-error-counter netlink command to drm_ras
 
 Cross-subsystem Changes:
 
 Core Changes:
 
 - drm/gpusvm: Reject VMAs with VM_IO or VM_PFNMAP when creating SVM ranges
 - drm/i915/display: switch to including common step file directly
 
 Driver Changes:
 
 - Engine initialization cleanup (Matt Roper, 10 commits)
   Clean up engine initialization code inherited from i915 by moving
   hardware programming (CCS enablement, HWSTAM, GFX_MODE, BLIT_CCTL,
   STOP_RING) into the RTP infrastructure.  This makes the programming
   visible and verifiable via debugfs, and applies consistently across
   both normal and execlist init paths.  Also fixes the name/definition
   of GFX_MODE, marks BCS engines as belonging to the GT forcewake
   domain, and drops the now-unused xe_hw_engine_mmio_write32() helper.
 
 - PF fair scheduling auto-provisioning (Michal Wajdeczko, 13 commits)
   Fix several corner cases in SR-IOV PF scheduling policy provisioning,
   then auto-provision PF and all VFs with 16ms execution-quantum and
   preemption-timeout defaults.  This prevents a VF from monopolizing
   the GPU by submitting workloads without gaps, without requiring the
   user to configure sysfs manually.
 
 - System Controller support for CRI/Xe3p (Anoop Vijay + Raag Jadav, 10 commits)
   Add xe_sysctrl infrastructure for communicating with the System
   Controller firmware entity on CRI/Xe3p discrete GPU platforms via a
   mailbox interface.  Includes type definitions, register definitions,
   mailbox communication, initialization, power management, interrupt
   handling, and event dispatch.  Builds on this to add initial RAS
   correctable error handling, using sysctrl interrupts to receive
   threshold-crossed events.
 
 - PXP state machine fixes (Daniele Ceraolo Spurio, 4 commits)
   Fix PXP state machine handling: reject PXP sessions on PTL platforms
   with older GSC firmware that does not support it, fix the restart
   flag not being cleared after jumping back in pxp_start, remove
   incorrect handling of an impossible state during suspend, and clean
   up termination status on failure.
 
 - Reset/wedge/unload corner case fixes (Zhanjun Dong + Matthew Brost, 5 commits)
   Fix memory leaks and fence signal failures that occurred during GPU
   reset, device wedging, and driver unload by forcefully tearing down
   remaining exec queues in GuC submit fini, always killing queues in
   pause/abort, and triggering queue cleanup when not in wedged mode 2.
   Also ensures GuC CT state transitions via STOP before DISABLED.
 
 - Wedge path memory allocation fixes (Matthew Brost, 3 commits)
   Avoid GFP_KERNEL allocations in xe_device_declare_wedged(), which
   runs in the DMA-fence signaling path.  Also drops the
   guc_submit_wedged_fini devm registration from xe_guc_submit_wedge()
   to clean up the wedge shutdown sequence.
 
 - PAT type cleanup and invalid index hardening (Xin Wang, 3 commits)
   Standardize pat_index fields to u16 across the driver, default
   XE_CACHE_NONE_COMPRESSION to XE_PAT_INVALID_IDX (matching
   WB_COMPRESSION), and introduce xe_cache_pat_idx() — a macro helper
   that validates cache_mode bounds and asserts on invalid PAT indices
   before returning the index.
 
 - Reject unsafe PAT indices for CPU cached memory (Jia Yao, 2 commits)
   Reject incoherent (coh_none) PAT indices for CPU cached memory in
   both the madvise ioctl and vm_bind with CPU_ADDR_MIRROR flag, closing
   a security gap where the GPU could bypass CPU caches and observe
   stale or sensitive data.
 
 - OA improvements for CRI device memory (Ashutosh Dixit, 3 commits)
   Move OA buffer access to the xe_map layer to support both system and
   device memory (required for CRI), switch OA buffer mmap to use
   drm_gem_mmap_obj, and implement workaround Wa_14026633728.
 
 - xe_drm.h documentation fixes (Shuicheng Lin, 6 commits)
   Fix multiple documentation issues in the xe_drm.h UAPI header:
   typos, spelling errors, grammar, wrong names and references,
   kernel-doc cross-reference syntax, and broken code examples.
 
 - kernel-doc syntax fixes in xe headers (Shuicheng Lin, 4 commits)
   Fix kernel-doc syntax issues across xe header files: missing '@'
   prefixes on member tags, stale/mismatched member tags, comment
   syntax errors, and type/parameter name mismatches in references.
 
 - Buffer object and DMA-buf resource leak fixes (Shuicheng Lin, 4 commits)
   Fix resource leaks on error paths: DMA-buf attachment leak in
   xe_gem_prime_import(), BO leak in xe_dma_buf_init_obj() on
   allocation failure, and BO leaks in xe_bo_init_locked() on GGTT
   flag validation and unaligned size validation failures.
 
 - Include guard cleanup (Shuicheng Lin, 5 commits)
   Fix and standardize include guards across xe header files: normalize
   double-underscore guards to single, add missing leading/trailing
   underscores, add missing _H suffixes, and add guards to previously
   unprotected headers.
 
 - VF CCS memory pool (Satyanarayana K V P, 2 commits)
   Switch VF CCS read/write operations from the DRM sub-allocator to
   DRM mm, fixing allocation failures in fence-disabled mode where
   the sub-allocator's hole cursor assumption breaks.  Also introduces
   a general BO-backed memory pool with shadow support using drm_mm.
 
 - i915/xe step definition unification (Jani Nikula, 3 commits)
   Complete the migration to the shared intel_step header: switch xe
   from its own xe_step enum to the shared intel_step naming and
   definitions, and update i915 display code to include the common
   step header directly.
 
 - Xe3p GT tuning fixes (3 commits)
   Three Xe3p GT tuning corrections: fix the register offset for
   GAMSTLB_CTRL, stop applying the CCCHKNREG1 tuning from Xe3p onward
   (no longer needed), and mark ROW_CHICKEN5 as a masked register.
 
 - Forcewake cleanup in GT and GuC PC (Raag Jadav, 3 commits)
   Drop a redundant forcewake reference in xe_gt, reorder forcewake
   usage in xe_guc_pc_fini_hw() to avoid a redundant hold, and convert
   xe_guc_pc_stop() to void since it can no longer fail.
 
 - SVM garbage collector fix on close (Matthew Brost, 2 commits)
   Disable the SVM garbage collector work item when an SVM is closed
   to prevent use-after-free when the GC fires after the SVM is freed.
 
 - Admin-only PF mode (Satyanarayana K V P, 2 commits)
   Derive an "admin-only PF" mode flag from xe_device state instead of
   using a local flag, and restrict device query responses when running
   in admin-only PF mode to avoid exposing internal state.
 
 - Enable hwmon energy attributes and accepted power limit for CRI (2 commits)
   Enable energy consumption hwmon attributes for the CRI platform and
   add support for reading the accepted (sustained) power limit via
   hwmon.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRskUM7w1oG5rx2IZO4FpNVCsYGvwUCafNROQAKCRC4FpNVCsYG
 v31cAQCS/7wH9kwyUxQZOgs/HfuZvbgu5IyrGxaDSrHY7twRtAD7BhvkfOcyB9VK
 6M2a7Y+QiVICgwjuDiwXikJalmRBmQE=
 =Y9j3
 -----END PGP SIGNATURE-----

Merge tag 'drm-xe-next-2026-04-30' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next

UAPI Changes:

- Debugfs multi-LRC engine info (Xin Wang, 2 commits)
  Expose multi-LRC engine classes in the debugfs engine info output
  and improve the output readability.

- drm/drm_ras: Add clear-error-counter netlink command to drm_ras

Cross-subsystem Changes:

Core Changes:

- drm/gpusvm: Reject VMAs with VM_IO or VM_PFNMAP when creating SVM ranges
- drm/i915/display: switch to including common step file directly

Driver Changes:

- Engine initialization cleanup (Matt Roper, 10 commits)
  Clean up engine initialization code inherited from i915 by moving
  hardware programming (CCS enablement, HWSTAM, GFX_MODE, BLIT_CCTL,
  STOP_RING) into the RTP infrastructure.  This makes the programming
  visible and verifiable via debugfs, and applies consistently across
  both normal and execlist init paths.  Also fixes the name/definition
  of GFX_MODE, marks BCS engines as belonging to the GT forcewake
  domain, and drops the now-unused xe_hw_engine_mmio_write32() helper.

- PF fair scheduling auto-provisioning (Michal Wajdeczko, 13 commits)
  Fix several corner cases in SR-IOV PF scheduling policy provisioning,
  then auto-provision PF and all VFs with 16ms execution-quantum and
  preemption-timeout defaults.  This prevents a VF from monopolizing
  the GPU by submitting workloads without gaps, without requiring the
  user to configure sysfs manually.

- System Controller support for CRI/Xe3p (Anoop Vijay + Raag Jadav, 10 commits)
  Add xe_sysctrl infrastructure for communicating with the System
  Controller firmware entity on CRI/Xe3p discrete GPU platforms via a
  mailbox interface.  Includes type definitions, register definitions,
  mailbox communication, initialization, power management, interrupt
  handling, and event dispatch.  Builds on this to add initial RAS
  correctable error handling, using sysctrl interrupts to receive
  threshold-crossed events.

- PXP state machine fixes (Daniele Ceraolo Spurio, 4 commits)
  Fix PXP state machine handling: reject PXP sessions on PTL platforms
  with older GSC firmware that does not support it, fix the restart
  flag not being cleared after jumping back in pxp_start, remove
  incorrect handling of an impossible state during suspend, and clean
  up termination status on failure.

- Reset/wedge/unload corner case fixes (Zhanjun Dong + Matthew Brost, 5 commits)
  Fix memory leaks and fence signal failures that occurred during GPU
  reset, device wedging, and driver unload by forcefully tearing down
  remaining exec queues in GuC submit fini, always killing queues in
  pause/abort, and triggering queue cleanup when not in wedged mode 2.
  Also ensures GuC CT state transitions via STOP before DISABLED.

- Wedge path memory allocation fixes (Matthew Brost, 3 commits)
  Avoid GFP_KERNEL allocations in xe_device_declare_wedged(), which
  runs in the DMA-fence signaling path.  Also drops the
  guc_submit_wedged_fini devm registration from xe_guc_submit_wedge()
  to clean up the wedge shutdown sequence.

- PAT type cleanup and invalid index hardening (Xin Wang, 3 commits)
  Standardize pat_index fields to u16 across the driver, default
  XE_CACHE_NONE_COMPRESSION to XE_PAT_INVALID_IDX (matching
  WB_COMPRESSION), and introduce xe_cache_pat_idx() — a macro helper
  that validates cache_mode bounds and asserts on invalid PAT indices
  before returning the index.

- Reject unsafe PAT indices for CPU cached memory (Jia Yao, 2 commits)
  Reject incoherent (coh_none) PAT indices for CPU cached memory in
  both the madvise ioctl and vm_bind with CPU_ADDR_MIRROR flag, closing
  a security gap where the GPU could bypass CPU caches and observe
  stale or sensitive data.

- OA improvements for CRI device memory (Ashutosh Dixit, 3 commits)
  Move OA buffer access to the xe_map layer to support both system and
  device memory (required for CRI), switch OA buffer mmap to use
  drm_gem_mmap_obj, and implement workaround Wa_14026633728.

- xe_drm.h documentation fixes (Shuicheng Lin, 6 commits)
  Fix multiple documentation issues in the xe_drm.h UAPI header:
  typos, spelling errors, grammar, wrong names and references,
  kernel-doc cross-reference syntax, and broken code examples.

- kernel-doc syntax fixes in xe headers (Shuicheng Lin, 4 commits)
  Fix kernel-doc syntax issues across xe header files: missing '@'
  prefixes on member tags, stale/mismatched member tags, comment
  syntax errors, and type/parameter name mismatches in references.

- Buffer object and DMA-buf resource leak fixes (Shuicheng Lin, 4 commits)
  Fix resource leaks on error paths: DMA-buf attachment leak in
  xe_gem_prime_import(), BO leak in xe_dma_buf_init_obj() on
  allocation failure, and BO leaks in xe_bo_init_locked() on GGTT
  flag validation and unaligned size validation failures.

- Include guard cleanup (Shuicheng Lin, 5 commits)
  Fix and standardize include guards across xe header files: normalize
  double-underscore guards to single, add missing leading/trailing
  underscores, add missing _H suffixes, and add guards to previously
  unprotected headers.

- VF CCS memory pool (Satyanarayana K V P, 2 commits)
  Switch VF CCS read/write operations from the DRM sub-allocator to
  DRM mm, fixing allocation failures in fence-disabled mode where
  the sub-allocator's hole cursor assumption breaks.  Also introduces
  a general BO-backed memory pool with shadow support using drm_mm.

- i915/xe step definition unification (Jani Nikula, 3 commits)
  Complete the migration to the shared intel_step header: switch xe
  from its own xe_step enum to the shared intel_step naming and
  definitions, and update i915 display code to include the common
  step header directly.

- Xe3p GT tuning fixes (3 commits)
  Three Xe3p GT tuning corrections: fix the register offset for
  GAMSTLB_CTRL, stop applying the CCCHKNREG1 tuning from Xe3p onward
  (no longer needed), and mark ROW_CHICKEN5 as a masked register.

- Forcewake cleanup in GT and GuC PC (Raag Jadav, 3 commits)
  Drop a redundant forcewake reference in xe_gt, reorder forcewake
  usage in xe_guc_pc_fini_hw() to avoid a redundant hold, and convert
  xe_guc_pc_stop() to void since it can no longer fail.

- SVM garbage collector fix on close (Matthew Brost, 2 commits)
  Disable the SVM garbage collector work item when an SVM is closed
  to prevent use-after-free when the GC fires after the SVM is freed.

- Admin-only PF mode (Satyanarayana K V P, 2 commits)
  Derive an "admin-only PF" mode flag from xe_device state instead of
  using a local flag, and restrict device query responses when running
  in admin-only PF mode to avoid exposing internal state.

- Enable hwmon energy attributes and accepted power limit for CRI (2 commits)
  Enable energy consumption hwmon attributes for the CRI platform and
  add support for reading the accepted (sustained) power limit via
  hwmon.

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Thomas Hellstrom <thomas.hellstrom@linux.intel.com>
Link: https://patch.msgid.link/afNSeZJHC3X2m3-N@fedora
This commit is contained in:
Dave Airlie 2026-05-04 18:20:49 +10:00
commit 27268b872e
148 changed files with 2553 additions and 651 deletions

View File

@ -52,6 +52,8 @@ User space tools can:
as a parameter.
* Query specific error counter values with the ``get-error-counter`` command, using both
``node-id`` and ``error-id`` as parameters.
* Clear specific error counters with the ``clear-error-counter`` command, using both
``node-id`` and ``error-id`` as parameters.
YAML-based Interface
--------------------
@ -101,3 +103,9 @@ Example: Query an error counter for a given node
sudo ynl --family drm_ras --do get-error-counter --json '{"node-id":0, "error-id":1}'
{'error-id': 1, 'error-name': 'error_name1', 'error-value': 0}
Example: Clear an error counter for a given node
.. code-block:: bash
sudo ynl --family drm_ras --do clear-error-counter --json '{"node-id":0, "error-id":1}'
None

View File

@ -29,3 +29,4 @@ DG2, etc is provided to prototype the driver.
xe_device
xe-drm-usage-stats.rst
xe_configfs
xe_gt_stats

View File

@ -0,0 +1,11 @@
.. SPDX-License-Identifier: (GPL-2.0+ OR MIT)
================
Xe GT Statistics
================
.. kernel-doc:: drivers/gpu/drm/xe/xe_gt_stats.c
:doc: Xe GT Statistics
.. kernel-doc:: drivers/gpu/drm/xe/xe_gt_stats_types.h
:internal:

View File

@ -99,7 +99,7 @@ operations:
flags: [admin-perm]
do:
request:
attributes:
attributes: &id-attrs
- node-id
- error-id
reply:
@ -113,3 +113,14 @@ operations:
- node-id
reply:
attributes: *errorinfo
-
name: clear-error-counter
doc: >-
Clear error counter for a given node.
The request includes the error-id and node-id of the
counter to be cleared.
attribute-set: error-counter-attrs
flags: [admin-perm]
do:
request:
attributes: *id-attrs

View File

@ -1065,6 +1065,11 @@ drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm,
goto err_notifier_remove;
}
if (vas->vm_flags & (VM_IO | VM_PFNMAP)) {
err = -EIO;
goto err_notifier_remove;
}
range = drm_gpusvm_range_find(notifier, fault_addr, fault_addr + 1);
if (range)
goto out_mmunlock;

View File

@ -26,7 +26,7 @@
* efficient lookup by ID. Nodes can be registered or unregistered
* dynamically at runtime.
*
* A Generic Netlink family `drm_ras` exposes two main operations to
* A Generic Netlink family `drm_ras` exposes the below operations to
* userspace:
*
* 1. LIST_NODES: Dump all currently registered RAS nodes.
@ -37,6 +37,10 @@
* Returns all counters of a node if only Node ID is provided or specific
* error counters.
*
* 3. CLEAR_ERROR_COUNTER: Clear error counter of a given node.
* Userspace must provide Node ID, Error ID.
* Clears specific error counter of a node if supported.
*
* Node registration:
*
* - drm_ras_node_register(): Registers a new node and assigns
@ -66,6 +70,8 @@
* operation, fetching all counters from a specific node.
* - drm_ras_nl_get_error_counter_doit(): Implements the GET_ERROR_COUNTER doit
* operation, fetching a counter value from a specific node.
* - drm_ras_nl_clear_error_counter_doit(): Implements the CLEAR_ERROR_COUNTER doit
* operation, clearing a counter value from a specific node.
*/
static DEFINE_XARRAY_ALLOC(drm_ras_xa);
@ -314,6 +320,41 @@ int drm_ras_nl_get_error_counter_doit(struct sk_buff *skb,
return doit_reply_value(info, node_id, error_id);
}
/**
* drm_ras_nl_clear_error_counter_doit() - Clear an error counter of a node
* @skb: Netlink message buffer
* @info: Generic Netlink info containing attributes of the request
*
* Extracts the node ID and error ID from the netlink attributes and
* clears the current value.
*
* Return: 0 on success, or negative errno on failure.
*/
int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb,
struct genl_info *info)
{
struct drm_ras_node *node;
u32 node_id, error_id;
if (!info->attrs ||
GENL_REQ_ATTR_CHECK(info, DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID) ||
GENL_REQ_ATTR_CHECK(info, DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID))
return -EINVAL;
node_id = nla_get_u32(info->attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID]);
error_id = nla_get_u32(info->attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID]);
node = xa_load(&drm_ras_xa, node_id);
if (!node || !node->clear_error_counter)
return -ENOENT;
if (error_id < node->error_counter_range.first ||
error_id > node->error_counter_range.last)
return -EINVAL;
return node->clear_error_counter(node, error_id);
}
/**
* drm_ras_node_register() - Register a new RAS node
* @node: Node structure to register

View File

@ -22,6 +22,12 @@ static const struct nla_policy drm_ras_get_error_counter_dump_nl_policy[DRM_RAS_
[DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID] = { .type = NLA_U32, },
};
/* DRM_RAS_CMD_CLEAR_ERROR_COUNTER - do */
static const struct nla_policy drm_ras_clear_error_counter_nl_policy[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID + 1] = {
[DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID] = { .type = NLA_U32, },
[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID] = { .type = NLA_U32, },
};
/* Ops table for drm_ras */
static const struct genl_split_ops drm_ras_nl_ops[] = {
{
@ -43,6 +49,13 @@ static const struct genl_split_ops drm_ras_nl_ops[] = {
.maxattr = DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP,
},
{
.cmd = DRM_RAS_CMD_CLEAR_ERROR_COUNTER,
.doit = drm_ras_nl_clear_error_counter_doit,
.policy = drm_ras_clear_error_counter_nl_policy,
.maxattr = DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
};
struct genl_family drm_ras_nl_family __ro_after_init = {

View File

@ -18,6 +18,8 @@ int drm_ras_nl_get_error_counter_doit(struct sk_buff *skb,
struct genl_info *info);
int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb,
struct netlink_callback *cb);
int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb,
struct genl_info *info);
extern struct genl_family drm_ras_nl_family;

View File

@ -28,6 +28,7 @@
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include <drm/intel/intel_pcode_regs.h>
#include <drm/intel/step.h>
#include "hsw_ips.h"
#include "intel_atomic.h"
@ -46,7 +47,6 @@
#include "intel_pci_config.h"
#include "intel_plane.h"
#include "intel_psr.h"
#include "intel_step.h"
#include "intel_vdsc.h"
#include "skl_watermark.h"
#include "skl_watermark_regs.h"

View File

@ -33,6 +33,7 @@
#include <drm/display/drm_scdc_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_privacy_screen_consumer.h>
#include <drm/intel/step.h>
#include "icl_dsi.h"
#include "intel_alpm.h"
@ -81,7 +82,6 @@
#include "intel_psr.h"
#include "intel_quirks.h"
#include "intel_snps_phy.h"
#include "intel_step.h"
#include "intel_tc.h"
#include "intel_vdsc.h"
#include "intel_vdsc_regs.h"

View File

@ -9,6 +9,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_print.h>
#include <drm/intel/pciids.h>
#include <drm/intel/step.h>
#include "intel_cx0_phy_regs.h"
#include "intel_de.h"
@ -21,7 +22,6 @@
#include "intel_display_types.h"
#include "intel_display_wa.h"
#include "intel_fbc.h"
#include "intel_step.h"
__diag_push();
__diag_ignore_all("-Woverride-init", "Allow field initialization overrides for display info");

View File

@ -8,6 +8,7 @@
#include <drm/drm_print.h>
#include <drm/intel/intel_pcode_regs.h>
#include <drm/intel/step.h>
#include "intel_backlight_regs.h"
#include "intel_cdclk.h"
@ -30,7 +31,6 @@
#include "intel_pmdemand.h"
#include "intel_pps_regs.h"
#include "intel_snps_phy.h"
#include "intel_step.h"
#include "skl_watermark.h"
#include "skl_watermark_regs.h"
#include "vlv_sideband.h"

View File

@ -4,12 +4,12 @@
*/
#include <drm/drm_print.h>
#include <drm/intel/step.h>
#include "intel_de.h"
#include "intel_display_core.h"
#include "intel_display_regs.h"
#include "intel_display_wa.h"
#include "intel_step.h"
static void gen11_display_wa_apply(struct intel_display *display)
{

View File

@ -32,6 +32,7 @@
#include <drm/drm_fixed.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>
#include <drm/intel/step.h>
#include "intel_atomic.h"
#include "intel_audio.h"
@ -56,7 +57,6 @@
#include "intel_link_bw.h"
#include "intel_pfit.h"
#include "intel_psr.h"
#include "intel_step.h"
#include "intel_vdsc.h"
#include "intel_vrr.h"
#include "skl_scaler.h"

View File

@ -25,6 +25,7 @@
#include <linux/string_helpers.h>
#include <drm/drm_print.h>
#include <drm/intel/step.h>
#include "bxt_dpio_phy_regs.h"
#include "intel_cx0_phy.h"
@ -41,7 +42,6 @@
#include "intel_lt_phy.h"
#include "intel_mg_phy_regs.h"
#include "intel_pch_refclk.h"
#include "intel_step.h"
#include "intel_tc.h"
/**

View File

@ -44,6 +44,7 @@
#include <drm/drm_blend.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>
#include <drm/intel/step.h>
#include "i9xx_plane_regs.h"
#include "intel_de.h"
@ -58,7 +59,6 @@
#include "intel_fbc_regs.h"
#include "intel_frontbuffer.h"
#include "intel_parent.h"
#include "intel_step.h"
#define for_each_fbc_id(__display, __fbc_id) \
for ((__fbc_id) = INTEL_FBC_A; (__fbc_id) < I915_MAX_FBCS; (__fbc_id)++) \

View File

@ -6,6 +6,7 @@
#include <linux/pci.h>
#include <drm/drm_print.h>
#include <drm/intel/step.h>
#include "intel_crtc.h"
#include "intel_de.h"
@ -17,7 +18,6 @@
#include "intel_dmc_regs.h"
#include "intel_dsb.h"
#include "intel_flipq.h"
#include "intel_step.h"
#include "intel_vblank.h"
#include "intel_vrr.h"

View File

@ -18,6 +18,7 @@
#include <drm/drm_print.h>
#include <drm/intel/i915_component.h>
#include <drm/intel/intel_pcode_regs.h>
#include <drm/intel/step.h>
#include "intel_connector.h"
#include "intel_de.h"
@ -33,7 +34,6 @@
#include "intel_hdcp_regs.h"
#include "intel_hdcp_shim.h"
#include "intel_parent.h"
#include "intel_step.h"
#define USE_HDCP_GSC(__display) (DISPLAY_VER(__display) >= 14)

View File

@ -6,6 +6,7 @@
#include <linux/bitops.h>
#include <drm/drm_print.h>
#include <drm/intel/step.h>
#include "intel_atomic.h"
#include "intel_bw.h"
@ -17,7 +18,6 @@
#include "intel_display_utils.h"
#include "intel_display_wa.h"
#include "intel_pmdemand.h"
#include "intel_step.h"
#include "skl_watermark.h"
struct pmdemand_params {

View File

@ -28,6 +28,7 @@
#include <drm/drm_debugfs.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
#include <drm/intel/step.h>
#include "intel_alpm.h"
#include "intel_atomic.h"
@ -51,7 +52,6 @@
#include "intel_psr_regs.h"
#include "intel_quirks.h"
#include "intel_snps_phy.h"
#include "intel_step.h"
#include "intel_vblank.h"
#include "intel_vdsc.h"
#include "intel_vrr.h"

View File

@ -8,6 +8,7 @@
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_print.h>
#include <drm/intel/step.h>
#include "intel_bo.h"
#include "intel_color.h"
@ -25,7 +26,6 @@
#include "intel_plane.h"
#include "intel_psr.h"
#include "intel_psr_regs.h"
#include "intel_step.h"
#include "skl_scaler.h"
#include "skl_universal_plane.h"
#include "skl_universal_plane_regs.h"

View File

@ -113,6 +113,7 @@ xe-y += xe_bb.o \
xe_pxp_submit.o \
xe_query.o \
xe_range_fence.o \
xe_ras.o \
xe_reg_sr.o \
xe_reg_whitelist.o \
xe_ring_ops.o \
@ -124,6 +125,9 @@ xe-y += xe_bb.o \
xe_step.o \
xe_survivability_mode.o \
xe_sync.o \
xe_sysctrl.o \
xe_sysctrl_event.o \
xe_sysctrl_mailbox.o \
xe_tile.o \
xe_tile_sysfs.o \
xe_tlb_inval.o \

View File

@ -192,6 +192,13 @@ enum {
* `GuC KLV`_ keys available for use with PF2GUC_UPDATE_VGT_POLICY.
*
* _`GUC_KLV_VGT_POLICY_SCHED_IF_IDLE` : 0x8001
* [From 70.12.0]
* This config allows to update scheduling priority of PF and all VFs at once.
* Setting this policy to 0 updates all VFs scheduling priorities to LOW, and
* setting this policy to 1 updates all VFs scheduling priorities to NORMAL.
* Those changes will take effect on the next VF-Switch event.
*
* [Before 70.12.0]
* This config sets whether strict scheduling is enabled whereby any VF
* that doesnt have work to submit is still allocated a fixed execution
* time-slice to ensure active VFs execution is always consistent even
@ -496,6 +503,7 @@ enum xe_guc_klv_ids {
GUC_WA_KLV_WAKE_POWER_DOMAINS_FOR_OUTBOUND_MMIO = 0x900a,
GUC_WA_KLV_RESET_BB_STACK_PTR_ON_VF_SWITCH = 0x900b,
GUC_WA_KLV_RESTORE_UNSAVED_MEDIA_CONTROL_REG = 0x900c,
GUC_WA_KLV_CLR_CS_INDIRECT_RING_STATE_IF_IDLE_AT_CTX_REG = 0x900e,
};
#endif

View File

@ -0,0 +1,65 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2026 Intel Corporation
*/
#ifndef _XE_SYSCTRL_ABI_H_
#define _XE_SYSCTRL_ABI_H_
#include <linux/types.h>
/**
* DOC: System Controller ABI
*
* This header defines the Application Binary Interface (ABI) used by
* drm/xe to communicate with System Controller firmware on Intel Xe3p
* discrete GPU platforms.
*
* System Controller (sysctrl) is a firmware-managed entity on Intel
* dGPUs responsible for certain low-level platform management
* functions.
*
* Communication protocol:
*
* Communication uses a mailbox interface with messages composed of:
*
* - Application message header (struct xe_sysctrl_app_msg_hdr)
* containing group_id, command, and version
* - Variable-length, command-specific payload
*
* Message header format:
*
* The 32-bit application message header is packed as:
*
* - Bits [7:0] : Group ID identifying command group
* - Bits [15:8] : Command identifier within group
* - Bits [23:16] : Command version for interface compatibility
* - Bits [31:24] : Reserved, must be zero
*
* This header defines firmware ABI message formats and constants shared
* between driver and System Controller firmware.
*/
/**
* struct xe_sysctrl_app_msg_hdr - Application layer message header
* @data: 32-bit header data
*
* Header structure for application-level messages.
*/
struct xe_sysctrl_app_msg_hdr {
u32 data;
} __packed;
#define SYSCTRL_HDR_GROUP_ID_MASK GENMASK(7, 0)
#define SYSCTRL_HDR_COMMAND_MASK GENMASK(14, 8)
#define SYSCTRL_HDR_COMMAND_MAX 0x7f
#define SYSCTRL_HDR_IS_RESPONSE BIT(15)
#define SYSCTRL_HDR_RESERVED_MASK GENMASK(23, 16)
#define SYSCTRL_HDR_RESULT_MASK GENMASK(31, 24)
#define APP_HDR_GROUP_ID_MASK GENMASK(7, 0)
#define APP_HDR_COMMAND_MASK GENMASK(15, 8)
#define APP_HDR_VERSION_MASK GENMASK(23, 16)
#define APP_HDR_RESERVED_MASK GENMASK(31, 24)
#endif

View File

@ -1,13 +0,0 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2023 Intel Corporation
*/
#ifndef __INTEL_STEP_H__
#define __INTEL_STEP_H__
#include "xe_step_types.h"
#define intel_step xe_step
#endif /* __INTEL_STEP_H__ */

View File

@ -14,6 +14,7 @@
#include "xe_device.h"
#include "xe_display_vma.h"
#include "xe_ggtt.h"
#include "xe_pat.h"
#include "xe_pm.h"
#include "xe_vram_types.h"
@ -24,7 +25,7 @@ write_dpt_rotated(struct xe_bo *bo, struct iosys_map *map, u32 *dpt_ofs, u32 bo_
struct xe_device *xe = xe_bo_device(bo);
struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt;
u32 column, row;
u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe->pat.idx[XE_CACHE_NONE]);
u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe_cache_pat_idx(xe, XE_CACHE_NONE));
/* TODO: Maybe rewrite so we can traverse the bo addresses sequentially,
* by writing dpt/ggtt in a different order?
@ -64,7 +65,7 @@ write_dpt_remapped_linear(struct xe_bo *bo, struct iosys_map *map,
struct xe_device *xe = xe_bo_device(bo);
struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt;
const u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo,
xe->pat.idx[XE_CACHE_NONE]);
xe_cache_pat_idx(xe, XE_CACHE_NONE));
unsigned int offset = plane->offset * XE_PAGE_SIZE;
unsigned int size = plane->size;
@ -87,7 +88,7 @@ write_dpt_remapped_tiled(struct xe_bo *bo, struct iosys_map *map,
struct xe_device *xe = xe_bo_device(bo);
struct xe_ggtt *ggtt = xe_device_get_root_tile(xe)->mem.ggtt;
const u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo,
xe->pat.idx[XE_CACHE_NONE]);
xe_cache_pat_idx(xe, XE_CACHE_NONE));
unsigned int offset, column, row;
for (row = 0; row < plane->height; row++) {
@ -190,7 +191,7 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb,
return PTR_ERR(dpt);
if (view->type == I915_GTT_VIEW_NORMAL) {
u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe->pat.idx[XE_CACHE_NONE]);
u64 pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe_cache_pat_idx(xe, XE_CACHE_NONE));
u32 x;
for (x = 0; x < size / XE_PAGE_SIZE; x++) {
@ -306,7 +307,7 @@ static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb,
/* display uses tiles instead of bytes here, so convert it back.. */
size = intel_rotation_info_size(&view->rotated) * XE_PAGE_SIZE;
pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe->pat.idx[XE_CACHE_NONE]);
pte = xe_ggtt_encode_pte_flags(ggtt, bo, xe_cache_pat_idx(xe, XE_CACHE_NONE));
vma->node = xe_ggtt_insert_node_transform(ggtt, bo, pte,
ALIGN(size, align), align,
view->type == I915_GTT_VIEW_NORMAL ?

View File

@ -37,9 +37,17 @@ static bool intel_hdcp_gsc_check_status(struct drm_device *drm)
struct xe_device *xe = to_xe_device(drm);
struct xe_tile *tile = xe_device_get_root_tile(xe);
struct xe_gt *gt = tile->media_gt;
struct xe_gsc *gsc = &gt->uc.gsc;
struct xe_gsc *gsc;
if (!gsc || !xe_uc_fw_is_available(&gsc->fw)) {
if (!gt) {
drm_dbg_kms(&xe->drm,
"not checking GSC status for HDCP2.x: media GT not present or disabled\n");
return false;
}
gsc = &gt->uc.gsc;
if (!xe_uc_fw_is_available(&gsc->fw)) {
drm_dbg_kms(&xe->drm,
"GSC Components not ready for HDCP2.x\n");
return false;

View File

@ -165,9 +165,9 @@
#define CTX_CTRL_INHIBIT_SYN_CTX_SWITCH REG_BIT(3)
#define CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT REG_BIT(0)
#define RING_MODE(base) XE_REG((base) + 0x29c)
#define GFX_DISABLE_LEGACY_MODE REG_BIT(3)
#define GFX_MODE(base) XE_REG((base) + 0x29c, XE_REG_OPTION_MASKED)
#define GFX_MSIX_INTERRUPT_ENABLE REG_BIT(13)
#define GFX_DISABLE_LEGACY_MODE REG_BIT(3)
#define RING_CSMQDEBUG(base) XE_REG((base) + 0x2b0)
@ -176,7 +176,6 @@
#define RING_TIMESTAMP_UDW(base) XE_REG((base) + 0x358 + 4)
#define RING_VALID_MASK 0x00000001
#define RING_VALID 0x00000001
#define STOP_RING REG_BIT(8)
#define RING_CTX_TIMESTAMP(base) XE_REG((base) + 0x3a8)
#define RING_CTX_TIMESTAMP_UDW(base) XE_REG((base) + 0x3ac)

View File

@ -528,6 +528,7 @@
#define ROW_CHICKEN3 XE_REG_MCR(0xe49c, XE_REG_OPTION_MASKED)
#define XE2_EUPEND_CHK_FLUSH_DIS REG_BIT(14)
#define DIS_EU_GRF_POISON_TO_LSC REG_BIT(13)
#define DIS_FIX_EOT1_FLUSH REG_BIT(9)
#define TDL_TSL_CHICKEN XE_REG_MCR(0xe4c4, XE_REG_OPTION_MASKED)
@ -535,6 +536,9 @@
#define SLM_WMTP_RESTORE REG_BIT(11)
#define RES_CHK_SPR_DIS REG_BIT(6)
#define TDL_TSL_CHICKEN2 XE_REG_MCR(0xe4cc, XE_REG_OPTION_MASKED)
#define TILEY_LOCALID REG_BIT(2)
#define ROW_CHICKEN XE_REG_MCR(0xe4f0, XE_REG_OPTION_MASKED)
#define UGM_BACKUP_MODE REG_BIT(13)
#define MDQ_ARBITRATION_MODE REG_BIT(12)
@ -560,6 +564,7 @@
#define DIS_ATOMIC_CHAINING_TYPED_WRITES REG_BIT(3)
#define TDL_CHICKEN XE_REG_MCR(0xe5f4, XE_REG_OPTION_MASKED)
#define BIT_APQ_OPT_DIS REG_BIT(14)
#define QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE REG_BIT(12)
#define EUSTALL_PERF_SAMPLING_DISABLE REG_BIT(5)

View File

@ -22,6 +22,7 @@
#define DISPLAY_IRQ REG_BIT(16)
#define SOC_H2DMEMINT_IRQ REG_BIT(13)
#define I2C_IRQ REG_BIT(12)
#define SYSCTRL_IRQ REG_BIT(11)
#define GT_DW_IRQ(x) REG_BIT(x)
/*

View File

@ -27,4 +27,7 @@
#define TEMP_SIGN_MASK REG_BIT(31)
#define BMG_PACKAGE_TEMPERATURE XE_REG(0x138434)
#define CRI_PACKAGE_ENERGY_STATUS XE_REG(0x138120)
#define CRI_PLATFORM_ENERGY_STATUS XE_REG(0x138458)
#endif /* _XE_PCODE_REGS_H_ */

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright © 2026 Intel Corporation
*/
#ifndef _XE_SYSCTRL_REGS_H_
#define _XE_SYSCTRL_REGS_H_
#include "xe_regs.h"
#define SYSCTRL_BASE_OFFSET 0xdb000
#define SYSCTRL_BASE (SOC_BASE + SYSCTRL_BASE_OFFSET)
#define SYSCTRL_MAILBOX_INDEX 0x03
#define SYSCTRL_BAR_LENGTH 0x1000
#define SYSCTRL_MB_CTRL XE_REG(0x10)
#define SYSCTRL_MB_CTRL_RUN_BUSY REG_BIT(31)
#define SYSCTRL_MB_CTRL_IRQ REG_BIT(30)
#define SYSCTRL_MB_CTRL_RUN_BUSY_OUT REG_BIT(29)
#define SYSCTRL_MB_CTRL_PARAM3_MASK REG_GENMASK(28, 24)
#define SYSCTRL_MB_CTRL_PARAM2_MASK REG_GENMASK(23, 16)
#define SYSCTRL_MB_CTRL_PARAM1_MASK REG_GENMASK(15, 8)
#define SYSCTRL_MB_CTRL_COMMAND_MASK REG_GENMASK(7, 0)
#define SYSCTRL_MB_CTRL_CMD REG_FIELD_PREP(SYSCTRL_MB_CTRL_COMMAND_MASK, 5)
#define SYSCTRL_MB_DATA0 XE_REG(0x14)
#define SYSCTRL_MB_DATA1 XE_REG(0x18)
#define SYSCTRL_MB_DATA2 XE_REG(0x1c)
#define SYSCTRL_MB_DATA3 XE_REG(0x20)
#define SYSCTRL_FRAME_PHASE REG_BIT(24)
#define SYSCTRL_FRAME_CURRENT_MASK REG_GENMASK(21, 16)
#define SYSCTRL_FRAME_TOTAL_MASK REG_GENMASK(13, 8)
#define SYSCTRL_FRAME_COMMAND_MASK REG_GENMASK(7, 0)
#endif

View File

@ -13,11 +13,28 @@
#define TEST_MAX_VFS 63
#define TEST_VRAM 0x7a800000ull /* random size that works on 32-bit */
static bool xe_device_is_admin_only_stub_enable(const struct xe_device *xe)
{
return true;
}
static bool xe_device_is_admin_only_stub_disable(const struct xe_device *xe)
{
return false;
}
static void pf_set_admin_mode(struct xe_device *xe, bool enable)
{
/* should match logic of xe_sriov_pf_admin_only() */
xe->sriov.pf.admin_only = enable;
typeof(xe_device_is_admin_only) *stub = enable ?
xe_device_is_admin_only_stub_enable :
xe_device_is_admin_only_stub_disable;
kunit_activate_static_stub(kunit_get_current_test(),
xe_device_is_admin_only,
*stub);
KUNIT_EXPECT_EQ(kunit_get_current_test(), enable, xe_sriov_pf_admin_only(xe));
KUNIT_EXPECT_EQ(kunit_get_current_test(), enable, xe_device_is_admin_only(xe));
}
static void pf_set_usable_vram(struct xe_device *xe, u64 usable)

View File

@ -9,6 +9,7 @@
#include "tests/xe_kunit_helpers.h"
#include "tests/xe_pci_test.h"
#include "xe_pat.h"
#include "xe_pci.h"
#include "xe_pm.h"
@ -246,7 +247,7 @@ static void xe_migrate_sanity_test(struct xe_migrate *m, struct kunit *test,
/* First part of the test, are we updating our pagetable bo with a new entry? */
xe_map_wr(xe, &bo->vmap, XE_PAGE_SIZE * (NUM_KERNEL_PDE - 1), u64,
0xdeaddeadbeefbeef);
expected = m->q->vm->pt_ops->pte_encode_bo(pt, 0, xe->pat.idx[XE_CACHE_WB], 0);
expected = m->q->vm->pt_ops->pte_encode_bo(pt, 0, xe_cache_pat_idx(xe, XE_CACHE_WB), 0);
if (m->q->vm->flags & XE_VM_FLAG_64K)
expected |= XE_PTE_PS64;
if (xe_bo_is_vram(pt))

View File

@ -131,12 +131,12 @@ static const char *subplatform_prefix(enum xe_subplatform s)
return s == XE_SUBPLATFORM_NONE ? "" : " ";
}
static const char *step_prefix(enum xe_step step)
static const char *step_prefix(enum intel_step step)
{
return step == STEP_NONE ? "" : " ";
}
static const char *step_name(enum xe_step step)
static const char *step_name(enum intel_step step)
{
return step == STEP_NONE ? "" : xe_step_name(step);
}

View File

@ -173,19 +173,6 @@ mem_type_to_migrate(struct xe_device *xe, u32 mem_type)
return tile->migrate;
}
static struct xe_vram_region *res_to_mem_region(struct ttm_resource *res)
{
struct xe_device *xe = ttm_to_xe_device(res->bo->bdev);
struct ttm_resource_manager *mgr;
struct xe_ttm_vram_mgr *vram_mgr;
xe_assert(xe, resource_is_vram(res));
mgr = ttm_manager_type(&xe->ttm, res->mem_type);
vram_mgr = to_xe_ttm_vram_mgr(mgr);
return container_of(vram_mgr, struct xe_vram_region, ttm);
}
static void try_add_system(struct xe_device *xe, struct xe_bo *bo,
u32 bo_flags, u32 *c)
{
@ -635,7 +622,7 @@ static int xe_ttm_io_mem_reserve(struct ttm_device *bdev,
return 0;
case XE_PL_VRAM0:
case XE_PL_VRAM1: {
struct xe_vram_region *vram = res_to_mem_region(mem);
struct xe_vram_region *vram = xe_map_resource_to_region(mem);
if (!xe_ttm_resource_visible(mem))
return -EINVAL;
@ -1642,7 +1629,7 @@ static unsigned long xe_ttm_io_mem_pfn(struct ttm_buffer_object *ttm_bo,
if (ttm_bo->resource->mem_type == XE_PL_STOLEN)
return xe_ttm_stolen_io_offset(bo, page_offset << PAGE_SHIFT) >> PAGE_SHIFT;
vram = res_to_mem_region(ttm_bo->resource);
vram = xe_map_resource_to_region(ttm_bo->resource);
xe_res_first(ttm_bo->resource, (u64)page_offset << PAGE_SHIFT, 0, &cursor);
return (vram->io_start + cursor.start) >> PAGE_SHIFT;
}
@ -1782,7 +1769,7 @@ static int xe_ttm_access_memory(struct ttm_buffer_object *ttm_bo,
goto out;
}
vram = res_to_mem_region(ttm_bo->resource);
vram = xe_map_resource_to_region(ttm_bo->resource);
xe_res_first(ttm_bo->resource, offset & PAGE_MASK,
xe_bo_size(bo) - (offset & PAGE_MASK), &cursor);
@ -2927,7 +2914,7 @@ uint64_t vram_region_gpu_offset(struct ttm_resource *res)
case XE_PL_SYSTEM:
return 0;
default:
return res_to_mem_region(res)->dpa_base;
return xe_map_resource_to_region(res)->dpa_base;
}
return 0;
}

View File

@ -67,7 +67,7 @@ struct xe_bo {
/** @attr: User controlled attributes for bo */
struct {
/**
* @atomic_access: type of atomic access bo needs
* @attr.atomic_access: type of atomic access bo needs
* protected by bo dma-resv lock
*/
u32 atomic_access;

View File

@ -15,9 +15,11 @@
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_force_wake.h"
#include "xe_gt.h"
#include "xe_gt_debugfs.h"
#include "xe_gt_printk.h"
#include "xe_guc_ads.h"
#include "xe_hw_engine.h"
#include "xe_mmio.h"
#include "xe_pm.h"
#include "xe_psmi.h"
@ -61,6 +63,37 @@ static struct xe_device *node_to_xe(struct drm_info_node *node)
return to_xe_device(node->minor->dev);
}
static void print_engine_class_mask(struct drm_printer *p, u16 mask)
{
if (!mask) {
drm_printf(p, " none\n");
return;
}
for (enum xe_engine_class ec = 0; ec < XE_ENGINE_CLASS_MAX; ec++) {
if (mask & BIT(ec))
drm_printf(p, " %s", xe_hw_engine_class_to_str(ec));
}
drm_printf(p, "\n");
}
static void print_engine_mask(struct drm_printer *p, struct xe_gt *gt, u64 mask)
{
struct xe_hw_engine *hwe;
enum xe_hw_engine_id id;
if (!mask) {
drm_printf(p, " none\n");
return;
}
for_each_hw_engine(hwe, gt, id) {
if (mask & BIT_ULL(id))
drm_printf(p, " %s", hwe->name);
}
drm_printf(p, "\n");
}
static int info(struct seq_file *m, void *data)
{
struct xe_device *xe = node_to_xe(m->private);
@ -88,13 +121,15 @@ static int info(struct seq_file *m, void *data)
drm_printf(&p, "has_flat_ccs %s\n", str_yes_no(xe->info.has_flat_ccs));
drm_printf(&p, "has_usm %s\n", str_yes_no(xe->info.has_usm));
drm_printf(&p, "skip_guc_pc %s\n", str_yes_no(xe->info.skip_guc_pc));
drm_printf(&p, "multi_lrc_engine_classes");
print_engine_class_mask(&p, xe->info.multi_lrc_mask);
for_each_gt(gt, xe, id) {
drm_printf(&p, "gt%d force wake %d\n", id,
xe_force_wake_ref(gt_to_fw(gt), XE_FW_GT));
drm_printf(&p, "gt%d engine_mask 0x%llx\n", id,
gt->info.engine_mask);
drm_printf(&p, "gt%d multi_queue_engine_class_mask 0x%x\n", id,
gt->info.multi_queue_engine_class_mask);
drm_printf(&p, "gt%d engines", id);
print_engine_mask(&p, gt, gt->info.engine_mask);
drm_printf(&p, "gt%d multi_queue_engine_classes", id);
print_engine_class_mask(&p, gt->info.multi_queue_engine_class_mask);
}
return 0;

View File

@ -3,6 +3,9 @@
* Copyright © 2025 Intel Corporation
*/
#ifndef _XE_DEP_SCHEDULER_H_
#define _XE_DEP_SCHEDULER_H_
#include <linux/types.h>
struct drm_sched_entity;
@ -19,3 +22,5 @@ void xe_dep_scheduler_fini(struct xe_dep_scheduler *dep_scheduler);
struct drm_sched_entity *
xe_dep_scheduler_entity(struct xe_dep_scheduler *dep_scheduler);
#endif

View File

@ -8,7 +8,7 @@
#include <linux/ascii85.h>
#include <linux/devcoredump.h>
#include <generated/utsrelease.h>
#include <linux/utsname.h>
#include <drm/drm_managed.h>
@ -101,7 +101,7 @@ static ssize_t __xe_devcoredump_read(char *buffer, ssize_t count,
drm_puts(&p, "**** Xe Device Coredump ****\n");
drm_printf(&p, "Reason: %s\n", ss->reason);
drm_puts(&p, "kernel: " UTS_RELEASE "\n");
drm_printf(&p, "kernel: %s\n", init_utsname()->release);
drm_puts(&p, "module: " KBUILD_MODNAME "\n");
ts = ktime_to_timespec64(ss->snapshot_time);
@ -149,7 +149,8 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
xe_guc_ct_snapshot_free(ss->guc.ct);
ss->guc.ct = NULL;
xe_guc_capture_put_matched_nodes(&ss->gt->uc.guc);
if (!IS_ERR_OR_NULL(ss->gt))
xe_guc_capture_put_matched_nodes(&ss->gt->uc.guc);
ss->matched_node = NULL;
xe_guc_exec_queue_snapshot_free(ss->ge);
@ -254,7 +255,8 @@ static void xe_devcoredump_free(void *data)
if (!data || !coredump_to_xe(coredump))
return;
cancel_work_sync(&coredump->snapshot.work);
if (coredump->captured)
cancel_work_sync(&coredump->snapshot.work);
mutex_lock(&coredump->lock);

View File

@ -17,6 +17,7 @@
#include <drm/drm_managed.h>
#include <drm/drm_pagemap_util.h>
#include <drm/drm_print.h>
#include <kunit/static_stub.h>
#include <uapi/drm/xe_drm.h>
#include "display/xe_display.h"
@ -25,6 +26,7 @@
#include "regs/xe_regs.h"
#include "xe_bo.h"
#include "xe_bo_evict.h"
#include "xe_configfs.h"
#include "xe_debugfs.h"
#include "xe_defaults.h"
#include "xe_devcoredump.h"
@ -65,6 +67,7 @@
#include "xe_survivability_mode.h"
#include "xe_sriov.h"
#include "xe_svm.h"
#include "xe_sysctrl.h"
#include "xe_tile.h"
#include "xe_ttm_stolen_mgr.h"
#include "xe_ttm_sys_mgr.h"
@ -389,7 +392,7 @@ bool xe_is_xe_file(const struct file *file)
return file->f_op == &xe_driver_fops;
}
static struct drm_driver driver = {
static struct drm_driver regular_driver = {
.driver_features =
DRIVER_GEM |
DRIVER_RENDER | DRIVER_SYNCOBJ |
@ -414,6 +417,40 @@ static struct drm_driver driver = {
.patchlevel = DRIVER_PATCHLEVEL,
};
#ifdef CONFIG_PCI_IOV
static const struct drm_ioctl_desc xe_ioctls_admin_only[] = {
DRM_IOCTL_DEF_DRV(XE_DEVICE_QUERY, xe_query_ioctl, DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(XE_OBSERVATION, xe_observation_ioctl, DRM_RENDER_ALLOW),
};
static struct drm_driver admin_only_driver = {
.driver_features =
DRIVER_GEM | DRIVER_RENDER | DRIVER_GEM_GPUVA,
.open = xe_file_open,
.postclose = xe_file_close,
.ioctls = xe_ioctls_admin_only,
.num_ioctls = ARRAY_SIZE(xe_ioctls_admin_only),
.fops = &xe_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
};
/**
* xe_device_is_admin_only() - Check whether device is admin only or not.
* @xe: the &xe_device to check
*
* Return: true if the device is admin only, false otherwise.
*/
bool xe_device_is_admin_only(const struct xe_device *xe)
{
KUNIT_STATIC_STUB_REDIRECT(xe_device_is_admin_only, xe);
return xe->drm.driver == &admin_only_driver;
}
#endif
static void xe_device_destroy(struct drm_device *dev, void *dummy)
{
struct xe_device *xe = to_xe_device(dev);
@ -438,16 +475,26 @@ static void xe_device_destroy(struct drm_device *dev, void *dummy)
struct xe_device *xe_device_create(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct drm_driver *driver = &regular_driver;
struct xe_device *xe;
int err;
xe_display_driver_set_hooks(&driver);
#ifdef CONFIG_PCI_IOV
/*
* Since XE device is not initialized yet, read from configfs
* directly to decide whether we are in admin-only PF mode or not.
*/
if (xe_configfs_admin_only_pf(pdev))
driver = &admin_only_driver;
#endif
err = aperture_remove_conflicting_pci_devices(pdev, driver.name);
xe_display_driver_set_hooks(driver);
err = aperture_remove_conflicting_pci_devices(pdev, driver->name);
if (err)
return ERR_PTR(err);
xe = devm_drm_dev_alloc(&pdev->dev, &driver, struct xe_device, drm);
xe = devm_drm_dev_alloc(&pdev->dev, driver, struct xe_device, drm);
if (IS_ERR(xe))
return xe;
@ -707,6 +754,11 @@ int xe_device_probe_early(struct xe_device *xe)
xe_sriov_probe_early(xe);
if (xe_device_is_admin_only(xe) && !IS_SRIOV_PF(xe)) {
xe_err(xe, "Can't run Admin-only mode without SR-IOV PF mode!\n");
return -ENODEV;
}
if (IS_SRIOV_VF(xe))
vf_update_device_info(xe);
@ -992,6 +1044,10 @@ int xe_device_probe(struct xe_device *xe)
if (err)
goto err_unregister_display;
err = xe_sysctrl_init(xe);
if (err)
goto err_unregister_display;
err = xe_device_sysfs_init(xe);
if (err)
goto err_unregister_display;

View File

@ -146,37 +146,37 @@ static inline struct xe_force_wake *gt_to_fw(struct xe_gt *gt)
void xe_device_assert_mem_access(struct xe_device *xe);
static inline bool xe_device_has_flat_ccs(struct xe_device *xe)
static inline bool xe_device_has_flat_ccs(const struct xe_device *xe)
{
return xe->info.has_flat_ccs;
}
static inline bool xe_device_has_sriov(struct xe_device *xe)
static inline bool xe_device_has_sriov(const struct xe_device *xe)
{
return xe->info.has_sriov;
}
static inline bool xe_device_has_msix(struct xe_device *xe)
static inline bool xe_device_has_msix(const struct xe_device *xe)
{
return xe->irq.msix.nvec > 0;
}
static inline bool xe_device_has_memirq(struct xe_device *xe)
static inline bool xe_device_has_memirq(const struct xe_device *xe)
{
return GRAPHICS_VERx100(xe) >= 1250;
}
static inline bool xe_device_uses_memirq(struct xe_device *xe)
static inline bool xe_device_uses_memirq(const struct xe_device *xe)
{
return xe_device_has_memirq(xe) && (IS_SRIOV_VF(xe) || xe_device_has_msix(xe));
}
static inline bool xe_device_has_lmtt(struct xe_device *xe)
static inline bool xe_device_has_lmtt(const struct xe_device *xe)
{
return IS_DGFX(xe);
}
static inline bool xe_device_has_mert(struct xe_device *xe)
static inline bool xe_device_has_mert(const struct xe_device *xe)
{
return xe->info.has_mert;
}
@ -211,6 +211,15 @@ bool xe_is_xe_file(const struct file *file);
struct xe_vm *xe_device_asid_to_vm(struct xe_device *xe, u32 asid);
#ifdef CONFIG_PCI_IOV
bool xe_device_is_admin_only(const struct xe_device *xe);
#else
static inline bool xe_device_is_admin_only(const struct xe_device *xe)
{
return false;
}
#endif
/*
* Occasionally it is seen that the G2H worker starts running after a delay of more than
* a second even after being queued and activated by the Linux workqueue subsystem. This

View File

@ -27,6 +27,7 @@
#include "xe_sriov_vf_ccs_types.h"
#include "xe_step_types.h"
#include "xe_survivability_mode_types.h"
#include "xe_sysctrl_types.h"
#include "xe_tile_types.h"
#include "xe_validation.h"
@ -196,6 +197,8 @@ struct xe_device {
u8 has_soc_remapper_telem:1;
/** @info.has_sriov: Supports SR-IOV */
u8 has_sriov:1;
/** @info.has_sysctrl: Supports System Controller */
u8 has_sysctrl:1;
/** @info.has_usm: Device has unified shared memory support */
u8 has_usm:1;
/** @info.has_64bit_timestamp: Device supports 64-bit timestamps */
@ -215,8 +218,6 @@ struct xe_device {
u8 probe_display:1;
/** @info.skip_guc_pc: Skip GuC based PM feature init */
u8 skip_guc_pc:1;
/** @info.skip_mtcfg: skip Multi-Tile configuration from MTCFG register */
u8 skip_mtcfg:1;
/** @info.skip_pcode: skip access to PCODE uC */
u8 skip_pcode:1;
/** @info.needs_shared_vf_gt_wq: needs shared GT WQ on VF */
@ -273,7 +274,7 @@ struct xe_device {
struct xe_vram_region *vram;
/** @mem.sys_mgr: system TTM manager */
struct ttm_resource_manager sys_mgr;
/** @mem.sys_mgr: system memory shrinker. */
/** @mem.shrinker: system memory shrinker. */
struct xe_shrinker *shrinker;
} mem;
@ -295,7 +296,7 @@ struct xe_device {
/** @usm: unified memory state */
struct {
/** @usm.asid: convert a ASID to VM */
/** @usm.asid_to_vm: convert an ASID to VM */
struct xarray asid_to_vm;
/** @usm.next_asid: next ASID, used to cyclical alloc asids */
u32 next_asid;
@ -312,7 +313,7 @@ struct xe_device {
/** @usm.pf_queue: Page fault queues */
struct xe_pagefault_queue pf_queue[XE_PAGEFAULT_QUEUE_COUNT];
#if IS_ENABLED(CONFIG_DRM_XE_PAGEMAP)
/** @usm.pagemap_shrinker: Shrinker for unused pagemaps */
/** @usm.dpagemap_shrinker: Shrinker for unused pagemaps */
struct drm_pagemap_shrinker *dpagemap_shrinker;
#endif
} usm;
@ -334,7 +335,7 @@ struct xe_device {
struct list_head kernel_bo_present;
/** @pinned.late.evicted: pinned BO that have been evicted */
struct list_head evicted;
/** @pinned.external: pinned external and dma-buf. */
/** @pinned.late.external: pinned external and dma-buf. */
struct list_head external;
} late;
} pinned;
@ -369,7 +370,7 @@ struct xe_device {
struct {
/**
* @mem_access.vram_userfault.lock: Protects access to
* @vram_usefault.list Using mutex instead of spinlock
* @mem_access.vram_userfault.list Using mutex instead of spinlock
* as lock is applied to entire list operation which
* may sleep
*/
@ -400,7 +401,7 @@ struct xe_device {
const struct xe_pat_table_entry *pat_primary_pta;
/** @pat.pat_media_pta: media GT PAT entry for page table accesses */
const struct xe_pat_table_entry *pat_media_pta;
u32 idx[__XE_CACHE_LEVEL_COUNT];
u16 idx[__XE_CACHE_LEVEL_COUNT];
} pat;
/** @d3cold: Encapsulate d3cold related stuff */
@ -508,6 +509,9 @@ struct xe_device {
/** @i2c: I2C host controller */
struct xe_i2c *i2c;
/** @sc: System Controller */
struct xe_sysctrl sc;
/** @atomic_svm_timeslice_ms: Atomic SVM fault timeslice MS */
u32 atomic_svm_timeslice_ms;
@ -578,7 +582,7 @@ struct xe_file {
/** @vm: VM state for file */
struct {
/** @vm.xe: xarray to store VMs */
/** @vm.xa: xarray to store VMs */
struct xarray xa;
/**
* @vm.lock: Protects VM lookup + reference and removal from

View File

@ -4,3 +4,4 @@
22019338487_display PLATFORM(LUNARLAKE)
14022085890 SUBPLATFORM(BATTLEMAGE, G21)
14026539277 PLATFORM(NOVALAKE_P), PLATFORM_STEP(A0, B0)
14026633728 PLATFORM(CRESCENTISLAND)

View File

@ -27,6 +27,16 @@ static int hw_query_error_counter(struct xe_drm_ras_counter *info,
return 0;
}
static int hw_clear_error_counter(struct xe_drm_ras_counter *info, u32 error_id)
{
if (!info || !info[error_id].name)
return -ENOENT;
atomic_set(&info[error_id].counter, 0);
return 0;
}
static int query_uncorrectable_error_counter(struct drm_ras_node *ep, u32 error_id,
const char **name, u32 *val)
{
@ -37,6 +47,15 @@ static int query_uncorrectable_error_counter(struct drm_ras_node *ep, u32 error_
return hw_query_error_counter(info, error_id, name, val);
}
static int clear_uncorrectable_error_counter(struct drm_ras_node *node, u32 error_id)
{
struct xe_device *xe = node->priv;
struct xe_drm_ras *ras = &xe->ras;
struct xe_drm_ras_counter *info = ras->info[DRM_XE_RAS_ERR_SEV_UNCORRECTABLE];
return hw_clear_error_counter(info, error_id);
}
static int query_correctable_error_counter(struct drm_ras_node *ep, u32 error_id,
const char **name, u32 *val)
{
@ -47,6 +66,15 @@ static int query_correctable_error_counter(struct drm_ras_node *ep, u32 error_id
return hw_query_error_counter(info, error_id, name, val);
}
static int clear_correctable_error_counter(struct drm_ras_node *node, u32 error_id)
{
struct xe_device *xe = node->priv;
struct xe_drm_ras *ras = &xe->ras;
struct xe_drm_ras_counter *info = ras->info[DRM_XE_RAS_ERR_SEV_CORRECTABLE];
return hw_clear_error_counter(info, error_id);
}
static struct xe_drm_ras_counter *allocate_and_copy_counters(struct xe_device *xe)
{
struct xe_drm_ras_counter *counter;
@ -92,10 +120,13 @@ static int assign_node_params(struct xe_device *xe, struct drm_ras_node *node,
if (IS_ERR(ras->info[severity]))
return PTR_ERR(ras->info[severity]);
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE)
if (severity == DRM_XE_RAS_ERR_SEV_CORRECTABLE) {
node->query_error_counter = query_correctable_error_counter;
else
node->clear_error_counter = clear_correctable_error_counter;
} else {
node->query_error_counter = query_uncorrectable_error_counter;
node->clear_error_counter = clear_uncorrectable_error_counter;
}
return 0;
}

View File

@ -2,8 +2,8 @@
/*
* Copyright © 2026 Intel Corporation
*/
#ifndef XE_DRM_RAS_H_
#define XE_DRM_RAS_H_
#ifndef _XE_DRM_RAS_H_
#define _XE_DRM_RAS_H_
struct xe_device;

View File

@ -3,8 +3,8 @@
* Copyright © 2025 Intel Corporation
*/
#ifndef __XE_EU_STALL_H__
#define __XE_EU_STALL_H__
#ifndef _XE_EU_STALL_H_
#define _XE_EU_STALL_H_
#include "xe_gt_types.h"
#include "xe_sriov.h"

View File

@ -214,7 +214,7 @@ struct xe_exec_queue {
*/
struct xe_dep_scheduler *dep_scheduler;
/**
* @last_fence: last fence for tlb invalidation, protected by
* @tlb_inval.last_fence: last fence for tlb invalidation, protected by
* vm->lock in write mode
*/
struct dma_fence *last_fence;

View File

@ -47,7 +47,6 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc,
struct xe_mmio *mmio = &gt->mmio;
struct xe_device *xe = gt_to_xe(gt);
u64 lrc_desc;
u32 ring_mode = REG_MASKED_FIELD_ENABLE(GFX_DISABLE_LEGACY_MODE);
lrc_desc = xe_lrc_descriptor(lrc);
@ -59,10 +58,6 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc,
lrc_desc |= FIELD_PREP(SW_CTX_ID, ctx_id);
}
if (hwe->class == XE_ENGINE_CLASS_COMPUTE)
xe_mmio_write32(mmio, RCU_MODE,
REG_MASKED_FIELD_ENABLE(RCU_MODE_CCS_ENABLE));
xe_lrc_write_ctx_reg(lrc, CTX_RING_TAIL, lrc->ring.tail);
lrc->ring.old_tail = lrc->ring.tail;
@ -82,10 +77,6 @@ static void __start_lrc(struct xe_hw_engine *hwe, struct xe_lrc *lrc,
xe_bo_ggtt_addr(hwe->hwsp));
xe_mmio_read32(mmio, RING_HWS_PGA(hwe->mmio_base));
if (xe_device_has_msix(gt_to_xe(hwe->gt)))
ring_mode |= REG_MASKED_FIELD_ENABLE(GFX_MSIX_INTERRUPT_ENABLE);
xe_mmio_write32(mmio, RING_MODE(hwe->mmio_base), ring_mode);
xe_mmio_write32(mmio, RING_EXECLIST_SQ_CONTENTS_LO(hwe->mmio_base),
lower_32_bits(lrc_desc));
xe_mmio_write32(mmio, RING_EXECLIST_SQ_CONTENTS_HI(hwe->mmio_base),

View File

@ -24,6 +24,7 @@
#include "xe_gt_types.h"
#include "xe_map.h"
#include "xe_mmio.h"
#include "xe_pat.h"
#include "xe_pm.h"
#include "xe_res_cursor.h"
#include "xe_sriov.h"
@ -115,7 +116,6 @@ struct xe_ggtt {
/** @size: Total usable size of this GGTT */
u64 size;
#define XE_GGTT_FLAGS_64K BIT(0)
/**
* @flags: Flags for this GGTT
* Acceptable flags:
@ -259,7 +259,7 @@ static u64 xe_ggtt_get_pte(struct xe_ggtt *ggtt, u64 addr)
static void xe_ggtt_clear(struct xe_ggtt *ggtt, u64 start, u64 size)
{
u16 pat_index = tile_to_xe(ggtt->tile)->pat.idx[XE_CACHE_WB];
u16 pat_index = xe_cache_pat_idx(tile_to_xe(ggtt->tile), XE_CACHE_WB);
u64 end = start + size - 1;
u64 scratch_pte;
@ -724,7 +724,7 @@ static void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
void xe_ggtt_map_bo_unlocked(struct xe_ggtt *ggtt, struct xe_bo *bo)
{
u16 cache_mode = bo->flags & XE_BO_FLAG_NEEDS_UC ? XE_CACHE_NONE : XE_CACHE_WB;
u16 pat_index = tile_to_xe(ggtt->tile)->pat.idx[cache_mode];
u16 pat_index = xe_cache_pat_idx(tile_to_xe(ggtt->tile), cache_mode);
u64 pte;
mutex_lock(&ggtt->lock);
@ -841,7 +841,7 @@ static int __xe_ggtt_insert_bo_at(struct xe_ggtt *ggtt, struct xe_bo *bo,
bo->ggtt_node[tile_id] = NULL;
} else {
u16 cache_mode = bo->flags & XE_BO_FLAG_NEEDS_UC ? XE_CACHE_NONE : XE_CACHE_WB;
u16 pat_index = tile_to_xe(ggtt->tile)->pat.idx[cache_mode];
u16 pat_index = xe_cache_pat_idx(tile_to_xe(ggtt->tile), cache_mode);
u64 pte = ggtt->pt_ops->pte_encode_flags(bo, pat_index);
xe_ggtt_map_bo(ggtt, bo->ggtt_node[tile_id], bo, pte);

View File

@ -993,7 +993,6 @@ void xe_gt_reset_async(struct xe_gt *gt)
void xe_gt_suspend_prepare(struct xe_gt *gt)
{
CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FORCEWAKE_ALL);
xe_uc_suspend_prepare(&gt->uc);
}

View File

@ -216,9 +216,7 @@ static const struct xe_mmio_range xe2lpg_sqidi_psmi_steering_table[] = {
static const struct xe_mmio_range xe2lpg_instance0_steering_table[] = {
{ 0x004000, 0x004AFF }, /* GAM, rsvd, GAMWKR */
{ 0x008700, 0x00887F }, /* SQIDI, MEMPIPE */
{ 0x00B000, 0x00B3FF }, /* NODE, L3BANK */
{ 0x00C800, 0x00CFFF }, /* GAM */
{ 0x00D880, 0x00D8FF }, /* NODE */
{ 0x00DD00, 0x00DDFF }, /* MEMPIPE */
{ 0x00E900, 0x00E97F }, /* MEMPIPE */
{ 0x00F000, 0x00FFFF }, /* GAM, GAMWKR */
@ -267,7 +265,7 @@ static const struct xe_mmio_range xe3p_xpc_gam_grp1_steering_table[] = {
{},
};
static const struct xe_mmio_range xe3p_xpc_node_steering_table[] = {
static const struct xe_mmio_range xe2_node_steering_table[] = {
{ 0x00B000, 0x00B0FF },
{ 0x00D880, 0x00D8FF },
{},
@ -298,7 +296,7 @@ static void init_steering_l3bank(struct xe_gt *gt)
struct xe_device *xe = gt_to_xe(gt);
struct xe_mmio *mmio = &gt->mmio;
if (GRAPHICS_VER(xe) >= 35) {
if (GRAPHICS_VER(xe) >= 20) {
unsigned int first_bank = xe_l3_bank_mask_ffs(gt->fuse_topo.l3_bank_mask);
const int banks_per_node = 4;
unsigned int node = first_bank / banks_per_node;
@ -430,19 +428,6 @@ void xe_gt_mcr_get_dss_steering(const struct xe_gt *gt, unsigned int dss, u16 *g
*instance = dss % gt->steering_dss_per_grp;
}
/**
* xe_gt_mcr_steering_info_to_dss_id - Get DSS ID from group/instance steering
* @gt: GT structure
* @group: steering group ID
* @instance: steering instance ID
*
* Return: the converted DSS id.
*/
u32 xe_gt_mcr_steering_info_to_dss_id(struct xe_gt *gt, u16 group, u16 instance)
{
return group * dss_per_group(gt) + instance;
}
static void init_steering_dss(struct xe_gt *gt)
{
gt->steering_dss_per_grp = dss_per_group(gt);
@ -536,7 +521,7 @@ void xe_gt_mcr_init_early(struct xe_gt *gt)
gt->steering[GAM1].ranges = xe3p_xpc_gam_grp1_steering_table;
gt->steering[INSTANCE0].ranges = xe3p_xpc_instance0_steering_table;
gt->steering[L3BANK].ranges = xelpg_l3bank_steering_table;
gt->steering[NODE].ranges = xe3p_xpc_node_steering_table;
gt->steering[NODE].ranges = xe2_node_steering_table;
} else if (GRAPHICS_VERx100(xe) >= 3510) {
gt->steering[DSS].ranges = xe2lpg_dss_steering_table;
gt->steering[INSTANCE0].ranges = xe3p_lpg_instance0_steering_table;
@ -544,6 +529,8 @@ void xe_gt_mcr_init_early(struct xe_gt *gt)
gt->steering[DSS].ranges = xe2lpg_dss_steering_table;
gt->steering[SQIDI_PSMI].ranges = xe2lpg_sqidi_psmi_steering_table;
gt->steering[INSTANCE0].ranges = xe2lpg_instance0_steering_table;
gt->steering[L3BANK].ranges = xelpg_l3bank_steering_table;
gt->steering[NODE].ranges = xe2_node_steering_table;
} else if (GRAPHICS_VERx100(xe) >= 1270) {
gt->steering[INSTANCE0].ranges = xelpg_instance0_steering_table;
gt->steering[L3BANK].ranges = xelpg_l3bank_steering_table;

View File

@ -33,7 +33,6 @@ bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt,
void xe_gt_mcr_steering_dump(struct xe_gt *gt, struct drm_printer *p);
void xe_gt_mcr_get_dss_steering(const struct xe_gt *gt,
unsigned int dss, u16 *group, u16 *instance);
u32 xe_gt_mcr_steering_info_to_dss_id(struct xe_gt *gt, u16 group, u16 instance);
/*
* Loop over each DSS and determine the group and instance IDs that

View File

@ -219,6 +219,7 @@ static void pf_restart(struct xe_gt *gt)
xe_gt_assert(gt, !xe_pm_runtime_suspended(xe));
xe_gt_sriov_pf_policy_restart(gt);
xe_gt_sriov_pf_config_restart(gt);
xe_gt_sriov_pf_control_restart(gt);

View File

@ -285,6 +285,13 @@ static u32 encode_config_ggtt(u32 *cfg, const struct xe_gt_sriov_config *config,
return encode_ggtt(cfg, xe_ggtt_node_addr(node), xe_ggtt_node_size(node), details);
}
static bool custom_sched_priority(struct xe_gt *gt, u32 priority)
{
return xe_gt_sriov_pf_policy_get_sched_if_idle_locked(gt) ?
priority != GUC_SCHED_PRIORITY_NORMAL :
priority != GUC_SCHED_PRIORITY_LOW;
}
static u32 encode_config_sched(struct xe_gt *gt, u32 *cfg, u32 n,
const struct xe_gt_sriov_config *config)
{
@ -313,6 +320,11 @@ static u32 encode_config_sched(struct xe_gt *gt, u32 *cfg, u32 n,
cfg[n++] = config->preempt_timeout[0];
}
if (custom_sched_priority(gt, config->sched_priority)) {
cfg[n++] = PREP_GUC_KLV_TAG(VF_CFG_SCHED_PRIORITY);
cfg[n++] = config->sched_priority;
}
return n;
}
@ -1922,29 +1934,45 @@ static u64 pf_profile_fair_lmem(struct xe_gt *gt, unsigned int num_vfs)
return ALIGN_DOWN(fair, alignment);
}
static void __pf_show_provisioning_lmem(struct xe_gt *gt, unsigned int first_vf,
unsigned int num_vfs, bool provisioned)
static void __pf_show_provisioned(struct xe_gt *gt, unsigned int first_vf,
unsigned int num_vfs, bool provisioned,
u32 (*get32)(struct xe_gt *, unsigned int),
u64 (*get64)(struct xe_gt *, unsigned int),
const char *what)
{
unsigned int allvfs = 1 + xe_gt_sriov_pf_get_totalvfs(gt); /* PF plus VFs */
unsigned long *bitmap __free(bitmap) = bitmap_zalloc(allvfs, GFP_KERNEL);
unsigned int weight;
unsigned int n;
bool pf;
xe_gt_assert(gt, get32 || get64);
if (!bitmap)
return;
for (n = first_vf; n < first_vf + num_vfs; n++) {
if (!!pf_get_vf_config_lmem(gt, VFID(n)) == provisioned)
if ((get32 && (!!get32(gt, VFID(n)) == provisioned)) ||
(get64 && (!!get64(gt, VFID(n)) == provisioned)))
bitmap_set(bitmap, n, 1);
}
pf = test_and_clear_bit(0, bitmap);
weight = bitmap_weight(bitmap, allvfs);
if (!weight)
if (!pf && !weight)
return;
xe_gt_sriov_info(gt, "VF%s%*pbl %s provisioned with VRAM\n",
weight > 1 ? "s " : "", allvfs, bitmap,
provisioned ? "already" : "not");
xe_gt_sriov_info(gt, "%s%s%s%s%*pbl %s provisioned with %s\n",
pf ? "PF" : "", pf && weight ? " and " : "",
weight ? "VF" : "", weight > 1 ? "s " : "",
allvfs, bitmap, provisioned ? "already" : "not", what);
}
static void __pf_show_provisioning_lmem(struct xe_gt *gt, unsigned int first_vf,
unsigned int num_vfs, bool provisioned)
{
__pf_show_provisioned(gt, first_vf, num_vfs, provisioned,
NULL, pf_get_vf_config_lmem, "VRAM");
}
static void pf_show_all_provisioned_lmem(struct xe_gt *gt)
@ -2078,6 +2106,17 @@ static u32 pf_get_exec_quantum(struct xe_gt *gt, unsigned int vfid)
return config->exec_quantum[0];
}
static bool pf_non_default_exec_quantum(struct xe_gt *gt, unsigned int vfid)
{
struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid);
int i;
for (i = 0; i < ARRAY_SIZE(config->exec_quantum); i++)
if (config->exec_quantum[i])
return true;
return false;
}
/**
* xe_gt_sriov_pf_config_set_exec_quantum_locked() - Configure PF/VF execution quantum.
* @gt: the &xe_gt
@ -2154,6 +2193,25 @@ u32 xe_gt_sriov_pf_config_get_exec_quantum(struct xe_gt *gt, unsigned int vfid)
return pf_get_exec_quantum(gt, vfid);
}
static int pf_bulk_set_exec_quantum(struct xe_gt *gt, u32 exec_quantum,
unsigned int first_vf, unsigned int num_vfs)
{
unsigned int n;
int err = 0;
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
for (n = first_vf; n < first_vf + num_vfs; n++) {
err = pf_provision_exec_quantum(gt, VFID(n), exec_quantum);
if (err)
break;
}
return pf_config_bulk_set_u32_done(gt, first_vf, num_vfs, exec_quantum,
pf_get_exec_quantum, "execution quantum",
exec_quantum_unit, n, err);
}
/**
* xe_gt_sriov_pf_config_bulk_set_exec_quantum_locked() - Configure EQ for PF and VFs.
* @gt: the &xe_gt to configure
@ -2166,20 +2224,8 @@ u32 xe_gt_sriov_pf_config_get_exec_quantum(struct xe_gt *gt, unsigned int vfid)
int xe_gt_sriov_pf_config_bulk_set_exec_quantum_locked(struct xe_gt *gt, u32 exec_quantum)
{
unsigned int totalvfs = xe_gt_sriov_pf_get_totalvfs(gt);
unsigned int n;
int err = 0;
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
for (n = 0; n <= totalvfs; n++) {
err = pf_provision_exec_quantum(gt, VFID(n), exec_quantum);
if (err)
break;
}
return pf_config_bulk_set_u32_done(gt, 0, 1 + totalvfs, exec_quantum,
pf_get_exec_quantum, "execution quantum",
exec_quantum_unit, n, err);
return pf_bulk_set_exec_quantum(gt, exec_quantum, PFID, 1 + totalvfs);
}
static int pf_provision_groups_exec_quantums(struct xe_gt *gt, unsigned int vfid,
@ -2293,6 +2339,17 @@ static u32 pf_get_preempt_timeout(struct xe_gt *gt, unsigned int vfid)
return config->preempt_timeout[0];
}
static bool pf_non_default_preempt_timeout(struct xe_gt *gt, unsigned int vfid)
{
struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid);
int i;
for (i = 0; i < ARRAY_SIZE(config->preempt_timeout); i++)
if (config->preempt_timeout[i])
return true;
return false;
}
/**
* xe_gt_sriov_pf_config_set_preempt_timeout_locked() - Configure PF/VF preemption timeout.
* @gt: the &xe_gt
@ -2368,6 +2425,25 @@ u32 xe_gt_sriov_pf_config_get_preempt_timeout(struct xe_gt *gt, unsigned int vfi
return pf_get_preempt_timeout(gt, vfid);
}
static int pf_bulk_set_preempt_timeout(struct xe_gt *gt, u32 preempt_timeout,
unsigned int first_vf, unsigned int num_vfs)
{
unsigned int n;
int err = 0;
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
for (n = first_vf; n < first_vf + num_vfs; n++) {
err = pf_provision_preempt_timeout(gt, VFID(n), preempt_timeout);
if (err)
break;
}
return pf_config_bulk_set_u32_done(gt, first_vf, num_vfs, preempt_timeout,
pf_get_preempt_timeout, "preemption timeout",
preempt_timeout_unit, n, err);
}
/**
* xe_gt_sriov_pf_config_bulk_set_preempt_timeout_locked() - Configure PT for PF and VFs.
* @gt: the &xe_gt to configure
@ -2380,20 +2456,8 @@ u32 xe_gt_sriov_pf_config_get_preempt_timeout(struct xe_gt *gt, unsigned int vfi
int xe_gt_sriov_pf_config_bulk_set_preempt_timeout_locked(struct xe_gt *gt, u32 preempt_timeout)
{
unsigned int totalvfs = xe_gt_sriov_pf_get_totalvfs(gt);
unsigned int n;
int err = 0;
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
for (n = 0; n <= totalvfs; n++) {
err = pf_provision_preempt_timeout(gt, VFID(n), preempt_timeout);
if (err)
break;
}
return pf_config_bulk_set_u32_done(gt, 0, 1 + totalvfs, preempt_timeout,
pf_get_preempt_timeout, "preemption timeout",
preempt_timeout_unit, n, err);
return pf_bulk_set_preempt_timeout(gt, preempt_timeout, PFID, 1 + totalvfs);
}
static int pf_provision_groups_preempt_timeouts(struct xe_gt *gt, unsigned int vfid,
@ -2500,7 +2564,7 @@ static int pf_provision_sched_priority(struct xe_gt *gt, unsigned int vfid, u32
return 0;
}
static int pf_get_sched_priority(struct xe_gt *gt, unsigned int vfid)
static u32 pf_get_sched_priority(struct xe_gt *gt, unsigned int vfid)
{
struct xe_gt_sriov_config *config = pf_pick_vf_config(gt, vfid);
@ -2550,6 +2614,35 @@ u32 xe_gt_sriov_pf_config_get_sched_priority(struct xe_gt *gt, unsigned int vfid
return priority;
}
/**
* xe_gt_sriov_pf_config_force_sched_priority_locked() - Force update scheduling priority.
* @gt: the &xe_gt
* @priority: new scheduling priority to set
*
* This function allows to update cached values of the scheduling priorities of all
* VFs (and PF) as result of applying the `GUC_KLV_VGT_POLICY_SCHED_IF_IDLE`_ policy.
*
* This function can only be called on PF.
*/
void xe_gt_sriov_pf_config_force_sched_priority_locked(struct xe_gt *gt, u32 priority)
{
unsigned int total_vfs = xe_gt_sriov_pf_get_totalvfs(gt);
struct xe_gt_sriov_config *config;
unsigned int n;
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
for (n = 0; n <= total_vfs; n++) {
config = pf_pick_vf_config(gt, VFID(n));
config->sched_priority = priority;
}
pf_config_bulk_set_u32_done(gt, PFID, 1 + total_vfs, priority,
pf_get_sched_priority, "scheduling priority",
sched_priority_unit, n, 0);
}
static void pf_reset_config_sched(struct xe_gt *gt, struct xe_gt_sriov_config *config)
{
int i;
@ -2562,6 +2655,104 @@ static void pf_reset_config_sched(struct xe_gt *gt, struct xe_gt_sriov_config *c
}
}
static bool pf_non_default_sched(struct xe_gt *gt, unsigned int vfid)
{
return pf_non_default_exec_quantum(gt, vfid) ||
pf_non_default_preempt_timeout(gt, vfid) ||
custom_sched_priority(gt, pf_get_sched_priority(gt, vfid));
}
static void __pf_show_provisioned_sched(struct xe_gt *gt, unsigned int first_vf,
unsigned int num_vfs, bool provisioned)
{
__pf_show_provisioned(gt, first_vf, num_vfs, provisioned,
pf_get_exec_quantum, NULL, "EQ");
__pf_show_provisioned(gt, first_vf, num_vfs, provisioned,
pf_get_preempt_timeout, NULL, "PT");
/* we only care about non-default priorities */
if (provisioned)
__pf_show_provisioned(gt, first_vf, num_vfs, true,
pf_get_sched_priority, NULL, "PRIORITY");
}
static void pf_show_all_provisioned_sched(struct xe_gt *gt)
{
__pf_show_provisioned_sched(gt, PFID, 1 + xe_gt_sriov_pf_get_totalvfs(gt), true);
}
static void pf_show_unprovisioned_sched(struct xe_gt *gt, unsigned int num_vfs)
{
__pf_show_provisioned_sched(gt, PFID, 1 + num_vfs, false);
}
static bool pf_needs_provision_sched(struct xe_gt *gt, unsigned int num_vfs)
{
unsigned int vfid;
for (vfid = PFID; vfid <= PFID + num_vfs; vfid++) {
if (pf_non_default_sched(gt, vfid)) {
pf_show_all_provisioned_sched(gt);
pf_show_unprovisioned_sched(gt, num_vfs);
return false;
}
}
if (xe_gt_sriov_pf_policy_get_sched_if_idle_locked(gt)) {
pf_show_all_provisioned_sched(gt);
pf_show_unprovisioned_sched(gt, num_vfs);
return false;
}
pf_show_all_provisioned_sched(gt);
return true;
}
/* With 16ms EQ/PT GuC should be able to handle up to 63 VFs within 2s */
#define XE_FAIR_EXEC_QUANTUM_MS 16
#define XE_FAIR_PREEMPT_TIMEOUT_US 16000
#define XE_FAIR_SCHED_PRIORITY GUC_SCHED_PRIORITY_LOW
#define XE_ADMIN_PF_SCHED_PRIORITY GUC_SCHED_PRIORITY_HIGH
/**
* xe_gt_sriov_pf_config_set_fair_sched() - Provision PF and VFs with fair scheduling.
* @gt: the &xe_gt
* @num_vfs: number of VFs to provision (can't be 0)
*
* This function can only be called on PF.
*
* Return: 0 on success or a negative error code on failure.
*/
int xe_gt_sriov_pf_config_set_fair_sched(struct xe_gt *gt, unsigned int num_vfs)
{
int result = 0;
int err;
xe_gt_assert(gt, num_vfs);
xe_gt_assert(gt, XE_FAIR_EXEC_QUANTUM_MS);
xe_gt_assert(gt, XE_FAIR_PREEMPT_TIMEOUT_US);
guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
if (!pf_needs_provision_sched(gt, num_vfs))
return 0;
err = pf_bulk_set_exec_quantum(gt, XE_FAIR_EXEC_QUANTUM_MS, PFID, 1 + num_vfs);
result = result ?: err;
err = pf_bulk_set_preempt_timeout(gt, XE_FAIR_PREEMPT_TIMEOUT_US, PFID, 1 + num_vfs);
result = result ?: err;
xe_gt_assert(gt, XE_FAIR_SCHED_PRIORITY == GUC_SCHED_PRIORITY_LOW);
xe_gt_assert(gt, !xe_gt_sriov_pf_policy_get_sched_if_idle_locked(gt));
if (xe_sriov_pf_admin_only(gt_to_xe(gt))) {
err = pf_provision_sched_priority(gt, PFID, XE_ADMIN_PF_SCHED_PRIORITY);
result = result ?: err;
}
return result;
}
static int pf_provision_threshold(struct xe_gt *gt, unsigned int vfid,
enum xe_guc_klv_threshold_index index, u32 value)
{
@ -2838,6 +3029,9 @@ static int pf_validate_vf_config(struct xe_gt *gt, unsigned int vfid)
valid_all = valid_all && valid_lmem;
}
/* also check optional EQ/PT/PRIO */
valid_any = valid_any || pf_non_default_sched(gt, vfid);
return valid_all ? 0 : valid_any ? -ENOKEY : -ENODATA;
}

View File

@ -71,12 +71,14 @@ int xe_gt_sriov_pf_config_set_groups_preempt_timeouts(struct xe_gt *gt, unsigned
u32 xe_gt_sriov_pf_config_get_sched_priority(struct xe_gt *gt, unsigned int vfid);
int xe_gt_sriov_pf_config_set_sched_priority(struct xe_gt *gt, unsigned int vfid, u32 priority);
void xe_gt_sriov_pf_config_force_sched_priority_locked(struct xe_gt *gt, u32 priority);
u32 xe_gt_sriov_pf_config_get_threshold(struct xe_gt *gt, unsigned int vfid,
enum xe_guc_klv_threshold_index index);
int xe_gt_sriov_pf_config_set_threshold(struct xe_gt *gt, unsigned int vfid,
enum xe_guc_klv_threshold_index index, u32 value);
int xe_gt_sriov_pf_config_set_fair_sched(struct xe_gt *gt, unsigned int num_vfs);
int xe_gt_sriov_pf_config_set_fair(struct xe_gt *gt, unsigned int vfid, unsigned int num_vfs);
int xe_gt_sriov_pf_config_sanitize(struct xe_gt *gt, unsigned int vfid, long timeout);
int xe_gt_sriov_pf_config_release(struct xe_gt *gt, unsigned int vfid, bool force);

View File

@ -8,6 +8,7 @@
#include "abi/guc_actions_sriov_abi.h"
#include "xe_gt.h"
#include "xe_gt_sriov_pf_config.h"
#include "xe_gt_sriov_pf_helpers.h"
#include "xe_gt_sriov_pf_policy.h"
#include "xe_gt_sriov_printk.h"
@ -16,7 +17,6 @@
#include "xe_guc_ct.h"
#include "xe_guc_klv_helpers.h"
#include "xe_guc_submit.h"
#include "xe_pm.h"
/*
* Return: number of KLVs that were successfully parsed and saved,
@ -67,6 +67,15 @@ static int pf_push_policy_buf_klvs(struct xe_gt *gt, u32 num_klvs,
return err;
}
if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) {
struct drm_printer p = xe_gt_dbg_printer(gt);
void *klvs = xe_guc_buf_cpu_ptr(buf);
xe_gt_sriov_dbg(gt, "pushed policy update with %u KLV%s:\n",
num_klvs, str_plural(num_klvs));
xe_guc_klv_print(klvs, num_dwords, &p);
}
return 0;
}
@ -153,33 +162,14 @@ static int pf_update_policy_u32(struct xe_gt *gt, u16 key, u32 *policy, u32 valu
return 0;
}
static void pf_bulk_reset_sched_priority(struct xe_gt *gt, u32 priority)
{
unsigned int total_vfs = 1 + xe_gt_sriov_pf_get_totalvfs(gt);
unsigned int n;
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
for (n = 0; n < total_vfs; n++)
gt->sriov.pf.vfs[n].config.sched_priority = priority;
}
static int pf_provision_sched_if_idle(struct xe_gt *gt, bool enable)
{
int err;
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
err = pf_update_policy_bool(gt, GUC_KLV_VGT_POLICY_SCHED_IF_IDLE_KEY,
&gt->sriov.pf.policy.guc.sched_if_idle,
enable);
if (!err)
pf_bulk_reset_sched_priority(gt, enable ? GUC_SCHED_PRIORITY_NORMAL :
GUC_SCHED_PRIORITY_LOW);
return err;
return pf_update_policy_bool(gt, GUC_KLV_VGT_POLICY_SCHED_IF_IDLE_KEY,
&gt->sriov.pf.policy.guc.sched_if_idle,
enable);
}
static int pf_reprovision_sched_if_idle(struct xe_gt *gt)
@ -187,6 +177,9 @@ static int pf_reprovision_sched_if_idle(struct xe_gt *gt)
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
if (!gt->sriov.pf.policy.guc.sched_if_idle)
return 0;
return pf_provision_sched_if_idle(gt, gt->sriov.pf.policy.guc.sched_if_idle);
}
@ -199,7 +192,39 @@ static void pf_sanitize_sched_if_idle(struct xe_gt *gt)
}
/**
* xe_gt_sriov_pf_policy_set_sched_if_idle - Control the 'sched_if_idle' policy.
* xe_gt_sriov_pf_policy_set_sched_if_idle_locked() - Control the 'sched_if_idle' policy.
* @gt: the &xe_gt where to apply the policy
* @enable: the value of the 'sched_if_idle' policy
*
* This function can only be called on PF.
*
* Return: 0 on success or a negative error code on failure.
*/
int xe_gt_sriov_pf_policy_set_sched_if_idle_locked(struct xe_gt *gt, bool enable)
{
u32 priority;
int err;
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
err = pf_provision_sched_if_idle(gt, enable);
if (err)
return err;
/*
* As of GuC 70.12 a change of this policy impacts individual configs
* of all VFs. See `GUC_KLV_VGT_POLICY_SCHED_IF_IDLE`_ for details.
*/
xe_gt_assert(gt, GUC_FIRMWARE_VER_AT_LEAST(&gt->uc.guc, 70, 12));
priority = enable ? GUC_SCHED_PRIORITY_NORMAL : GUC_SCHED_PRIORITY_LOW;
xe_gt_sriov_pf_config_force_sched_priority_locked(gt, priority);
return 0;
}
/**
* xe_gt_sriov_pf_policy_set_sched_if_idle() - Control the 'sched_if_idle' policy.
* @gt: the &xe_gt where to apply the policy
* @enable: the value of the 'sched_if_idle' policy
*
@ -209,13 +234,26 @@ static void pf_sanitize_sched_if_idle(struct xe_gt *gt)
*/
int xe_gt_sriov_pf_policy_set_sched_if_idle(struct xe_gt *gt, bool enable)
{
int err;
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
mutex_lock(xe_gt_sriov_pf_master_mutex(gt));
err = pf_provision_sched_if_idle(gt, enable);
mutex_unlock(xe_gt_sriov_pf_master_mutex(gt));
return xe_gt_sriov_pf_policy_set_sched_if_idle_locked(gt, enable);
}
return err;
/**
* xe_gt_sriov_pf_policy_get_sched_if_idle_locked() - Retrieve value of 'sched_if_idle' policy.
* @gt: the &xe_gt where to read the policy from
*
* This function can only be called on PF.
*
* Return: last value of 'sched_if_idle' policy applied.
*/
bool xe_gt_sriov_pf_policy_get_sched_if_idle_locked(struct xe_gt *gt)
{
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
return gt->sriov.pf.policy.guc.sched_if_idle;
}
/**
@ -228,15 +266,10 @@ int xe_gt_sriov_pf_policy_set_sched_if_idle(struct xe_gt *gt, bool enable)
*/
bool xe_gt_sriov_pf_policy_get_sched_if_idle(struct xe_gt *gt)
{
bool enable;
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
mutex_lock(xe_gt_sriov_pf_master_mutex(gt));
enable = gt->sriov.pf.policy.guc.sched_if_idle;
mutex_unlock(xe_gt_sriov_pf_master_mutex(gt));
return enable;
return xe_gt_sriov_pf_policy_get_sched_if_idle_locked(gt);
}
static int pf_provision_reset_engine(struct xe_gt *gt, bool enable)
@ -253,6 +286,9 @@ static int pf_reprovision_reset_engine(struct xe_gt *gt)
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
if (!gt->sriov.pf.policy.guc.reset_engine)
return 0;
return pf_provision_reset_engine(gt, gt->sriov.pf.policy.guc.reset_engine);
}
@ -319,6 +355,9 @@ static int pf_reprovision_sample_period(struct xe_gt *gt)
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
lockdep_assert_held(xe_gt_sriov_pf_master_mutex(gt));
if (!gt->sriov.pf.policy.guc.sample_period)
return 0;
return pf_provision_sample_period(gt, gt->sriov.pf.policy.guc.sample_period);
}
@ -689,30 +728,23 @@ void xe_gt_sriov_pf_policy_sanitize(struct xe_gt *gt)
}
/**
* xe_gt_sriov_pf_policy_reprovision - Reprovision (and optionally reset) policy settings.
* xe_gt_sriov_pf_policy_restart() - Reprovision policy settings.
* @gt: the &xe_gt
* @reset: if true will reprovision using default values instead of latest
*
* This function can only be called on PF.
*
* Return: 0 on success or a negative error code on failure.
*/
int xe_gt_sriov_pf_policy_reprovision(struct xe_gt *gt, bool reset)
int xe_gt_sriov_pf_policy_restart(struct xe_gt *gt)
{
int err = 0;
xe_pm_runtime_get_noresume(gt_to_xe(gt));
guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
mutex_lock(xe_gt_sriov_pf_master_mutex(gt));
if (reset)
pf_sanitize_guc_policies(gt);
err |= pf_reprovision_sched_if_idle(gt);
err |= pf_reprovision_reset_engine(gt);
err |= pf_reprovision_sample_period(gt);
err |= pf_reprovision_sched_groups(gt);
mutex_unlock(xe_gt_sriov_pf_master_mutex(gt));
xe_pm_runtime_put(gt_to_xe(gt));
return err ? -ENXIO : 0;
}

View File

@ -14,7 +14,9 @@ struct drm_printer;
struct xe_gt;
int xe_gt_sriov_pf_policy_set_sched_if_idle(struct xe_gt *gt, bool enable);
int xe_gt_sriov_pf_policy_set_sched_if_idle_locked(struct xe_gt *gt, bool enable);
bool xe_gt_sriov_pf_policy_get_sched_if_idle(struct xe_gt *gt);
bool xe_gt_sriov_pf_policy_get_sched_if_idle_locked(struct xe_gt *gt);
int xe_gt_sriov_pf_policy_set_reset_engine(struct xe_gt *gt, bool enable);
bool xe_gt_sriov_pf_policy_get_reset_engine(struct xe_gt *gt);
int xe_gt_sriov_pf_policy_set_sample_period(struct xe_gt *gt, u32 value);
@ -29,7 +31,7 @@ bool xe_gt_sriov_pf_policy_sched_groups_enabled(struct xe_gt *gt);
void xe_gt_sriov_pf_policy_init(struct xe_gt *gt);
void xe_gt_sriov_pf_policy_sanitize(struct xe_gt *gt);
int xe_gt_sriov_pf_policy_reprovision(struct xe_gt *gt, bool reset);
int xe_gt_sriov_pf_policy_restart(struct xe_gt *gt);
int xe_gt_sriov_pf_policy_print(struct xe_gt *gt, struct drm_printer *p);
#endif

View File

@ -49,7 +49,6 @@ struct xe_gt_sriov_pf_workers {
* @service: service data.
* @control: control data.
* @policy: policy data.
* @migration: migration data.
* @spare: PF-only provisioning configuration.
* @vfs: metadata for all VFs.
*/

View File

@ -9,6 +9,47 @@
#include "xe_device.h"
#include "xe_gt_stats.h"
/**
* DOC: Xe GT Statistics
*
* Overview
* ========
*
* The Xe driver exposes per-GT statistics through the debugfs filesystem at::
*
* /sys/kernel/debug/dri/<device>/gt<id>/stats
*
* This interface requires the kernel to be built with ``CONFIG_DEBUG_FS=y``.
*
* Reading statistics
* ==================
*
* Reading the file prints all available statistics, one per line, in
* ``name: value`` format::
*
* $ cat /sys/kernel/debug/dri/0/gt0/stats
* svm_pagefault_count: 0
* tlb_inval_count: 1234
* ...
*
* All values are 64-bit unsigned integers aggregated across all CPUs.
* Counters accumulate since the driver was loaded or since the last explicit
* reset. Timing counters use microseconds as their unit; data volume counters
* use KiB.
*
* Resetting statistics
* ====================
*
* Writing a boolean true value to the file resets all counters to zero::
*
* echo 1 > /sys/kernel/debug/dri/0/gt0/stats
*
* Any value accepted by ``kstrtobool()`` (e.g. ``1``, ``y``, ``yes``,
* ``on``) triggers the reset. Resetting while the GPU is active may yield
* unpredictable intermediate values; it is recommended to reset only when
* the GPU is idle.
*/
static void xe_gt_stats_fini(struct drm_device *drm, void *arg)
{
struct xe_gt *gt = arg;

View File

@ -8,6 +8,124 @@
#include <linux/types.h>
/**
* enum xe_gt_stats_id - GT statistics identifiers
* @XE_GT_STATS_ID_SVM_PAGEFAULT_COUNT: Total SVM page faults handled.
* @XE_GT_STATS_ID_TLB_INVAL: Total GPU Translation Lookaside Buffer (TLB)
* invalidations issued.
* @XE_GT_STATS_ID_SVM_TLB_INVAL_COUNT: TLB invalidations issued during SVM
* page-fault handling.
* @XE_GT_STATS_ID_SVM_TLB_INVAL_US: Cumulative time (µs) waiting for TLB
* invalidations during SVM page-fault handling.
*
* @XE_GT_STATS_ID_VMA_PAGEFAULT_COUNT: Buffer-object (non-SVM) page faults
* handled.
* @XE_GT_STATS_ID_VMA_PAGEFAULT_KB: Size (KiB) of VMAs involved in
* buffer-object page fault handling.
* @XE_GT_STATS_ID_INVALID_PREFETCH_PAGEFAULT_COUNT: GPU prefetch faults for
* addresses with no valid backing.
*
* @XE_GT_STATS_ID_SVM_4K_PAGEFAULT_COUNT: SVM page faults resolved by
* mapping 4K pages.
* @XE_GT_STATS_ID_SVM_64K_PAGEFAULT_COUNT: SVM page faults resolved by
* mapping 64K pages.
* @XE_GT_STATS_ID_SVM_2M_PAGEFAULT_COUNT: SVM page faults resolved by
* mapping 2M pages.
* @XE_GT_STATS_ID_SVM_4K_VALID_PAGEFAULT_COUNT: Valid SVM page faults
* at 4K page size, where the GPU mapping was already valid resolved without
* creating new mappings.
* @XE_GT_STATS_ID_SVM_64K_VALID_PAGEFAULT_COUNT: Valid SVM page faults at 64K
* page size.
* @XE_GT_STATS_ID_SVM_2M_VALID_PAGEFAULT_COUNT: Valid SVM page faults at 2M
* page size.
* @XE_GT_STATS_ID_SVM_4K_PAGEFAULT_US: Cumulative time (µs) handling 4K SVM
* page faults.
* @XE_GT_STATS_ID_SVM_64K_PAGEFAULT_US: Cumulative time (µs) handling 64K
* SVM page faults.
* @XE_GT_STATS_ID_SVM_2M_PAGEFAULT_US: Cumulative time (µs) handling 2M SVM
* page faults.
*
* @XE_GT_STATS_ID_SVM_4K_MIGRATE_COUNT: 4K pages moved from CPU to device
* memory.
* @XE_GT_STATS_ID_SVM_64K_MIGRATE_COUNT: 64K pages moved from CPU to device
* memory.
* @XE_GT_STATS_ID_SVM_2M_MIGRATE_COUNT: 2M pages moved from CPU to device
* memory.
* @XE_GT_STATS_ID_SVM_4K_MIGRATE_US: Cumulative time (µs) moving 4K pages
* from CPU to device memory.
* @XE_GT_STATS_ID_SVM_64K_MIGRATE_US: Cumulative time (µs) moving 64K pages
* from CPU to device memory.
* @XE_GT_STATS_ID_SVM_2M_MIGRATE_US: Cumulative time (µs) moving 2M pages
* from CPU to device memory.
*
* @XE_GT_STATS_ID_SVM_DEVICE_COPY_US: Cumulative time (µs) for memory copies to
* device, across all page sizes.
* @XE_GT_STATS_ID_SVM_4K_DEVICE_COPY_US: Cumulative time (µs) for memory copies
* of 4K pages to device.
* @XE_GT_STATS_ID_SVM_64K_DEVICE_COPY_US: Cumulative time (µs) for memory
* copies of 64K pages to device.
* @XE_GT_STATS_ID_SVM_2M_DEVICE_COPY_US: Cumulative time (µs) for memory copies
* of 2M pages to device.
* @XE_GT_STATS_ID_SVM_CPU_COPY_US: Cumulative time (µs) for memory copies to
* CPU, across all page sizes.
* @XE_GT_STATS_ID_SVM_4K_CPU_COPY_US: Cumulative time (µs) for memory copies of
* 4K pages to CPU.
* @XE_GT_STATS_ID_SVM_64K_CPU_COPY_US: Cumulative time (µs) for memory copies
* of 64K pages to CPU.
* @XE_GT_STATS_ID_SVM_2M_CPU_COPY_US: Cumulative time (µs) for memory copies of
* 2M pages to CPU.
* @XE_GT_STATS_ID_SVM_DEVICE_COPY_KB: Data (KiB) copied to device across all
* page sizes.
* @XE_GT_STATS_ID_SVM_4K_DEVICE_COPY_KB: Data (KiB) copied to device for 4K
* pages.
* @XE_GT_STATS_ID_SVM_64K_DEVICE_COPY_KB: Data (KiB) copied to device for
* 64K pages.
* @XE_GT_STATS_ID_SVM_2M_DEVICE_COPY_KB: Data (KiB) copied to device for 2M
* pages.
* @XE_GT_STATS_ID_SVM_CPU_COPY_KB: Data (KiB) copied to CPU across all page
* sizes.
* @XE_GT_STATS_ID_SVM_4K_CPU_COPY_KB: Data (KiB) copied to CPU for 4K pages.
* @XE_GT_STATS_ID_SVM_64K_CPU_COPY_KB: Data (KiB) copied to CPU for 64K pages.
* @XE_GT_STATS_ID_SVM_2M_CPU_COPY_KB: Data (KiB) copied to CPU for 2M pages.
*
* @XE_GT_STATS_ID_SVM_4K_GET_PAGES_US: Cumulative time (µs) getting CPU
* memory pages for GPU access at 4K page size.
* @XE_GT_STATS_ID_SVM_64K_GET_PAGES_US: Cumulative time (µs) getting CPU
* memory pages for GPU access at 64K page size.
* @XE_GT_STATS_ID_SVM_2M_GET_PAGES_US: Cumulative time (µs) getting CPU
* memory pages for GPU access at 2M page size.
* @XE_GT_STATS_ID_SVM_4K_BIND_US: Cumulative time (µs) binding 4K pages
* into the GPU page table.
* @XE_GT_STATS_ID_SVM_64K_BIND_US: Cumulative time (µs) binding 64K pages
* into the GPU page table.
* @XE_GT_STATS_ID_SVM_2M_BIND_US: Cumulative time (µs) binding 2M pages
* into the GPU page table.
*
* @XE_GT_STATS_ID_HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_COUNT: Times the
* scheduler preempted a long-running (LR) GPU exec queue.
* @XE_GT_STATS_ID_HW_ENGINE_GROUP_SKIP_LR_QUEUE_COUNT: Times the scheduler
* skipped suspend because the system was idle.
* @XE_GT_STATS_ID_HW_ENGINE_GROUP_WAIT_DMA_QUEUE_COUNT: Times the driver
* stalled waiting for prior GPU work to complete before scheduling more.
* @XE_GT_STATS_ID_HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_US: Cumulative time
* (µs) spent preempting long-running (LR) GPU exec queues.
* @XE_GT_STATS_ID_HW_ENGINE_GROUP_WAIT_DMA_QUEUE_US: Cumulative time (µs)
* stalled waiting for prior GPU work to complete.
*
* @XE_GT_STATS_ID_PRL_4K_ENTRY_COUNT: 4K-page entries from the page reclaim
* list that were processed.
* @XE_GT_STATS_ID_PRL_64K_ENTRY_COUNT: 64K-page entries from the page reclaim
* list that were processed.
* @XE_GT_STATS_ID_PRL_2M_ENTRY_COUNT: 2M-page entries from the page reclaim
* list that were processed.
* @XE_GT_STATS_ID_PRL_ISSUED_COUNT: Times a page reclamation was issued.
* @XE_GT_STATS_ID_PRL_ABORTED_COUNT: Times the page reclaim process was
* aborted.
*
* @__XE_GT_STATS_NUM_IDS: Number of valid IDs; not a real counter.
*
* See Documentation/gpu/xe/xe_gt_stats.rst.
*/
enum xe_gt_stats_id {
XE_GT_STATS_ID_SVM_PAGEFAULT_COUNT,
XE_GT_STATS_ID_TLB_INVAL,

View File

@ -136,7 +136,7 @@ struct xe_gt {
/** @info.gmdid: raw GMD_ID value from hardware */
u32 gmdid;
/**
* @multi_queue_engine_class_mask: Bitmask of engine classes with
* @info.multi_queue_engine_class_mask: Bitmask of engine classes with
* multi queue support enabled.
*/
u16 multi_queue_engine_class_mask;
@ -355,7 +355,7 @@ struct xe_gt {
/** @user_engines: engines present in GT and available to userspace */
struct {
/**
* @user_engines.mask: like @info->engine_mask, but take in
* @user_engines.mask: like @info.engine_mask, but take in
* consideration only engines available to userspace
*/
u64 mask;

View File

@ -780,6 +780,14 @@ int xe_guc_init(struct xe_guc *guc)
if (GUC_SUBMIT_VER(guc) < MAKE_GUC_VER(1, 14, 0))
xe->info.has_page_reclaim_hw_assist = false;
/* Disable indirect_ring_state if missing GuC 70.53+ WA 14025515070. */
if (gt->info.has_indirect_ring_state &&
XE_GT_WA(gt, 14025515070) &&
GUC_SUBMIT_VER(guc) < MAKE_GUC_VER(1, 26, 0)) {
gt->info.has_indirect_ring_state = 0;
xe_gt_notice(gt, "indirect ring state requires WA in GuC submit ver 1.26+\n");
}
if (IS_SRIOV_VF(xe)) {
ret = devm_add_action_or_reset(xe->drm.dev, vf_guc_fini_hw, guc);
if (ret)
@ -1693,13 +1701,8 @@ void xe_guc_reset_wait(struct xe_guc *guc)
void xe_guc_stop_prepare(struct xe_guc *guc)
{
if (!IS_SRIOV_VF(guc_to_xe(guc))) {
int err;
err = xe_guc_pc_stop(&guc->pc);
xe_gt_WARN(guc_to_gt(guc), err, "Failed to stop GuC PC: %pe\n",
ERR_PTR(err));
}
if (!IS_SRIOV_VF(guc_to_xe(guc)))
xe_guc_pc_stop(&guc->pc);
}
void xe_guc_stop(struct xe_guc *guc)

View File

@ -360,6 +360,9 @@ static void guc_waklv_init(struct xe_guc_ads *ads)
if (XE_GT_WA(gt, 14020001231))
guc_waklv_enable(ads, NULL, 0, &offset, &remain,
GUC_WORKAROUND_KLV_DISABLE_PSMI_INTERRUPTS_AT_C6_ENTRY_RESTORE_AT_EXIT);
if (XE_GT_WA(gt, 14025515070) && GUC_FIRMWARE_VER_AT_LEAST(&gt->uc.guc, 70, 53))
guc_waklv_enable(ads, NULL, 0, &offset, &remain,
GUC_WA_KLV_CLR_CS_INDIRECT_RING_STATE_IF_IDLE_AT_CTX_REG);
size = guc_ads_waklv_size(ads) - remain;
if (!size)
@ -742,10 +745,8 @@ static unsigned int guc_mmio_regset_write(struct xe_guc_ads *ads,
struct xe_reg reg;
bool skip;
} *e, extra_regs[] = {
{ .reg = RING_MODE(hwe->mmio_base), },
{ .reg = RING_HWS_PGA(hwe->mmio_base), },
{ .reg = RING_IMR(hwe->mmio_base), },
{ .reg = RCU_MODE, .skip = hwe != hwe_rcs_reset_domain },
{ .reg = CCS_MODE,
.skip = hwe != hwe_rcs_reset_domain || !xe_gt_ccs_mode_enabled(hwe->gt) },
};

View File

@ -111,7 +111,7 @@ struct __guc_capture_parsed_output {
{ RING_TAIL(0), REG_32BIT, 0, 0, 0, "RING_TAIL"}, \
{ RING_CTL(0), REG_32BIT, 0, 0, 0, "RING_CTL"}, \
{ RING_MI_MODE(0), REG_32BIT, 0, 0, 0, "RING_MI_MODE"}, \
{ RING_MODE(0), REG_32BIT, 0, 0, 0, "RING_MODE"}, \
{ GFX_MODE(0), REG_32BIT, 0, 0, 0, "GFX_MODE"}, \
{ RING_ESR(0), REG_32BIT, 0, 0, 0, "RING_ESR"}, \
{ RING_EMR(0), REG_32BIT, 0, 0, 0, "RING_EMR"}, \
{ RING_EIR(0), REG_32BIT, 0, 0, 0, "RING_EIR"}, \

View File

@ -3,8 +3,8 @@
* Copyright © 2021-2024 Intel Corporation
*/
#ifndef _XE_GUC_CAPTURE_H
#define _XE_GUC_CAPTURE_H
#ifndef _XE_GUC_CAPTURE_H_
#define _XE_GUC_CAPTURE_H_
#include <linux/types.h>
#include "abi/guc_capture_abi.h"

View File

@ -3,8 +3,8 @@
* Copyright © 2021-2024 Intel Corporation
*/
#ifndef _XE_GUC_CAPTURE_TYPES_H
#define _XE_GUC_CAPTURE_TYPES_H
#ifndef _XE_GUC_CAPTURE_TYPES_H_
#define _XE_GUC_CAPTURE_TYPES_H_
#include <linux/types.h>
#include "regs/xe_reg_defs.h"
@ -32,7 +32,7 @@ struct __guc_mmio_reg_descr {
/**
* @data_type: data type of the register
* Could be 32 bit, low or hi dword of a 64 bit, see enum
* register_data_type
* capture_register_data_type
*/
enum capture_register_data_type data_type;
/** @flags: Flags for the register */

View File

@ -186,13 +186,16 @@ static void fast_req_track(struct xe_guc_ct *ct, u16 fence, u16 action) { }
struct g2h_fence {
u32 *response_buffer;
u32 seqno;
/* fields below this point are setup based on the response */
u32 response_data;
u16 response_len;
u16 error;
u16 hint;
u16 reason;
u32 counter;
bool cancel;
bool retry;
bool wait;
bool fail;
bool done;
};
@ -204,6 +207,11 @@ static void g2h_fence_init(struct g2h_fence *g2h_fence, u32 *response_buffer)
g2h_fence->seqno = ~0x0;
}
static void g2h_fence_reinit(struct g2h_fence *g2h_fence)
{
memset_after(g2h_fence, 0, seqno);
}
static void g2h_fence_cancel(struct g2h_fence *g2h_fence)
{
g2h_fence->cancel = true;
@ -1331,6 +1339,7 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
/* READ_ONCEs pairs with WRITE_ONCEs in parse_g2h_response
* and g2h_fence_cancel.
*/
wait_again:
ret = wait_event_timeout(ct->g2h_fence_wq, READ_ONCE(g2h_fence.done), HZ);
if (!ret) {
LNL_FLUSH_WORK(&ct->g2h_worker);
@ -1356,6 +1365,14 @@ static int guc_ct_send_recv(struct xe_guc_ct *ct, const u32 *action, u32 len,
return -ETIME;
}
if (g2h_fence.wait) {
xe_gt_dbg(gt, "H2G action %#x busy: counter %u\n",
action[0], g2h_fence.counter);
/* we can't leave any response data if we want to wait again */
g2h_fence_reinit(&g2h_fence);
mutex_unlock(&ct->lock);
goto wait_again;
}
if (g2h_fence.retry) {
xe_gt_dbg(gt, "H2G action %#x retrying: reason %#x\n",
action[0], g2h_fence.reason);
@ -1508,7 +1525,12 @@ static int parse_g2h_response(struct xe_guc_ct *ct, u32 *msg, u32 len)
return -EPROTO;
}
g2h_fence = xa_erase(&ct->fence_lookup, fence);
/* don't erase as we still expect a final response with the same fence */
if (type == GUC_HXG_TYPE_NO_RESPONSE_BUSY)
g2h_fence = xa_load(&ct->fence_lookup, fence);
else
g2h_fence = xa_erase(&ct->fence_lookup, fence);
if (unlikely(!g2h_fence)) {
/* Don't tear down channel, as send could've timed out */
/* CT_DEAD(ct, NULL, PARSE_G2H_UNKNOWN); */
@ -1519,6 +1541,12 @@ static int parse_g2h_response(struct xe_guc_ct *ct, u32 *msg, u32 len)
xe_gt_assert(gt, fence == g2h_fence->seqno);
/*
* reinit as we might have already process this g2h_fence before
* if we received a NO_RESPONSE_BUSY reply
*/
g2h_fence_reinit(g2h_fence);
if (type == GUC_HXG_TYPE_RESPONSE_FAILURE) {
g2h_fence->fail = true;
g2h_fence->error = FIELD_GET(GUC_HXG_FAILURE_MSG_0_ERROR, hxg[0]);
@ -1526,6 +1554,9 @@ static int parse_g2h_response(struct xe_guc_ct *ct, u32 *msg, u32 len)
} else if (type == GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
g2h_fence->retry = true;
g2h_fence->reason = FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, hxg[0]);
} else if (type == GUC_HXG_TYPE_NO_RESPONSE_BUSY) {
g2h_fence->wait = true;
g2h_fence->counter = FIELD_GET(GUC_HXG_BUSY_MSG_0_COUNTER, hxg[0]);
} else if (g2h_fence->response_buffer) {
g2h_fence->response_len = hxg_len;
memcpy(g2h_fence->response_buffer, hxg, hxg_len * sizeof(u32));
@ -1533,7 +1564,9 @@ static int parse_g2h_response(struct xe_guc_ct *ct, u32 *msg, u32 len)
g2h_fence->response_data = FIELD_GET(GUC_HXG_RESPONSE_MSG_0_DATA0, hxg[0]);
}
g2h_release_space(ct, GUC_CTB_HXG_MSG_MAX_LEN);
/* don't release any space if it was an intermediate message */
if (!g2h_fence->wait)
g2h_release_space(ct, GUC_CTB_HXG_MSG_MAX_LEN);
/* WRITE_ONCE pairs with READ_ONCEs in guc_ct_send_recv. */
WRITE_ONCE(g2h_fence->done, true);
@ -1570,6 +1603,7 @@ static int parse_g2h_msg(struct xe_guc_ct *ct, u32 *msg, u32 len)
case GUC_HXG_TYPE_RESPONSE_SUCCESS:
case GUC_HXG_TYPE_RESPONSE_FAILURE:
case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
case GUC_HXG_TYPE_NO_RESPONSE_BUSY:
ret = parse_g2h_response(ct, msg, len);
break;
default:

View File

@ -102,9 +102,9 @@ struct xe_dead_ct {
bool reported;
/** @worker: worker thread to get out of interrupt context before dumping */
struct work_struct worker;
/** snapshot_ct: copy of CT state and CTB content at point of error */
/** @snapshot_ct: copy of CT state and CTB content at point of error */
struct xe_guc_ct_snapshot *snapshot_ct;
/** snapshot_log: copy of GuC log at point of error */
/** @snapshot_log: copy of GuC log at point of error */
struct xe_guc_log_snapshot *snapshot_log;
};
@ -134,9 +134,9 @@ struct xe_guc_ct {
spinlock_t fast_lock;
/** @ctbs: buffers for sending and receiving commands */
struct {
/** @ctbs.send: Host to GuC (H2G, send) channel */
/** @ctbs.h2g: Host to GuC (H2G, send) channel */
struct guc_ctb h2g;
/** @ctbs.recv: GuC to Host (G2H, receive) channel */
/** @ctbs.g2h: GuC to Host (G2H, receive) channel */
struct guc_ctb g2h;
} ctbs;
/** @g2h_outstanding: number of outstanding G2H */

View File

@ -3,8 +3,8 @@
* Copyright © 2022 Intel Corporation
*/
#ifndef _XE_GUC_FWIF_H
#define _XE_GUC_FWIF_H
#ifndef _XE_GUC_FWIF_H_
#define _XE_GUC_FWIF_H_
#include <linux/bits.h>

View File

@ -890,9 +890,26 @@ void xe_guc_pc_init_early(struct xe_guc_pc *pc)
pc_init_fused_rp_values(pc);
}
static bool pc_needs_min_freq_change(struct xe_guc_pc *pc)
{
struct xe_device *xe = pc_to_xe(pc);
struct xe_gt *gt = pc_to_gt(pc);
if (XE_DEVICE_WA(xe, 14022085890))
return true;
if (xe_gt_is_media_type(gt))
return false;
if (xe->info.platform == XE_BATTLEMAGE ||
xe->info.platform == XE_CRESCENTISLAND)
return true;
return false;
}
static int pc_adjust_freq_bounds(struct xe_guc_pc *pc)
{
struct xe_tile *tile = gt_to_tile(pc_to_gt(pc));
int ret;
lockdep_assert_held(&pc->freq_lock);
@ -919,7 +936,18 @@ static int pc_adjust_freq_bounds(struct xe_guc_pc *pc)
if (pc_get_min_freq(pc) > pc->rp0_freq)
ret = pc_set_min_freq(pc, pc->rp0_freq);
if (XE_DEVICE_WA(tile_to_xe(tile), 14022085890))
/*
* Setting GT RP min frequency to 1.2GHz by default for
* GT0(Graphics) Tile of BMG and CRI.
*
* While BMG G21 WA will apply min frequency for
* both GT0(Graphics) and GT1(Media) Tile.
*
* This is an active frequency, so if the device is idle
* we aren't expecting high power output across board
*
*/
if (pc_needs_min_freq_change(pc))
ret = pc_set_min_freq(pc, max(BMG_MIN_FREQ, pc_get_min_freq(pc)));
out:
@ -1288,18 +1316,16 @@ int xe_guc_pc_start(struct xe_guc_pc *pc)
* xe_guc_pc_stop - Stop GuC's Power Conservation component
* @pc: Xe_GuC_PC instance
*/
int xe_guc_pc_stop(struct xe_guc_pc *pc)
void xe_guc_pc_stop(struct xe_guc_pc *pc)
{
struct xe_device *xe = pc_to_xe(pc);
if (xe->info.skip_guc_pc)
return 0;
return;
mutex_lock(&pc->freq_lock);
pc->freq_ready = false;
mutex_unlock(&pc->freq_lock);
return 0;
}
/**
@ -1314,10 +1340,10 @@ static void xe_guc_pc_fini_hw(void *arg)
if (xe_device_wedged(xe))
return;
CLASS(xe_force_wake, fw_ref)(gt_to_fw(pc_to_gt(pc)), XE_FW_GT);
XE_WARN_ON(xe_guc_pc_stop(pc));
xe_guc_pc_stop(pc);
/* Bind requested freq to mert_freq_cap before unload */
CLASS(xe_force_wake, fw_ref)(gt_to_fw(pc_to_gt(pc)), XE_FW_GT);
pc_set_cur_freq(pc, min(pc_max_freq_cap(pc), xe_guc_pc_get_rpe_freq(pc)));
}

View File

@ -13,7 +13,7 @@ struct drm_printer;
int xe_guc_pc_init(struct xe_guc_pc *pc);
int xe_guc_pc_start(struct xe_guc_pc *pc);
int xe_guc_pc_stop(struct xe_guc_pc *pc);
void xe_guc_pc_stop(struct xe_guc_pc *pc);
void xe_guc_pc_print(struct xe_guc_pc *pc, struct drm_printer *p);
int xe_guc_pc_action_set_param(struct xe_guc_pc *pc, u8 id, u32 value);
int xe_guc_pc_action_unset_param(struct xe_guc_pc *pc, u8 id);

View File

@ -15,7 +15,7 @@
* struct xe_guc_relay - Data used by the VF-PF Relay Communication over GuC.
*/
struct xe_guc_relay {
/**@lock: protects all internal data. */
/** @lock: protects all internal data. */
spinlock_t lock;
/** @worker: dispatches incoming action messages. */

View File

@ -2968,9 +2968,10 @@ int xe_guc_exec_queue_reset_handler(struct xe_guc *guc, u32 *msg, u32 len)
if (unlikely(!q))
return -EPROTO;
xe_gt_info(gt, "Engine reset: engine_class=%s, logical_mask: 0x%x, guc_id=%d, state=0x%0x",
xe_hw_engine_class_to_str(q->class), q->logical_mask, guc_id,
atomic_read(&q->guc->state));
if (!exec_queue_killed(q))
xe_gt_info(gt, "Engine reset: engine_class=%s, logical_mask: 0x%x, guc_id=%d, state=0x%0x",
xe_hw_engine_class_to_str(q->class), q->logical_mask, guc_id,
atomic_read(&q->guc->state));
trace_xe_exec_queue_reset(q);

View File

@ -138,7 +138,7 @@ struct xe_guc_submit_exec_queue_snapshot {
u32 primary;
/** @multi_queue.pos: Position of the exec queue within the multi queue group */
u8 pos;
/** @valid: The exec queue is part of a multi queue group */
/** @multi_queue.valid: The exec queue is part of a multi queue group */
bool valid;
} multi_queue;
};

View File

@ -67,7 +67,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 0,
.irq_offset = ilog2(INTR_BCS(0)),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = BLT_RING_BASE,
},
[XE_HW_ENGINE_BCS1] = {
@ -75,7 +75,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 1,
.irq_offset = ilog2(INTR_BCS(1)),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS1_RING_BASE,
},
[XE_HW_ENGINE_BCS2] = {
@ -83,7 +83,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 2,
.irq_offset = ilog2(INTR_BCS(2)),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS2_RING_BASE,
},
[XE_HW_ENGINE_BCS3] = {
@ -91,7 +91,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 3,
.irq_offset = ilog2(INTR_BCS(3)),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS3_RING_BASE,
},
[XE_HW_ENGINE_BCS4] = {
@ -99,7 +99,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 4,
.irq_offset = ilog2(INTR_BCS(4)),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS4_RING_BASE,
},
[XE_HW_ENGINE_BCS5] = {
@ -107,7 +107,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 5,
.irq_offset = ilog2(INTR_BCS(5)),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS5_RING_BASE,
},
[XE_HW_ENGINE_BCS6] = {
@ -115,7 +115,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 6,
.irq_offset = ilog2(INTR_BCS(6)),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS6_RING_BASE,
},
[XE_HW_ENGINE_BCS7] = {
@ -123,7 +123,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.irq_offset = ilog2(INTR_BCS(7)),
.instance = 7,
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS7_RING_BASE,
},
[XE_HW_ENGINE_BCS8] = {
@ -131,7 +131,7 @@ static const struct engine_info engine_infos[] = {
.class = XE_ENGINE_CLASS_COPY,
.instance = 8,
.irq_offset = ilog2(INTR_BCS8),
.domain = XE_FW_RENDER,
.domain = XE_FW_GT,
.mmio_base = XEHPC_BCS8_RING_BASE,
},
@ -282,27 +282,6 @@ static void hw_engine_fini(void *arg)
hwe->gt = NULL;
}
/**
* xe_hw_engine_mmio_write32() - Write engine register
* @hwe: engine
* @reg: register to write into
* @val: desired 32-bit value to write
*
* This function will write val into an engine specific register.
* Forcewake must be held by the caller.
*
*/
void xe_hw_engine_mmio_write32(struct xe_hw_engine *hwe,
struct xe_reg reg, u32 val)
{
xe_gt_assert(hwe->gt, !(reg.addr & hwe->mmio_base));
xe_force_wake_assert_held(gt_to_fw(hwe->gt), hwe->domain);
reg.addr += hwe->mmio_base;
xe_mmio_write32(&hwe->gt->mmio, reg, val);
}
/**
* xe_hw_engine_mmio_read32() - Read engine register
* @hwe: engine
@ -325,24 +304,8 @@ u32 xe_hw_engine_mmio_read32(struct xe_hw_engine *hwe, struct xe_reg reg)
void xe_hw_engine_enable_ring(struct xe_hw_engine *hwe)
{
u32 ccs_mask =
xe_hw_engine_mask_per_class(hwe->gt, XE_ENGINE_CLASS_COMPUTE);
u32 ring_mode = REG_MASKED_FIELD_ENABLE(GFX_DISABLE_LEGACY_MODE);
if (hwe->class == XE_ENGINE_CLASS_COMPUTE && ccs_mask)
xe_mmio_write32(&hwe->gt->mmio, RCU_MODE,
REG_MASKED_FIELD_ENABLE(RCU_MODE_CCS_ENABLE));
xe_hw_engine_mmio_write32(hwe, RING_HWSTAM(0), ~0x0);
xe_hw_engine_mmio_write32(hwe, RING_HWS_PGA(0),
xe_bo_ggtt_addr(hwe->hwsp));
if (xe_device_has_msix(gt_to_xe(hwe->gt)))
ring_mode |= REG_MASKED_FIELD_ENABLE(GFX_MSIX_INTERRUPT_ENABLE);
xe_hw_engine_mmio_write32(hwe, RING_MODE(0), ring_mode);
xe_hw_engine_mmio_write32(hwe, RING_MI_MODE(0),
REG_MASKED_FIELD_DISABLE(STOP_RING));
xe_hw_engine_mmio_read32(hwe, RING_MI_MODE(0));
xe_mmio_write32(&hwe->gt->mmio, RING_HWS_PGA(hwe->mmio_base),
xe_bo_ggtt_addr(hwe->hwsp));
}
static bool xe_hw_engine_match_fixed_cslice_mode(const struct xe_device *xe,
@ -390,7 +353,7 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe)
* BLIT_CCTL registers are needed to be programmed to un-cached.
*/
{ XE_RTP_NAME("BLIT_CCTL_default_MOCS"),
XE_RTP_RULES(GRAPHICS_VERSION_RANGE(1200, XE_RTP_END_VERSION_UNDEFINED),
XE_RTP_RULES(GRAPHICS_VERSION_RANGE(1200, 1274),
ENGINE_CLASS(COPY)),
XE_RTP_ACTIONS(FIELD_SET(BLIT_CCTL(0),
BLIT_CCTL_DST_MOCS_MASK |
@ -436,13 +399,23 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
const struct xe_rtp_entry_sr engine_entries[] = {
{ XE_RTP_NAME("RING_CMD_CCTL_default_MOCS"),
XE_RTP_RULES(GRAPHICS_VERSION_RANGE(1200, XE_RTP_END_VERSION_UNDEFINED)),
XE_RTP_RULES(FUNC(xe_rtp_match_always)),
XE_RTP_ACTIONS(FIELD_SET(RING_CMD_CCTL(0),
CMD_CCTL_WRITE_OVERRIDE_MASK |
CMD_CCTL_READ_OVERRIDE_MASK,
ring_cmd_cctl_val,
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
},
{ XE_RTP_NAME("Disable HW status page updates for interrupts"),
XE_RTP_RULES(FUNC(xe_rtp_match_always)),
XE_RTP_ACTIONS(SET(RING_HWSTAM(0), ~0x0,
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
},
{ XE_RTP_NAME("Disable engine 'legacy' mode"),
XE_RTP_RULES(FUNC(xe_rtp_match_always)),
XE_RTP_ACTIONS(SET(GFX_MODE(0), GFX_DISABLE_LEGACY_MODE,
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
},
/*
* To allow the GSC engine to go idle on MTL we need to enable
* idle messaging and set the hysteresis value (we use 0xA=5us
@ -465,12 +438,22 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), CS_PRIORITY_MEM_READ,
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
},
{ XE_RTP_NAME("Enable CCS Engine(s)"),
XE_RTP_RULES(GRAPHICS_VERSION_RANGE(1255, XE_RTP_END_VERSION_UNDEFINED),
FUNC(xe_rtp_match_first_render_or_compute)),
XE_RTP_ACTIONS(SET(RCU_MODE, RCU_MODE_CCS_ENABLE))
},
/* Use Fixed slice CCS mode */
{ XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"),
XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)),
XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE,
RCU_MODE_FIXED_SLICE_CCS_MODE))
},
{ XE_RTP_NAME("Enable MSI-X interrupt support"),
XE_RTP_RULES(FUNC(xe_rtp_match_has_msix)),
XE_RTP_ACTIONS(SET(GFX_MODE(0), GFX_MSIX_INTERRUPT_ENABLE,
XE_RTP_ACTION_FLAG(ENGINE_BASE)))
},
};
xe_rtp_process_to_sr(&ctx, engine_entries, ARRAY_SIZE(engine_entries),
@ -1026,6 +1009,9 @@ bool xe_hw_engine_is_reserved(struct xe_hw_engine *hwe)
struct xe_gt *gt = hwe->gt;
struct xe_device *xe = gt_to_xe(gt);
if (xe_device_is_admin_only(xe))
return true;
if (hwe->class == XE_ENGINE_CLASS_OTHER)
return true;

View File

@ -76,7 +76,6 @@ const char *xe_hw_engine_class_to_str(enum xe_engine_class class);
u64 xe_hw_engine_read_timestamp(struct xe_hw_engine *hwe);
enum xe_force_wake_domains xe_hw_engine_to_fw_domain(struct xe_hw_engine *hwe);
void xe_hw_engine_mmio_write32(struct xe_hw_engine *hwe, struct xe_reg reg, u32 val);
u32 xe_hw_engine_mmio_read32(struct xe_hw_engine *hwe, struct xe_reg reg);
#endif

View File

@ -79,7 +79,7 @@ struct xe_hw_engine_class_intf {
* @defaults: default scheduling properties
*/
struct {
/** @sched_props.set_job_timeout: Set job timeout in ms for engine */
/** @sched_props.job_timeout_ms: Set job timeout in ms for engine */
u32 job_timeout_ms;
/** @sched_props.job_timeout_min: Min job timeout in ms for engine */
u32 job_timeout_min;

View File

@ -2,8 +2,8 @@
/*
* Copyright © 2025 Intel Corporation
*/
#ifndef XE_HW_ERROR_H_
#define XE_HW_ERROR_H_
#ifndef _XE_HW_ERROR_H_
#define _XE_HW_ERROR_H_
#include <linux/types.h>

View File

@ -180,6 +180,18 @@ struct xe_hwmon {
struct xe_hwmon_thermal_info temp;
};
static inline int prepare_power_limit_param2(const struct xe_hwmon *hwmon)
{
if (hwmon->boot_power_limit_read) {
if (hwmon->xe->info.platform >= XE_CRESCENTISLAND)
return READ_PL_ACCEPTED;
else
return READ_PL_FROM_PCODE;
} else {
return READ_PL_FROM_FW;
}
}
static int xe_hwmon_pcode_read_power_limit(const struct xe_hwmon *hwmon, u32 attr, int channel,
u32 *uval)
{
@ -191,9 +203,7 @@ static int xe_hwmon_pcode_read_power_limit(const struct xe_hwmon *hwmon, u32 att
(channel == CHANNEL_CARD) ?
READ_PSYSGPU_POWER_LIMIT :
READ_PACKAGE_POWER_LIMIT,
hwmon->boot_power_limit_read ?
READ_PL_FROM_PCODE : READ_PL_FROM_FW),
&val0, &val1);
prepare_power_limit_param2(hwmon)), &val0, &val1);
if (ret) {
drm_dbg(&hwmon->xe->drm, "read failed ch %d val0 0x%08x, val1 0x%08x, ret %d\n",
@ -226,10 +236,7 @@ static int xe_hwmon_pcode_rmw_power_limit(const struct xe_hwmon *hwmon, u32 attr
(channel == CHANNEL_CARD) ?
READ_PSYSGPU_POWER_LIMIT :
READ_PACKAGE_POWER_LIMIT,
hwmon->boot_power_limit_read ?
READ_PL_FROM_PCODE : READ_PL_FROM_FW),
&val0, &val1);
prepare_power_limit_param2(hwmon)), &val0, &val1);
if (ret)
drm_dbg(&hwmon->xe->drm, "read failed ch %d val0 0x%08x, val1 0x%08x, ret %d\n",
channel, val0, val1, ret);
@ -296,7 +303,12 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg
return GT_PERF_STATUS;
break;
case REG_PKG_ENERGY_STATUS:
if (xe->info.platform == XE_PVC && channel == CHANNEL_PKG) {
if (xe->info.platform == XE_CRESCENTISLAND) {
if (channel == CHANNEL_CARD)
return CRI_PLATFORM_ENERGY_STATUS;
else if (channel == CHANNEL_PKG)
return CRI_PACKAGE_ENERGY_STATUS;
} else if (xe->info.platform == XE_PVC && channel == CHANNEL_PKG) {
return PVC_GT0_PLATFORM_ENERGY_STATUS;
} else if ((xe->info.platform == XE_DG2) && (channel == CHANNEL_PKG)) {
return PCU_CR_PACKAGE_ENERGY_STATUS;

View File

@ -24,6 +24,7 @@
#include "xe_mmio.h"
#include "xe_pxp.h"
#include "xe_sriov.h"
#include "xe_sysctrl.h"
#include "xe_tile.h"
/*
@ -525,6 +526,7 @@ static irqreturn_t dg1_irq_handler(int irq, void *arg)
xe_heci_csc_irq_handler(xe, master_ctl);
xe_display_irq_handler(xe, master_ctl);
xe_i2c_irq_handler(xe, master_ctl);
xe_sysctrl_irq_handler(xe, master_ctl);
xe_mert_irq_handler(xe, master_ctl);
gu_misc_iir = gu_misc_irq_ack(xe, master_ctl);
}

View File

@ -682,25 +682,6 @@ static void set_memory_based_intr(u32 *regs, struct xe_hw_engine *hwe)
}
}
static int lrc_ring_mi_mode(struct xe_hw_engine *hwe)
{
struct xe_device *xe = gt_to_xe(hwe->gt);
if (GRAPHICS_VERx100(xe) >= 1250)
return 0x70;
else
return 0x60;
}
static void reset_stop_ring(u32 *regs, struct xe_hw_engine *hwe)
{
int x;
x = lrc_ring_mi_mode(hwe);
regs[x + 1] &= ~STOP_RING;
regs[x + 1] |= STOP_RING << 16;
}
static inline bool xe_lrc_has_indirect_ring_state(struct xe_lrc *lrc)
{
return lrc->flags & XE_LRC_FLAG_INDIRECT_RING_STATE;
@ -980,7 +961,6 @@ static void *empty_lrc_data(struct xe_hw_engine *hwe)
set_offsets(regs, reg_offsets(gt_to_xe(gt), hwe->class), hwe);
set_context_control(regs, hwe);
set_memory_based_intr(regs, hwe);
reset_stop_ring(regs, hwe);
if (xe_gt_has_indirect_ring_state(gt)) {
regs = data + xe_gt_lrc_size(gt, hwe->class) -
LRC_INDIRECT_RING_STATE_SIZE;

View File

@ -31,6 +31,7 @@
#include "xe_map.h"
#include "xe_mem_pool.h"
#include "xe_mocs.h"
#include "xe_pat.h"
#include "xe_printk.h"
#include "xe_pt.h"
#include "xe_res_cursor.h"
@ -217,7 +218,7 @@ static void xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
struct xe_vm *vm, u32 *ofs)
{
struct xe_device *xe = tile_to_xe(tile);
u16 pat_index = xe->pat.idx[XE_CACHE_WB];
u16 pat_index = xe_cache_pat_idx(xe, XE_CACHE_WB);
u8 id = tile->id;
u32 num_entries = NUM_PT_SLOTS, num_level = vm->pt_root[id]->level;
#define VRAM_IDENTITY_MAP_COUNT 2
@ -337,7 +338,7 @@ static void xe_migrate_prepare_vm(struct xe_tile *tile, struct xe_migrate *m,
* if flat ccs is enabled.
*/
if (GRAPHICS_VER(xe) >= 20 && xe_device_has_flat_ccs(xe)) {
u16 comp_pat_index = xe->pat.idx[XE_CACHE_NONE_COMPRESSION];
u16 comp_pat_index = xe_cache_pat_idx(xe, XE_CACHE_NONE_COMPRESSION);
u64 vram_offset = IDENTITY_OFFSET +
DIV_ROUND_UP_ULL(actual_phy_size, SZ_1G);
u64 pt31_ofs = xe_bo_size(bo) - XE_PAGE_SIZE;
@ -637,10 +638,10 @@ static void emit_pte(struct xe_migrate *m,
/* Indirect access needs compression enabled uncached PAT index */
if (GRAPHICS_VERx100(xe) >= 2000)
pat_index = is_comp_pte ? xe->pat.idx[XE_CACHE_NONE_COMPRESSION] :
xe->pat.idx[XE_CACHE_WB];
pat_index = is_comp_pte ? xe_cache_pat_idx(xe, XE_CACHE_NONE_COMPRESSION) :
xe_cache_pat_idx(xe, XE_CACHE_WB);
else
pat_index = xe->pat.idx[XE_CACHE_WB];
pat_index = xe_cache_pat_idx(xe, XE_CACHE_WB);
ptes = DIV_ROUND_UP(size, XE_PAGE_SIZE);
@ -1876,7 +1877,7 @@ __xe_migrate_update_pgtables(struct xe_migrate *m,
/* For sysmem PTE's, need to map them in our hole.. */
if (!IS_DGFX(xe)) {
u16 pat_index = xe->pat.idx[XE_CACHE_WB];
u16 pat_index = xe_cache_pat_idx(xe, XE_CACHE_WB);
u32 ptes, ofs;
ppgtt_ofs = NUM_KERNEL_PDE - 1;
@ -2098,7 +2099,7 @@ static void build_pt_update_batch_sram(struct xe_migrate *m,
struct drm_pagemap_addr *sram_addr,
u32 size, int level)
{
u16 pat_index = tile_to_xe(m->tile)->pat.idx[XE_CACHE_WB];
u16 pat_index = xe_cache_pat_idx(tile_to_xe(m->tile), XE_CACHE_WB);
u64 gpu_page_size = 0x1ull << xe_pt_shift(level);
u32 ptes;
int i = 0;

View File

@ -3,8 +3,8 @@
* Copyright © 2020 Intel Corporation
*/
#ifndef _XE_MIGRATE_
#define _XE_MIGRATE_
#ifndef _XE_MIGRATE_H_
#define _XE_MIGRATE_H_
#include <linux/types.h>

View File

@ -3,8 +3,8 @@
* Copyright(c) 2019-2025 Intel Corporation. All rights reserved.
*/
#ifndef __XE_NVM_H__
#define __XE_NVM_H__
#ifndef _XE_NVM_H_
#define _XE_NVM_H_
struct xe_device;

View File

@ -9,11 +9,13 @@
#include <linux/poll.h>
#include <drm/drm_drv.h>
#include <drm/drm_gem.h>
#include <drm/drm_managed.h>
#include <drm/drm_syncobj.h>
#include <uapi/drm/xe_drm.h>
#include <generated/xe_wa_oob.h>
#include <generated/xe_device_wa_oob.h>
#include "abi/guc_actions_slpc_abi.h"
#include "instructions/xe_mi_commands.h"
@ -213,32 +215,45 @@ static u32 xe_oa_hw_tail_read(struct xe_oa_stream *stream)
#define oa_report_header_64bit(__s) \
((__s)->oa_buffer.format->header == HDR_64_BIT)
static u64 oa_report_id(struct xe_oa_stream *stream, void *report)
static u64 oa_report_id(struct xe_oa_stream *stream, u32 report_offset)
{
return oa_report_header_64bit(stream) ? *(u64 *)report : *(u32 *)report;
}
struct iosys_map *map = &stream->oa_buffer.bo->vmap;
static void oa_report_id_clear(struct xe_oa_stream *stream, u32 *report)
{
if (oa_report_header_64bit(stream))
*(u64 *)report = 0;
else
*report = 0;
}
static u64 oa_timestamp(struct xe_oa_stream *stream, void *report)
{
return oa_report_header_64bit(stream) ?
*((u64 *)report + 1) :
*((u32 *)report + 1);
xe_map_rd(stream->oa->xe, map, report_offset, u64) :
xe_map_rd(stream->oa->xe, map, report_offset, u32);
}
static void oa_timestamp_clear(struct xe_oa_stream *stream, u32 *report)
static void oa_report_id_clear(struct xe_oa_stream *stream, u32 report_offset)
{
if (oa_report_header_64bit(stream))
*(u64 *)&report[2] = 0;
else
report[1] = 0;
struct iosys_map *map = &stream->oa_buffer.bo->vmap;
oa_report_header_64bit(stream) ?
xe_map_wr(stream->oa->xe, map, report_offset, u64, 0) :
xe_map_wr(stream->oa->xe, map, report_offset, u32, 0);
}
static u64 oa_timestamp(struct xe_oa_stream *stream, u32 report_offset)
{
struct iosys_map *map = &stream->oa_buffer.bo->vmap;
return oa_report_header_64bit(stream) ?
xe_map_rd(stream->oa->xe, map, report_offset + 8, u64) :
xe_map_rd(stream->oa->xe, map, report_offset + 4, u32);
}
static void oa_timestamp_clear(struct xe_oa_stream *stream, u32 report_offset)
{
struct iosys_map *map = &stream->oa_buffer.bo->vmap;
oa_report_header_64bit(stream) ?
xe_map_wr(stream->oa->xe, map, report_offset + 8, u64, 0) :
xe_map_wr(stream->oa->xe, map, report_offset + 4, u32, 0);
}
static bool mert_wa_14026633728(struct xe_oa_stream *s)
{
return s->oa_unit->type == DRM_XE_OA_UNIT_TYPE_MERT && XE_DEVICE_WA(s->oa->xe, 14026633728);
}
static bool xe_oa_buffer_check_unlocked(struct xe_oa_stream *stream)
@ -275,9 +290,7 @@ static bool xe_oa_buffer_check_unlocked(struct xe_oa_stream *stream)
* they were written. If not : (°°
*/
while (xe_oa_circ_diff(stream, tail, stream->oa_buffer.tail) >= report_size) {
void *report = stream->oa_buffer.vaddr + tail;
if (oa_report_id(stream, report) || oa_timestamp(stream, report))
if (oa_report_id(stream, tail) || oa_timestamp(stream, tail))
break;
tail = xe_oa_circ_diff(stream, tail, report_size);
@ -311,30 +324,37 @@ static enum hrtimer_restart xe_oa_poll_check_timer_cb(struct hrtimer *hrtimer)
return HRTIMER_RESTART;
}
static unsigned long
xe_oa_copy_to_user(struct xe_oa_stream *stream, void __user *dst, u32 report_offset, u32 len)
{
xe_assert(stream->oa->xe, len <= stream->oa_buffer.format->size);
xe_map_memcpy_from(stream->oa->xe, stream->oa_buffer.bounce,
&stream->oa_buffer.bo->vmap, report_offset, len);
return copy_to_user(dst, stream->oa_buffer.bounce, len);
}
static int xe_oa_append_report(struct xe_oa_stream *stream, char __user *buf,
size_t count, size_t *offset, const u8 *report)
size_t count, size_t *offset, u32 report_offset)
{
int report_size = stream->oa_buffer.format->size;
int report_size_partial;
u8 *oa_buf_end;
if ((count - *offset) < report_size)
return -ENOSPC;
buf += *offset;
oa_buf_end = stream->oa_buffer.vaddr + stream->oa_buffer.circ_size;
report_size_partial = oa_buf_end - report;
report_size_partial = stream->oa_buffer.circ_size - report_offset;
if (report_size_partial < report_size) {
if (copy_to_user(buf, report, report_size_partial))
if (xe_oa_copy_to_user(stream, buf, report_offset, report_size_partial))
return -EFAULT;
buf += report_size_partial;
if (copy_to_user(buf, stream->oa_buffer.vaddr,
report_size - report_size_partial))
if (xe_oa_copy_to_user(stream, buf, 0, report_size - report_size_partial))
return -EFAULT;
} else if (copy_to_user(buf, report, report_size)) {
} else if (xe_oa_copy_to_user(stream, buf, report_offset, report_size)) {
return -EFAULT;
}
@ -347,7 +367,6 @@ static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf,
size_t count, size_t *offset)
{
int report_size = stream->oa_buffer.format->size;
u8 *oa_buf_base = stream->oa_buffer.vaddr;
u32 gtt_offset = xe_bo_ggtt_addr(stream->oa_buffer.bo);
size_t start_offset = *offset;
unsigned long flags;
@ -364,26 +383,24 @@ static int xe_oa_append_reports(struct xe_oa_stream *stream, char __user *buf,
for (; xe_oa_circ_diff(stream, tail, head);
head = xe_oa_circ_incr(stream, head, report_size)) {
u8 *report = oa_buf_base + head;
ret = xe_oa_append_report(stream, buf, count, offset, report);
ret = xe_oa_append_report(stream, buf, count, offset, head);
if (ret)
break;
if (!(stream->oa_buffer.circ_size % report_size)) {
/* Clear out report id and timestamp to detect unlanded reports */
oa_report_id_clear(stream, (void *)report);
oa_timestamp_clear(stream, (void *)report);
oa_report_id_clear(stream, head);
oa_timestamp_clear(stream, head);
} else {
u8 *oa_buf_end = stream->oa_buffer.vaddr + stream->oa_buffer.circ_size;
u32 part = oa_buf_end - report;
struct iosys_map *map = &stream->oa_buffer.bo->vmap;
u32 part = stream->oa_buffer.circ_size - head;
/* Zero out the entire report */
if (report_size <= part) {
memset(report, 0, report_size);
xe_map_memset(stream->oa->xe, map, head, 0, report_size);
} else {
memset(report, 0, part);
memset(oa_buf_base, 0, report_size - part);
xe_map_memset(stream->oa->xe, map, head, 0, part);
xe_map_memset(stream->oa->xe, map, 0, 0, report_size - part);
}
}
}
@ -436,7 +453,8 @@ static void xe_oa_init_oa_buffer(struct xe_oa_stream *stream)
spin_unlock_irqrestore(&stream->oa_buffer.ptr_lock, flags);
/* Zero out the OA buffer since we rely on zero report id and timestamp fields */
memset(stream->oa_buffer.vaddr, 0, xe_bo_size(stream->oa_buffer.bo));
xe_map_memset(stream->oa->xe, &stream->oa_buffer.bo->vmap, 0, 0,
xe_bo_size(stream->oa_buffer.bo));
}
static u32 __format_to_oactrl(const struct xe_oa_format *format, int counter_sel_mask)
@ -699,6 +717,7 @@ static int num_lri_dwords(int num_regs)
static void xe_oa_free_oa_buffer(struct xe_oa_stream *stream)
{
xe_bo_unpin_map_no_vm(stream->oa_buffer.bo);
kfree(stream->oa_buffer.bounce);
}
static void xe_oa_free_configs(struct xe_oa_stream *stream)
@ -880,18 +899,25 @@ static void xe_oa_stream_destroy(struct xe_oa_stream *stream)
static int xe_oa_alloc_oa_buffer(struct xe_oa_stream *stream, size_t size)
{
u32 vram = mert_wa_14026633728(stream) ?
XE_BO_FLAG_VRAM_IF_DGFX(xe_device_get_root_tile(stream->oa->xe)) :
XE_BO_FLAG_SYSTEM;
struct xe_bo *bo;
bo = xe_bo_create_pin_map_novm(stream->oa->xe, stream->gt->tile,
size, ttm_bo_type_kernel,
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_GGTT, false);
vram | XE_BO_FLAG_GGTT, false);
if (IS_ERR(bo))
return PTR_ERR(bo);
stream->oa_buffer.bo = bo;
/* mmap implementation requires OA buffer to be in system memory */
xe_assert(stream->oa->xe, bo->vmap.is_iomem == 0);
stream->oa_buffer.vaddr = bo->vmap.vaddr;
stream->oa_buffer.bounce = kmalloc(stream->oa_buffer.format->size, GFP_KERNEL);
if (!stream->oa_buffer.bounce) {
xe_bo_unpin_map_no_vm(stream->oa_buffer.bo);
return -ENOMEM;
}
return 0;
}
@ -1673,8 +1699,6 @@ static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma)
{
struct xe_oa_stream *stream = file->private_data;
struct xe_bo *bo = stream->oa_buffer.bo;
unsigned long start = vma->vm_start;
int i, ret;
if (xe_observation_paranoid && !perfmon_capable()) {
drm_dbg(&stream->oa->xe->drm, "Insufficient privilege to map OA buffer\n");
@ -1682,7 +1706,7 @@ static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma)
}
/* Can mmap the entire OA buffer or nothing (no partial OA buffer mmaps) */
if (vma->vm_end - vma->vm_start != xe_bo_size(stream->oa_buffer.bo)) {
if (vma->vm_end - vma->vm_start != xe_bo_size(bo)) {
drm_dbg(&stream->oa->xe->drm, "Wrong mmap size, must be OA buffer size\n");
return -EINVAL;
}
@ -1698,17 +1722,7 @@ static int xe_oa_mmap(struct file *file, struct vm_area_struct *vma)
vm_flags_mod(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_DONTCOPY,
VM_MAYWRITE | VM_MAYEXEC);
xe_assert(stream->oa->xe, bo->ttm.ttm->num_pages == vma_pages(vma));
for (i = 0; i < bo->ttm.ttm->num_pages; i++) {
ret = remap_pfn_range(vma, start, page_to_pfn(bo->ttm.ttm->pages[i]),
PAGE_SIZE, vma->vm_page_prot);
if (ret)
break;
start += PAGE_SIZE;
}
return ret;
return drm_gem_mmap_obj(&bo->ttm.base, xe_bo_size(bo), vma);
}
static const struct file_operations xe_oa_fops = {

View File

@ -67,7 +67,7 @@ struct xe_oa_format {
u32 counter_select;
/** @size: record size as written by HW (multiple of 64 byte cachelines) */
int size;
/** @type: of enum @drm_xe_oa_format_type */
/** @type: of enum drm_xe_oa_format_type */
int type;
/** @header: 32 or 64 bit report headers */
enum xe_oa_report_header header;
@ -154,16 +154,18 @@ struct xe_oa {
u16 oa_unit_ids;
};
/** @xe_oa_buffer: State of the stream OA buffer */
/**
* struct xe_oa_buffer - State of the stream OA buffer
*/
struct xe_oa_buffer {
/** @format: data format */
const struct xe_oa_format *format;
/** @format: xe_bo backing the OA buffer */
/** @bo: xe_bo backing the OA buffer */
struct xe_bo *bo;
/** @vaddr: mapped vaddr of the OA buffer */
u8 *vaddr;
/** @bounce: bounce buffer used with xe_map layer */
void *bounce;
/** @ptr_lock: Lock protecting reads/writes to head/tail pointers */
spinlock_t ptr_lock;

View File

@ -86,7 +86,7 @@ struct xe_pagefault {
u8 engine_class;
/** @consumer.engine_instance: engine instance */
u8 engine_instance;
/** consumer.reserved: reserved bits for future expansion */
/** @consumer.reserved: reserved bits for future expansion */
u64 reserved;
} consumer;
/**
@ -112,7 +112,7 @@ struct xe_pagefault {
};
/**
* struct xe_pagefault_queue: Xe pagefault queue (consumer)
* struct xe_pagefault_queue - Xe pagefault queue (consumer)
*
* Used to capture all device page faults for deferred processing. Size this
* queue to absorb the devices worst-case number of outstanding faults.

View File

@ -531,6 +531,14 @@ static int xe2_dump(struct xe_gt *gt, struct drm_printer *p)
drm_printf(p, "Page Table Access:\n");
xe->pat.ops->entry_dump(p, "PTA_MODE", pat, false);
if (xe_gt_is_media_type(gt))
pat = xe_mmio_read32(&gt->mmio, XE_REG(_PAT_ATS));
else
pat = xe_gt_mcr_unicast_read_any(gt, XE_REG_MCR(_PAT_ATS));
drm_printf(p, "PCIe ATS/PASID:\n");
xe->pat.ops->entry_dump(p, "PAT_ATS ", pat, false);
return 0;
}
@ -551,6 +559,7 @@ static const struct xe_pat_ops xe3p_xpc_pat_ops = {
void xe_pat_init_early(struct xe_device *xe)
{
xe->pat.idx[XE_CACHE_WB_COMPRESSION] = XE_PAT_INVALID_IDX;
xe->pat.idx[XE_CACHE_NONE_COMPRESSION] = XE_PAT_INVALID_IDX;
if (GRAPHICS_VERx100(xe) == 3511) {
xe->pat.ops = &xe3p_xpc_pat_ops;
xe->pat.table = xe3p_xpc_pat_table;

View File

@ -82,4 +82,12 @@ bool xe_pat_index_get_comp_en(struct xe_device *xe, u16 pat_index);
*/
u16 xe_pat_index_get_l3_policy(struct xe_device *xe, u16 pat_index);
#define xe_cache_pat_idx(xe, cache_mode) ({ \
const struct xe_device *__xedev = (xe); \
enum xe_cache_level __mode = (cache_mode); \
xe_assert(__xedev, __mode < __XE_CACHE_LEVEL_COUNT); \
xe_assert(__xedev, __xedev->pat.idx[__mode] != XE_PAT_INVALID_IDX); \
__xedev->pat.idx[__mode]; \
})
#endif

View File

@ -466,6 +466,7 @@ static const struct xe_device_desc cri_desc = {
.has_soc_remapper_sysctrl = true,
.has_soc_remapper_telem = true,
.has_sriov = true,
.has_sysctrl = true,
.max_gt_per_tile = 2,
MULTI_LRC_MASK,
.require_force_probe = true,
@ -764,8 +765,8 @@ static int xe_info_init_early(struct xe_device *xe,
xe->info.has_soc_remapper_telem = desc->has_soc_remapper_telem;
xe->info.has_sriov = xe_configfs_primary_gt_allowed(to_pci_dev(xe->drm.dev)) &&
desc->has_sriov;
xe->info.has_sysctrl = desc->has_sysctrl;
xe->info.skip_guc_pc = desc->skip_guc_pc;
xe->info.skip_mtcfg = desc->skip_mtcfg;
xe->info.skip_pcode = desc->skip_pcode;
xe->info.needs_scratch = desc->needs_scratch;
xe->info.needs_shared_vf_gt_wq = desc->needs_shared_vf_gt_wq;
@ -807,9 +808,6 @@ static void xe_info_probe_tile_count(struct xe_device *xe)
if (xe->info.tile_count == 1)
return;
if (xe->info.skip_mtcfg)
return;
mmio = xe_root_tile_mmio(xe);
/*
@ -960,6 +958,12 @@ static int xe_info_init(struct xe_device *xe,
xe->info.has_64bit_timestamp = graphics_desc->has_64bit_timestamp;
xe->info.has_mem_copy_instr = GRAPHICS_VER(xe) >= 20;
if (IS_SRIOV_VF(xe)) {
xe->info.has_sysctrl = 0;
xe->info.has_soc_remapper_sysctrl = 0;
xe->info.has_soc_remapper_telem = 0;
}
xe_info_probe_tile_count(xe);
for_each_remote_tile(tile, xe, id) {

View File

@ -191,6 +191,8 @@ static int pf_disable_vfs(struct xe_device *xe)
pci_disable_sriov(pdev);
xe_sriov_pf_reprovision_default(xe);
pf_reset_vfs(xe, num_vfs);
xe_sriov_pf_unprovision_vfs(xe, num_vfs);

View File

@ -57,9 +57,9 @@ struct xe_device_desc {
u8 has_soc_remapper_sysctrl:1;
u8 has_soc_remapper_telem:1;
u8 has_sriov:1;
u8 has_sysctrl:1;
u8 needs_scratch:1;
u8 skip_guc_pc:1;
u8 skip_mtcfg:1;
u8 skip_pcode:1;
u8 needs_shared_vf_gt_wq:1;
};

View File

@ -3,6 +3,9 @@
* Copyright © 2022 Intel Corporation
*/
#ifndef _XE_PCODE_API_H_
#define _XE_PCODE_API_H_
/* Internal to xe_pcode */
#include "regs/xe_reg_defs.h"
@ -47,8 +50,9 @@
#define WRITE_PSYSGPU_POWER_LIMIT 0x7
#define READ_PACKAGE_POWER_LIMIT 0x8
#define WRITE_PACKAGE_POWER_LIMIT 0x9
#define READ_PL_FROM_FW 0x1
#define READ_PL_FROM_PCODE 0x0
#define READ_PL_FROM_FW 0x1
#define READ_PL_ACCEPTED 0x2
#define PCODE_THERMAL_INFO 0x25
#define READ_THERMAL_LIMITS 0x0
@ -101,3 +105,5 @@
#define BMG_PCIE_CAP XE_REG(0x138340)
#define LINK_DOWNGRADE REG_GENMASK(1, 0)
#define DOWNGRADE_CAPABLE 2
#endif

View File

@ -26,6 +26,7 @@
#include "xe_pcode.h"
#include "xe_pxp.h"
#include "xe_sriov_vf_ccs.h"
#include "xe_sysctrl.h"
#include "xe_trace.h"
#include "xe_vm.h"
#include "xe_wa.h"
@ -259,6 +260,8 @@ int xe_pm_resume(struct xe_device *xe)
xe_i2c_pm_resume(xe, true);
xe_sysctrl_pm_resume(xe);
xe_irq_resume(xe);
for_each_gt(gt, xe, id) {
@ -670,6 +673,9 @@ int xe_pm_runtime_resume(struct xe_device *xe)
xe_i2c_pm_resume(xe, xe->d3cold.allowed);
if (xe->d3cold.allowed)
xe_sysctrl_pm_resume(xe);
xe_irq_resume(xe);
for_each_gt(gt, xe, id) {

View File

@ -14,6 +14,7 @@
#include "xe_gt_stats.h"
#include "xe_migrate.h"
#include "xe_page_reclaim.h"
#include "xe_pat.h"
#include "xe_pt_types.h"
#include "xe_pt_walk.h"
#include "xe_res_cursor.h"
@ -62,7 +63,7 @@ static u64 __xe_pt_empty_pte(struct xe_tile *tile, struct xe_vm *vm,
unsigned int level)
{
struct xe_device *xe = tile_to_xe(tile);
u16 pat_index = xe->pat.idx[XE_CACHE_WB];
u16 pat_index = xe_cache_pat_idx(xe, XE_CACHE_WB);
u8 id = tile->id;
if (!xe_vm_has_scratch(vm))

View File

@ -34,7 +34,7 @@ struct xe_pt {
bool rebind;
bool is_compact;
#if IS_ENABLED(CONFIG_DRM_XE_DEBUG_VM)
/** addr: Virtual address start address of the PT. */
/** @addr: Virtual address start address of the PT. */
u64 addr;
#endif
};

View File

@ -2,8 +2,8 @@
/*
* Copyright © 2022 Intel Corporation
*/
#ifndef __XE_PT_WALK__
#define __XE_PT_WALK__
#ifndef _XE_PT_WALK_H_
#define _XE_PT_WALK_H_
#include <linux/pagewalk.h>
#include <linux/types.h>
@ -34,7 +34,7 @@ struct xe_pt_walk {
* changed during the walk.
*/
const u64 *shifts;
/** @max_level: Highest populated level in @sizes */
/** @max_level: Highest populated level in @shifts */
unsigned int max_level;
/**
* @shared_pt_mode: Whether to skip all entries that are private
@ -49,7 +49,7 @@ struct xe_pt_walk {
/**
* typedef xe_pt_entry_fn - gpu page-table-walk callback-function
* @parent: The parent page.table.
* @parent: The parent page table.
* @offset: The offset (number of entries) into the page table.
* @level: The level of @parent.
* @addr: The virtual address.
@ -111,14 +111,14 @@ static inline bool xe_pt_covers(u64 addr, u64 end, unsigned int level,
}
/**
* xe_pt_num_entries: Number of page-table entries of a given range at this
* xe_pt_num_entries - Number of page-table entries of a given range at this
* level
* @addr: Start address.
* @end: End address.
* @level: Page table level.
* @walk: Walk info.
*
* Return: The number of page table entries at this level between @start and
* Return: The number of page table entries at this level between @addr and
* @end.
*/
static inline pgoff_t
@ -132,7 +132,7 @@ xe_pt_num_entries(u64 addr, u64 end, unsigned int level,
}
/**
* xe_pt_offset: Offset of the page-table entry for a given address.
* xe_pt_offset - Offset of the page-table entry for a given address.
* @addr: The address.
* @level: Page table level.
* @walk: Walk info.

View File

@ -13,10 +13,12 @@
#include "xe_device_types.h"
#include "xe_exec_queue.h"
#include "xe_force_wake.h"
#include "xe_guc_exec_queue_types.h"
#include "xe_guc_submit.h"
#include "xe_gsc_proxy.h"
#include "xe_gt_types.h"
#include "xe_huc.h"
#include "xe_hw_engine.h"
#include "xe_mmio.h"
#include "xe_pm.h"
#include "xe_pxp_submit.h"
@ -740,6 +742,10 @@ static void pxp_invalidate_queues(struct xe_pxp *pxp)
spin_unlock_irq(&pxp->queues.lock);
list_for_each_entry_safe(q, tmp, &to_clean, pxp.link) {
drm_dbg(&pxp->xe->drm,
"Killing queue due to PXP termination: eclass=%s, guc_id=%d\n",
xe_hw_engine_class_to_str(q->class), q->guc->id);
xe_exec_queue_kill(q);
/*

View File

@ -3,8 +3,8 @@
* Copyright(c) 2024, Intel Corporation. All rights reserved.
*/
#ifndef __XE_PXP_H__
#define __XE_PXP_H__
#ifndef _XE_PXP_H_
#define _XE_PXP_H_
#include <linux/types.h>
@ -32,4 +32,4 @@ int xe_pxp_key_assign(struct xe_pxp *pxp, struct xe_bo *bo);
int xe_pxp_bo_key_check(struct xe_pxp *pxp, struct xe_bo *bo);
int xe_pxp_obj_key_check(struct drm_gem_object *obj);
#endif /* __XE_PXP_H__ */
#endif /* _XE_PXP_H_ */

Some files were not shown because too many files have changed in this diff Show More