summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2026-01-16 13:39:15 +1000
committerDave Airlie <airlied@redhat.com>2026-01-16 13:39:44 +1000
commit971c2b68bddb87f4929e66cd4563fca78b722210 (patch)
tree3bc70fe3059e143f0f0f9425f39b83ae02da4617
parent9d10cd526111a989eb353c3a4df9d4c79695ea8d (diff)
parent83675851547e835c15252c601f41acf269c351d9 (diff)
Merge tag 'drm-xe-next-2026-01-15' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next
UAPI Changes: - Remove unused KEEP_ACTIVE flag in the new multi queue uAPI (Niranjana) - Expose new temperature attributes in HWMON (Karthik) Driver Changes: - Force i2c into polling mode when in survivability (Raag) - Validate preferred system memory placement in xe_svm_range_validate (Brost) - Adjust page count tracepoints in shrinker (Brost) - Fix a couple drm_pagemap issues with multi-GPU (Brost) - Define GuC firmware for NVL-S (Roper) - Handle GT resume failure (Raag) - Improve wedged mode handling (Lukasz) - Add missing newlines to drm_warn messages (Osama) - Fix WQ_MEM_RECLAIM passed as max_active to alloc_workqueue (Marco) - Page-reclaim fixes and PRL stats addition (Brian) - Fix struct guc_lfd_file_header kernel-doc (Jani) - Allow compressible surfaces to be 1-way coherent (Xin) - Fix DRM scheduler layering violations in Xe (Brost) - Minor improvements to MERT code (Michal) - Privatize struct xe_ggtt_node (Maarten) - Convert wait for lmem init into an assert (Bala) - Enable GSC loading and PXP for PTL (Daniele) - Replace use of system_wq with tlb_inval->timeout_wq (Marco) - VRAM addr range bit expansion (Fei) - Cleanup unused header includes (Roper) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patch.msgid.link/aWkSxRQK7VhTlP32@intel.com
-rw-r--r--Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon110
-rw-r--r--drivers/gpu/drm/drm_pagemap.c22
-rw-r--r--drivers/gpu/drm/xe/Makefile3
-rw-r--r--drivers/gpu/drm/xe/abi/guc_lfd_abi.h5
-rw-r--r--drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h4
-rw-r--r--drivers/gpu/drm/xe/display/xe_fb_pin.c104
-rw-r--r--drivers/gpu/drm/xe/display/xe_hdcp_gsc.c2
-rw-r--r--drivers/gpu/drm/xe/display/xe_stolen.c2
-rw-r--r--drivers/gpu/drm/xe/regs/xe_gt_regs.h6
-rw-r--r--drivers/gpu/drm/xe/regs/xe_mert_regs.h10
-rw-r--r--drivers/gpu/drm/xe/regs/xe_pcode_regs.h3
-rw-r--r--drivers/gpu/drm/xe/tests/xe_bo.c1
-rw-r--r--drivers/gpu/drm/xe/tests/xe_guc_buf_kunit.c2
-rw-r--r--drivers/gpu/drm/xe/xe_bb.c3
-rw-r--r--drivers/gpu/drm/xe/xe_bo.c33
-rw-r--r--drivers/gpu/drm/xe/xe_bo.h8
-rw-r--r--drivers/gpu/drm/xe/xe_debugfs.c75
-rw-r--r--drivers/gpu/drm/xe/xe_devcoredump.c3
-rw-r--r--drivers/gpu/drm/xe/xe_device.c141
-rw-r--r--drivers/gpu/drm/xe/xe_device.h2
-rw-r--r--drivers/gpu/drm/xe/xe_device_types.h25
-rw-r--r--drivers/gpu/drm/xe/xe_exec.c1
-rw-r--r--drivers/gpu/drm/xe/xe_exec_queue.c62
-rw-r--r--drivers/gpu/drm/xe/xe_exec_queue.h2
-rw-r--r--drivers/gpu/drm/xe/xe_exec_queue_types.h4
-rw-r--r--drivers/gpu/drm/xe/xe_execlist.c3
-rw-r--r--drivers/gpu/drm/xe/xe_ggtt.c219
-rw-r--r--drivers/gpu/drm/xe/xe_ggtt.h14
-rw-r--r--drivers/gpu/drm/xe/xe_ggtt_types.h32
-rw-r--r--drivers/gpu/drm/xe/xe_gpu_scheduler.c9
-rw-r--r--drivers/gpu/drm/xe/xe_gpu_scheduler.h37
-rw-r--r--drivers/gpu/drm/xe/xe_gpu_scheduler_types.h2
-rw-r--r--drivers/gpu/drm/xe/xe_gsc.c13
-rw-r--r--drivers/gpu/drm/xe/xe_gsc_debugfs.c5
-rw-r--r--drivers/gpu/drm/xe/xe_gsc_proxy.c2
-rw-r--r--drivers/gpu/drm/xe/xe_gsc_submit.c2
-rw-r--r--drivers/gpu/drm/xe/xe_gt.c34
-rw-r--r--drivers/gpu/drm/xe/xe_gt_clock.c6
-rw-r--r--drivers/gpu/drm/xe/xe_gt_debugfs.c1
-rw-r--r--drivers/gpu/drm/xe/xe_gt_idle.c1
-rw-r--r--drivers/gpu/drm/xe/xe_gt_mcr.c1
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c21
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c1
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c2
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sriov_pf_policy.c1
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c5
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sriov_vf.c1
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sriov_vf_types.h4
-rw-r--r--drivers/gpu/drm/xe/xe_gt_stats.c7
-rw-r--r--drivers/gpu/drm/xe/xe_gt_stats_types.h5
-rw-r--r--drivers/gpu/drm/xe/xe_gt_sysfs.c2
-rw-r--r--drivers/gpu/drm/xe/xe_gt_throttle.c2
-rw-r--r--drivers/gpu/drm/xe/xe_guc_ads.c18
-rw-r--r--drivers/gpu/drm/xe/xe_guc_ads.h5
-rw-r--r--drivers/gpu/drm/xe/xe_guc_buf.c1
-rw-r--r--drivers/gpu/drm/xe/xe_guc_capture.c14
-rw-r--r--drivers/gpu/drm/xe/xe_guc_debugfs.c5
-rw-r--r--drivers/gpu/drm/xe/xe_guc_exec_queue_types.h2
-rw-r--r--drivers/gpu/drm/xe/xe_guc_hwconfig.c4
-rw-r--r--drivers/gpu/drm/xe/xe_guc_log.c2
-rw-r--r--drivers/gpu/drm/xe/xe_guc_relay.c3
-rw-r--r--drivers/gpu/drm/xe/xe_guc_submit.c377
-rw-r--r--drivers/gpu/drm/xe/xe_guc_submit_types.h11
-rw-r--r--drivers/gpu/drm/xe/xe_guc_tlb_inval.c3
-rw-r--r--drivers/gpu/drm/xe/xe_heci_gsc.c1
-rw-r--r--drivers/gpu/drm/xe/xe_huc.c1
-rw-r--r--drivers/gpu/drm/xe/xe_huc_debugfs.c5
-rw-r--r--drivers/gpu/drm/xe/xe_hw_engine.c1
-rw-r--r--drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c2
-rw-r--r--drivers/gpu/drm/xe/xe_hw_engine_group.c2
-rw-r--r--drivers/gpu/drm/xe/xe_hw_fence.c20
-rw-r--r--drivers/gpu/drm/xe/xe_hw_fence.h2
-rw-r--r--drivers/gpu/drm/xe/xe_hwmon.c279
-rw-r--r--drivers/gpu/drm/xe/xe_i2c.c13
-rw-r--r--drivers/gpu/drm/xe/xe_irq.c1
-rw-r--r--drivers/gpu/drm/xe/xe_late_bind_fw_types.h4
-rw-r--r--drivers/gpu/drm/xe/xe_lmtt.c2
-rw-r--r--drivers/gpu/drm/xe/xe_lrc.c45
-rw-r--r--drivers/gpu/drm/xe/xe_lrc.h3
-rw-r--r--drivers/gpu/drm/xe/xe_memirq.c2
-rw-r--r--drivers/gpu/drm/xe/xe_mert.c76
-rw-r--r--drivers/gpu/drm/xe/xe_mert.h15
-rw-r--r--drivers/gpu/drm/xe/xe_mmio.c4
-rw-r--r--drivers/gpu/drm/xe/xe_mocs.c2
-rw-r--r--drivers/gpu/drm/xe/xe_module.c10
-rw-r--r--drivers/gpu/drm/xe/xe_module.h2
-rw-r--r--drivers/gpu/drm/xe/xe_nvm.c1
-rw-r--r--drivers/gpu/drm/xe/xe_page_reclaim.c6
-rw-r--r--drivers/gpu/drm/xe/xe_page_reclaim.h20
-rw-r--r--drivers/gpu/drm/xe/xe_pat.c52
-rw-r--r--drivers/gpu/drm/xe/xe_pat.h2
-rw-r--r--drivers/gpu/drm/xe/xe_pci.c5
-rw-r--r--drivers/gpu/drm/xe/xe_pci_types.h1
-rw-r--r--drivers/gpu/drm/xe/xe_pcode_api.h7
-rw-r--r--drivers/gpu/drm/xe/xe_pm.c26
-rw-r--r--drivers/gpu/drm/xe/xe_psmi.c2
-rw-r--r--drivers/gpu/drm/xe/xe_pt.c84
-rw-r--r--drivers/gpu/drm/xe/xe_pt_types.h1
-rw-r--r--drivers/gpu/drm/xe/xe_pxp.c1
-rw-r--r--drivers/gpu/drm/xe/xe_pxp_debugfs.c2
-rw-r--r--drivers/gpu/drm/xe/xe_reg_sr.c5
-rw-r--r--drivers/gpu/drm/xe/xe_reg_whitelist.c1
-rw-r--r--drivers/gpu/drm/xe/xe_ring_ops.c29
-rw-r--r--drivers/gpu/drm/xe/xe_rtp.c1
-rw-r--r--drivers/gpu/drm/xe/xe_sa.c2
-rw-r--r--drivers/gpu/drm/xe/xe_sched_job.c3
-rw-r--r--drivers/gpu/drm/xe/xe_sched_job_types.h2
-rw-r--r--drivers/gpu/drm/xe/xe_sriov_packet.c1
-rw-r--r--drivers/gpu/drm/xe/xe_sriov_pf.c4
-rw-r--r--drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c1
-rw-r--r--drivers/gpu/drm/xe/xe_sriov_vf.c1
-rw-r--r--drivers/gpu/drm/xe/xe_step.c3
-rw-r--r--drivers/gpu/drm/xe/xe_survivability_mode.c3
-rw-r--r--drivers/gpu/drm/xe/xe_svm.c2
-rw-r--r--drivers/gpu/drm/xe/xe_tile.c3
-rw-r--r--drivers/gpu/drm/xe/xe_tlb_inval.c17
-rw-r--r--drivers/gpu/drm/xe/xe_tlb_inval_types.h2
-rw-r--r--drivers/gpu/drm/xe/xe_trace.h5
-rw-r--r--drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c1
-rw-r--r--drivers/gpu/drm/xe/xe_ttm_sys_mgr.c1
-rw-r--r--drivers/gpu/drm/xe/xe_ttm_vram_mgr.c1
-rw-r--r--drivers/gpu/drm/xe/xe_uc.c2
-rw-r--r--drivers/gpu/drm/xe/xe_uc_debugfs.c2
-rw-r--r--drivers/gpu/drm/xe/xe_uc_fw.c14
-rw-r--r--drivers/gpu/drm/xe/xe_validation.c1
-rw-r--r--drivers/gpu/drm/xe/xe_vm.c28
-rw-r--r--drivers/gpu/drm/xe/xe_vm.h2
-rw-r--r--drivers/gpu/drm/xe/xe_vram.c4
-rw-r--r--drivers/gpu/drm/xe/xe_vram_freq.c1
-rw-r--r--drivers/gpu/drm/xe/xe_vsec.c1
-rw-r--r--drivers/gpu/drm/xe/xe_wa.c2
-rw-r--r--drivers/gpu/drm/xe/xe_wait_user_fence.c1
-rw-r--r--drivers/gpu/drm/xe/xe_wopcm.c2
-rw-r--r--include/uapi/drm/xe_drm.h4
134 files changed, 1391 insertions, 973 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
index d9e2b17c6872..55ab45f669ac 100644
--- a/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
+++ b/Documentation/ABI/testing/sysfs-driver-intel-xe-hwmon
@@ -109,6 +109,22 @@ Description: RO. Package current voltage in millivolt.
Only supported for particular Intel Xe graphics platforms.
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_crit
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. Package critical temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_emergency
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. Package shutdown temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_input
Date: March 2025
KernelVersion: 6.15
@@ -117,6 +133,30 @@ Description: RO. Package temperature in millidegree Celsius.
Only supported for particular Intel Xe graphics platforms.
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp2_max
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. Package maximum temperature limit in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp3_crit
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. VRAM critical temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp3_emergency
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. VRAM shutdown temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp3_input
Date: March 2025
KernelVersion: 6.15
@@ -125,6 +165,76 @@ Description: RO. VRAM temperature in millidegree Celsius.
Only supported for particular Intel Xe graphics platforms.
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp4_crit
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. Memory controller critical temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp4_emergency
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. Memory controller shutdown temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp4_input
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. Memory controller average temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp5_crit
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. GPU PCIe critical temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp5_emergency
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. GPU PCIe shutdown temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp5_input
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. GPU PCIe temperature in millidegree Celsius.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp[6-21]_crit
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. VRAM channel critical temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp[6-21]_emergency
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. VRAM channel shutdown temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
+What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/temp[6-21]_input
+Date: January 2026
+KernelVersion: 7.0
+Contact: intel-xe@lists.freedesktop.org
+Description: RO. VRAM channel temperature in millidegree Celsius.
+
+ Only supported for particular Intel Xe graphics platforms.
+
What: /sys/bus/pci/drivers/xe/.../hwmon/hwmon<i>/fan1_input
Date: March 2025
KernelVersion: 6.16
diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index ba099aa7c52f..03ee39a761a4 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -480,8 +480,18 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation,
.start = start,
.end = end,
.pgmap_owner = pagemap->owner,
- .flags = MIGRATE_VMA_SELECT_SYSTEM | MIGRATE_VMA_SELECT_DEVICE_COHERENT |
- MIGRATE_VMA_SELECT_DEVICE_PRIVATE,
+ /*
+ * FIXME: MIGRATE_VMA_SELECT_DEVICE_PRIVATE intermittently
+ * causes 'xe_exec_system_allocator --r *race*no*' to trigger aa
+ * engine reset and a hard hang due to getting stuck on a folio
+ * lock. This should work and needs to be root-caused. The only
+ * downside of not selecting MIGRATE_VMA_SELECT_DEVICE_PRIVATE
+ * is that device-to-device migrations won’t work; instead,
+ * memory will bounce through system memory. This path should be
+ * rare and only occur when the madvise attributes of memory are
+ * changed or atomics are being used.
+ */
+ .flags = MIGRATE_VMA_SELECT_SYSTEM | MIGRATE_VMA_SELECT_DEVICE_COHERENT,
};
unsigned long i, npages = npages_in_range(start, end);
unsigned long own_pages = 0, migrated_pages = 0;
@@ -582,7 +592,7 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation,
err = ops->populate_devmem_pfn(devmem_allocation, npages, migrate.dst);
if (err)
- goto err_finalize;
+ goto err_aborted_migration;
own_pages = 0;
@@ -621,8 +631,10 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation,
err = drm_pagemap_migrate_range(devmem_allocation, migrate.src, migrate.dst,
pages, pagemap_addr, &last, &cur,
mdetails);
- if (err)
+ if (err) {
+ npages = i + 1;
goto err_finalize;
+ }
}
cur.start = npages;
cur.ops = NULL; /* Force migration */
@@ -646,7 +658,7 @@ err_finalize:
err_aborted_migration:
migrate_vma_pages(&migrate);
- for (i = 0; i < npages;) {
+ for (i = 0; !err && i < npages;) {
struct page *page = migrate_pfn_to_page(migrate.src[i]);
unsigned long nr_pages = page ? NR_PAGES(folio_order(page_folio(page))) : 1;
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 2b20c79d7ec9..b39cbb756232 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -370,7 +370,8 @@ always-$(CONFIG_DRM_XE_WERROR) += \
$(patsubst %.h,%.hdrtest, $(shell cd $(src) && find * -name '*.h' $(hdrtest_find_args)))
quiet_cmd_hdrtest = HDRTEST $(patsubst %.hdrtest,%.h,$@)
- cmd_hdrtest = $(CC) -DHDRTEST $(filter-out $(CFLAGS_GCOV), $(c_flags)) -S -o /dev/null -x c /dev/null -include $<; touch $@
+ cmd_hdrtest = $(CC) $(filter-out $(CFLAGS_GCOV), $(c_flags)) -S -o /dev/null -x c /dev/null -include $< -include $<; \
+ $(srctree)/scripts/kernel-doc -none -Werror $<; touch $@
$(obj)/%.hdrtest: $(src)/%.h FORCE
$(call if_changed_dep,hdrtest)
diff --git a/drivers/gpu/drm/xe/abi/guc_lfd_abi.h b/drivers/gpu/drm/xe/abi/guc_lfd_abi.h
index b6ed20d5b508..5c48459f365f 100644
--- a/drivers/gpu/drm/xe/abi/guc_lfd_abi.h
+++ b/drivers/gpu/drm/xe/abi/guc_lfd_abi.h
@@ -148,7 +148,7 @@ struct guc_lfd_data_os_info {
} __packed;
/**
- * struct guc_logfile_header - Header of GuC Log Streaming-LFD-File Format.
+ * struct guc_lfd_file_header - Header of GuC Log Streaming-LFD-File Format.
* This structure encapsulates the layout of the guc-log-file format
*/
struct guc_lfd_file_header {
@@ -163,8 +163,7 @@ struct guc_lfd_file_header {
#define GUC_LFD_FILE_HEADER_VERSION_MASK_MAJOR GENMASK(31, 16)
#define GUC_LFD_FILE_HEADER_VERSION_MASK_MINOR GENMASK(15, 0)
- /** @stream: A stream of one or more guc_lfd_data LFD blocks
- */
+ /** @stream: A stream of one or more guc_lfd_data LFD blocks */
u32 stream[];
} __packed;
diff --git a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
index b17e3bab23d5..c4b5adaaa99a 100644
--- a/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
+++ b/drivers/gpu/drm/xe/compat-i915-headers/i915_vma.h
@@ -8,7 +8,7 @@
#include <uapi/drm/i915_drm.h>
-#include "xe_ggtt_types.h"
+#include "xe_ggtt.h"
#include <linux/refcount.h>
@@ -30,7 +30,7 @@ struct i915_vma {
static inline u32 i915_ggtt_offset(const struct i915_vma *vma)
{
- return vma->node->base.start;
+ return xe_ggtt_node_addr(vma->node);
}
#endif
diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c
index a22a9182dadb..d2c4e94180fa 100644
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c
+++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c
@@ -171,12 +171,13 @@ static int __xe_pin_fb_vma_dpt(const struct intel_framebuffer *fb,
}
static void
-write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo_ofs,
+write_ggtt_rotated(struct xe_ggtt *ggtt, u32 *ggtt_ofs,
+ u64 pte_flags,
+ xe_ggtt_set_pte_fn write_pte,
+ struct xe_bo *bo, u32 bo_ofs,
u32 width, u32 height, u32 src_stride, u32 dst_stride)
{
- struct xe_device *xe = xe_bo_device(bo);
u32 column, row;
- u64 pte = ggtt->pt_ops->pte_encode_flags(bo, xe->pat.idx[XE_CACHE_NONE]);
for (column = 0; column < width; column++) {
u32 src_idx = src_stride * (height - 1) + column + bo_ofs;
@@ -184,7 +185,7 @@ write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo
for (row = 0; row < height; row++) {
u64 addr = xe_bo_addr(bo, src_idx * XE_PAGE_SIZE, XE_PAGE_SIZE);
- ggtt->pt_ops->ggtt_set_pte(ggtt, *ggtt_ofs, pte | addr);
+ write_pte(ggtt, *ggtt_ofs, pte_flags | addr);
*ggtt_ofs += XE_PAGE_SIZE;
src_idx -= src_stride;
}
@@ -194,6 +195,28 @@ write_ggtt_rotated(struct xe_bo *bo, struct xe_ggtt *ggtt, u32 *ggtt_ofs, u32 bo
}
}
+struct fb_rotate_args {
+ const struct i915_gtt_view *view;
+ struct xe_bo *bo;
+};
+
+static void write_ggtt_rotated_node(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
+ u64 pte_flags, xe_ggtt_set_pte_fn write_pte, void *data)
+{
+ struct fb_rotate_args *args = data;
+ struct xe_bo *bo = args->bo;
+ const struct intel_rotation_info *rot_info = &args->view->rotated;
+ u32 ggtt_ofs = xe_ggtt_node_addr(node);
+
+ for (u32 i = 0; i < ARRAY_SIZE(rot_info->plane); i++)
+ write_ggtt_rotated(ggtt, &ggtt_ofs, pte_flags, write_pte,
+ bo, rot_info->plane[i].offset,
+ rot_info->plane[i].width,
+ rot_info->plane[i].height,
+ rot_info->plane[i].src_stride,
+ rot_info->plane[i].dst_stride);
+}
+
static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb,
const struct i915_gtt_view *view,
struct i915_vma *vma,
@@ -204,66 +227,43 @@ static int __xe_pin_fb_vma_ggtt(const struct intel_framebuffer *fb,
struct xe_device *xe = to_xe_device(fb->base.dev);
struct xe_tile *tile0 = xe_device_get_root_tile(xe);
struct xe_ggtt *ggtt = tile0->mem.ggtt;
+ u64 pte, size;
u32 align;
- int ret;
+ int ret = 0;
/* TODO: Consider sharing framebuffer mapping?
* embed i915_vma inside intel_framebuffer
*/
guard(xe_pm_runtime_noresume)(xe);
- ACQUIRE(mutex_intr, lock)(&ggtt->lock);
- ret = ACQUIRE_ERR(mutex_intr, &lock);
- if (ret)
- return ret;
align = XE_PAGE_SIZE;
- if (xe_bo_is_vram(bo) && ggtt->flags & XE_GGTT_FLAGS_64K)
- align = max_t(u32, align, SZ_64K);
+ if (xe_bo_is_vram(bo) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K)
+ align = max(align, SZ_64K);
+ /* Fast case, preallocated GGTT view? */
if (bo->ggtt_node[tile0->id] && view->type == I915_GTT_VIEW_NORMAL) {
vma->node = bo->ggtt_node[tile0->id];
- } else if (view->type == I915_GTT_VIEW_NORMAL) {
- vma->node = xe_ggtt_node_init(ggtt);
- if (IS_ERR(vma->node))
- return PTR_ERR(vma->node);
-
- ret = xe_ggtt_node_insert_locked(vma->node, xe_bo_size(bo), align, 0);
- if (ret) {
- xe_ggtt_node_fini(vma->node);
- return ret;
- }
-
- xe_ggtt_map_bo(ggtt, vma->node, bo, xe->pat.idx[XE_CACHE_NONE]);
- } else {
- u32 i, ggtt_ofs;
- const struct intel_rotation_info *rot_info = &view->rotated;
-
- /* display seems to use tiles instead of bytes here, so convert it back.. */
- u32 size = intel_rotation_info_size(rot_info) * XE_PAGE_SIZE;
-
- vma->node = xe_ggtt_node_init(ggtt);
- if (IS_ERR(vma->node)) {
- ret = PTR_ERR(vma->node);
- return ret;
- }
-
- ret = xe_ggtt_node_insert_locked(vma->node, size, align, 0);
- if (ret) {
- xe_ggtt_node_fini(vma->node);
- return ret;
- }
-
- ggtt_ofs = vma->node->base.start;
-
- for (i = 0; i < ARRAY_SIZE(rot_info->plane); i++)
- write_ggtt_rotated(bo, ggtt, &ggtt_ofs,
- rot_info->plane[i].offset,
- rot_info->plane[i].width,
- rot_info->plane[i].height,
- rot_info->plane[i].src_stride,
- rot_info->plane[i].dst_stride);
+ return 0;
}
+ /* TODO: Consider sharing framebuffer mapping?
+ * embed i915_vma inside intel_framebuffer
+ */
+ if (view->type == I915_GTT_VIEW_NORMAL)
+ size = xe_bo_size(bo);
+ else
+ /* 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]);
+ vma->node = xe_ggtt_node_insert_transform(ggtt, bo, pte,
+ ALIGN(size, align), align,
+ view->type == I915_GTT_VIEW_NORMAL ?
+ NULL : write_ggtt_rotated_node,
+ &(struct fb_rotate_args){view, bo});
+ if (IS_ERR(vma->node))
+ ret = PTR_ERR(vma->node);
+
return ret;
}
@@ -353,7 +353,7 @@ static void __xe_unpin_fb_vma(struct i915_vma *vma)
if (vma->dpt)
xe_bo_unpin_map_no_vm(vma->dpt);
else if (!xe_ggtt_node_allocated(vma->bo->ggtt_node[tile_id]) ||
- vma->bo->ggtt_node[tile_id]->base.start != vma->node->base.start)
+ vma->bo->ggtt_node[tile_id] != vma->node)
xe_ggtt_node_remove(vma->node, false);
ttm_bo_reserve(&vma->bo->ttm, false, false, NULL);
diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
index 07acae121aa7..ed1f65f5ef4d 100644
--- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
+++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c
@@ -39,7 +39,7 @@ static bool intel_hdcp_gsc_check_status(struct drm_device *drm)
struct xe_gt *gt = tile->media_gt;
struct xe_gsc *gsc = &gt->uc.gsc;
- if (!gsc || !xe_uc_fw_is_enabled(&gsc->fw)) {
+ if (!gsc || !xe_uc_fw_is_available(&gsc->fw)) {
drm_dbg_kms(&xe->drm,
"GSC Components not ready for HDCP2.x\n");
return false;
diff --git a/drivers/gpu/drm/xe/display/xe_stolen.c b/drivers/gpu/drm/xe/display/xe_stolen.c
index 12771709183a..8dc2f86ec602 100644
--- a/drivers/gpu/drm/xe/display/xe_stolen.c
+++ b/drivers/gpu/drm/xe/display/xe_stolen.c
@@ -78,7 +78,7 @@ static u64 xe_stolen_node_address(const struct intel_stolen_node *node)
static u64 xe_stolen_node_size(const struct intel_stolen_node *node)
{
- return node->bo->ttm.base.size;
+ return xe_bo_size(node->bo);
}
static struct intel_stolen_node *xe_stolen_node_alloc(struct drm_device *drm)
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
index 93643da57428..24fc64fc832e 100644
--- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
@@ -89,6 +89,7 @@
#define UNIFIED_COMPRESSION_FORMAT REG_GENMASK(3, 0)
#define XE2_GAMREQSTRM_CTRL XE_REG_MCR(0x4194)
+#define EN_CMP_1WCOH REG_BIT(15)
#define CG_DIS_CNTLBUS REG_BIT(6)
#define CCS_AUX_INV XE_REG(0x4208)
@@ -101,6 +102,11 @@
#define XE2_LMEM_CFG XE_REG(0x48b0)
+#define XE2_GAMWALK_CTRL 0x47e4
+#define XE2_GAMWALK_CTRL_MEDIA XE_REG(XE2_GAMWALK_CTRL + MEDIA_GT_GSI_OFFSET)
+#define XE2_GAMWALK_CTRL_3D XE_REG_MCR(XE2_GAMWALK_CTRL)
+#define EN_CMP_1WCOH_GW REG_BIT(14)
+
#define XEHP_FLAT_CCS_BASE_ADDR XE_REG_MCR(0x4910)
#define XEHP_FLAT_CCS_PTR REG_GENMASK(31, 8)
diff --git a/drivers/gpu/drm/xe/regs/xe_mert_regs.h b/drivers/gpu/drm/xe/regs/xe_mert_regs.h
index c345e11ceea8..99e5a26da657 100644
--- a/drivers/gpu/drm/xe/regs/xe_mert_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_mert_regs.h
@@ -11,11 +11,13 @@
#define MERT_LMEM_CFG XE_REG(0x1448b0)
#define MERT_TLB_CT_INTR_ERR_ID_PORT XE_REG(0x145190)
-#define MERT_TLB_CT_VFID_MASK REG_GENMASK(16, 9)
-#define MERT_TLB_CT_ERROR_MASK REG_GENMASK(5, 0)
-#define MERT_TLB_CT_LMTT_FAULT 0x05
+#define CATERR_VFID REG_GENMASK(16, 9)
+#define CATERR_CODES REG_GENMASK(5, 0)
+#define CATERR_NO_ERROR 0x00
+#define CATERR_UNMAPPED_GGTT 0x01
+#define CATERR_LMTT_FAULT 0x05
#define MERT_TLB_INV_DESC_A XE_REG(0x14cf7c)
#define MERT_TLB_INV_DESC_A_VALID REG_BIT(0)
-#endif /* _XE_MERT_REGS_H_ */
+#endif
diff --git a/drivers/gpu/drm/xe/regs/xe_pcode_regs.h b/drivers/gpu/drm/xe/regs/xe_pcode_regs.h
index fb097607b86c..4b3c46eb858f 100644
--- a/drivers/gpu/drm/xe/regs/xe_pcode_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_pcode_regs.h
@@ -21,7 +21,10 @@
#define BMG_FAN_1_SPEED XE_REG(0x138140)
#define BMG_FAN_2_SPEED XE_REG(0x138170)
#define BMG_FAN_3_SPEED XE_REG(0x1381a0)
+#define BMG_VRAM_TEMPERATURE_N(n) XE_REG(0x138260 + ((n) * (sizeof(u32))))
#define BMG_VRAM_TEMPERATURE XE_REG(0x1382c0)
+#define TEMP_MASK_VRAM_N REG_GENMASK(30, 8)
+#define TEMP_SIGN_MASK REG_BIT(31)
#define BMG_PACKAGE_TEMPERATURE XE_REG(0x138434)
#endif /* _XE_PCODE_REGS_H_ */
diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c
index 2278e589a493..b7d8e45804cf 100644
--- a/drivers/gpu/drm/xe/tests/xe_bo.c
+++ b/drivers/gpu/drm/xe/tests/xe_bo.c
@@ -18,6 +18,7 @@
#include "tests/xe_test.h"
#include "xe_bo_evict.h"
+#include "xe_gt.h"
#include "xe_pci.h"
#include "xe_pm.h"
diff --git a/drivers/gpu/drm/xe/tests/xe_guc_buf_kunit.c b/drivers/gpu/drm/xe/tests/xe_guc_buf_kunit.c
index d266882adc0e..acddbedcf17c 100644
--- a/drivers/gpu/drm/xe/tests/xe_guc_buf_kunit.c
+++ b/drivers/gpu/drm/xe/tests/xe_guc_buf_kunit.c
@@ -67,7 +67,7 @@ static int guc_buf_test_init(struct kunit *test)
KUNIT_ASSERT_EQ(test, 0,
xe_ggtt_init_kunit(ggtt, DUT_GGTT_START,
- DUT_GGTT_START + DUT_GGTT_SIZE));
+ DUT_GGTT_SIZE));
kunit_activate_static_stub(test, xe_managed_bo_create_pin_map,
replacement_xe_managed_bo_create_pin_map);
diff --git a/drivers/gpu/drm/xe/xe_bb.c b/drivers/gpu/drm/xe/xe_bb.c
index 6d20229c11de..8b678297aaa2 100644
--- a/drivers/gpu/drm/xe/xe_bb.c
+++ b/drivers/gpu/drm/xe/xe_bb.c
@@ -7,10 +7,9 @@
#include "instructions/xe_mi_commands.h"
#include "xe_assert.h"
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_exec_queue_types.h"
#include "xe_gt.h"
-#include "xe_hw_fence.h"
#include "xe_sa.h"
#include "xe_sched_job.h"
#include "xe_vm_types.h"
diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c
index 8b6474cd3eaf..e9180b01a4e4 100644
--- a/drivers/gpu/drm/xe/xe_bo.c
+++ b/drivers/gpu/drm/xe/xe_bo.c
@@ -26,9 +26,9 @@
#include "xe_dma_buf.h"
#include "xe_drm_client.h"
#include "xe_ggtt.h"
-#include "xe_gt.h"
#include "xe_map.h"
#include "xe_migrate.h"
+#include "xe_pat.h"
#include "xe_pm.h"
#include "xe_preempt_fence.h"
#include "xe_pxp.h"
@@ -1054,6 +1054,7 @@ static long xe_bo_shrink_purge(struct ttm_operation_ctx *ctx,
unsigned long *scanned)
{
struct xe_device *xe = ttm_to_xe_device(bo->bdev);
+ struct ttm_tt *tt = bo->ttm;
long lret;
/* Fake move to system, without copying data. */
@@ -1078,8 +1079,10 @@ static long xe_bo_shrink_purge(struct ttm_operation_ctx *ctx,
.writeback = false,
.allow_move = false});
- if (lret > 0)
+ if (lret > 0) {
xe_ttm_tt_account_subtract(xe, bo->ttm);
+ update_global_total_pages(bo->bdev, -(long)tt->num_pages);
+ }
return lret;
}
@@ -1165,8 +1168,10 @@ long xe_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo,
if (needs_rpm)
xe_pm_runtime_put(xe);
- if (lret > 0)
+ if (lret > 0) {
xe_ttm_tt_account_subtract(xe, tt);
+ update_global_total_pages(bo->bdev, -(long)tt->num_pages);
+ }
out_unref:
xe_bo_put(xe_bo);
@@ -1709,7 +1714,7 @@ static void xe_ttm_bo_destroy(struct ttm_buffer_object *ttm_bo)
xe_assert(xe, list_empty(&ttm_bo->base.gpuva.list));
for_each_tile(tile, xe, id)
- if (bo->ggtt_node[id] && bo->ggtt_node[id]->base.size)
+ if (bo->ggtt_node[id])
xe_ggtt_remove_bo(tile->mem.ggtt, bo);
#ifdef CONFIG_PROC_FS
@@ -3517,16 +3522,16 @@ bool xe_bo_needs_ccs_pages(struct xe_bo *bo)
if (IS_DGFX(xe) && (bo->flags & XE_BO_FLAG_SYSTEM))
return false;
+ /* Check if userspace explicitly requested no compression */
+ if (bo->flags & XE_BO_FLAG_NO_COMPRESSION)
+ return false;
+
/*
- * Compression implies coh_none, therefore we know for sure that WB
- * memory can't currently use compression, which is likely one of the
- * common cases.
- * Additionally, userspace may explicitly request no compression via the
- * DRM_XE_GEM_CREATE_FLAG_NO_COMPRESSION flag, which should also disable
- * CCS usage.
+ * For WB (Write-Back) CPU caching mode, check if the device
+ * supports WB compression with coherency.
*/
- if (bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB ||
- bo->flags & XE_BO_FLAG_NO_COMPRESSION)
+ if (bo->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB &&
+ xe->pat.idx[XE_CACHE_WB_COMPRESSION] == XE_PAT_INVALID_IDX)
return false;
return true;
@@ -3603,8 +3608,8 @@ void xe_bo_put(struct xe_bo *bo)
might_lock(&bo->client->bos_lock);
#endif
for_each_tile(tile, xe_bo_device(bo), id)
- if (bo->ggtt_node[id] && bo->ggtt_node[id]->ggtt)
- xe_ggtt_might_lock(bo->ggtt_node[id]->ggtt);
+ if (bo->ggtt_node[id])
+ xe_ggtt_might_lock(tile->mem.ggtt);
drm_gem_object_put(&bo->ttm.base);
}
}
diff --git a/drivers/gpu/drm/xe/xe_bo.h b/drivers/gpu/drm/xe/xe_bo.h
index 8ab4474129c3..c914ab719f20 100644
--- a/drivers/gpu/drm/xe/xe_bo.h
+++ b/drivers/gpu/drm/xe/xe_bo.h
@@ -9,6 +9,7 @@
#include <drm/ttm/ttm_tt.h>
#include "xe_bo_types.h"
+#include "xe_ggtt.h"
#include "xe_macros.h"
#include "xe_validation.h"
#include "xe_vm_types.h"
@@ -252,13 +253,14 @@ static inline u32
__xe_bo_ggtt_addr(struct xe_bo *bo, u8 tile_id)
{
struct xe_ggtt_node *ggtt_node = bo->ggtt_node[tile_id];
+ u64 offset;
if (XE_WARN_ON(!ggtt_node))
return 0;
- XE_WARN_ON(ggtt_node->base.size > xe_bo_size(bo));
- XE_WARN_ON(ggtt_node->base.start + ggtt_node->base.size > (1ull << 32));
- return ggtt_node->base.start;
+ offset = xe_ggtt_node_addr(ggtt_node);
+ XE_WARN_ON(offset + xe_bo_size(bo) > (1ull << 32));
+ return offset;
}
static inline u32
diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c
index 0907868b32d6..844cfafe1ec7 100644
--- a/drivers/gpu/drm/xe/xe_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_debugfs.c
@@ -254,36 +254,81 @@ static ssize_t wedged_mode_show(struct file *f, char __user *ubuf,
return simple_read_from_buffer(ubuf, size, pos, buf, len);
}
+static int __wedged_mode_set_reset_policy(struct xe_gt *gt, enum xe_wedged_mode mode)
+{
+ bool enable_engine_reset;
+ int ret;
+
+ enable_engine_reset = (mode != XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET);
+ ret = xe_guc_ads_scheduler_policy_toggle_reset(&gt->uc.guc.ads,
+ enable_engine_reset);
+ if (ret)
+ xe_gt_err(gt, "Failed to update GuC ADS scheduler policy (%pe)\n", ERR_PTR(ret));
+
+ return ret;
+}
+
+static int wedged_mode_set_reset_policy(struct xe_device *xe, enum xe_wedged_mode mode)
+{
+ struct xe_gt *gt;
+ int ret;
+ u8 id;
+
+ guard(xe_pm_runtime)(xe);
+ for_each_gt(gt, xe, id) {
+ ret = __wedged_mode_set_reset_policy(gt, mode);
+ if (ret) {
+ if (id > 0) {
+ xe->wedged.inconsistent_reset = true;
+ drm_err(&xe->drm, "Inconsistent reset policy state between GTs\n");
+ }
+ return ret;
+ }
+ }
+
+ xe->wedged.inconsistent_reset = false;
+
+ return 0;
+}
+
+static bool wedged_mode_needs_policy_update(struct xe_device *xe, enum xe_wedged_mode mode)
+{
+ if (xe->wedged.inconsistent_reset)
+ return true;
+
+ if (xe->wedged.mode == mode)
+ return false;
+
+ if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET ||
+ mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)
+ return true;
+
+ return false;
+}
+
static ssize_t wedged_mode_set(struct file *f, const char __user *ubuf,
size_t size, loff_t *pos)
{
struct xe_device *xe = file_inode(f)->i_private;
- struct xe_gt *gt;
u32 wedged_mode;
ssize_t ret;
- u8 id;
ret = kstrtouint_from_user(ubuf, size, 0, &wedged_mode);
if (ret)
return ret;
- if (wedged_mode > 2)
- return -EINVAL;
+ ret = xe_device_validate_wedged_mode(xe, wedged_mode);
+ if (ret)
+ return ret;
- if (xe->wedged.mode == wedged_mode)
- return size;
+ if (wedged_mode_needs_policy_update(xe, wedged_mode)) {
+ ret = wedged_mode_set_reset_policy(xe, wedged_mode);
+ if (ret)
+ return ret;
+ }
xe->wedged.mode = wedged_mode;
- guard(xe_pm_runtime)(xe);
- for_each_gt(gt, xe, id) {
- ret = xe_guc_ads_scheduler_policy_toggle_reset(&gt->uc.guc.ads);
- if (ret) {
- xe_gt_err(gt, "Failed to update GuC ADS scheduler policy. GuC may still cause engine reset even with wedged_mode=2\n");
- return -EIO;
- }
- }
-
return size;
}
diff --git a/drivers/gpu/drm/xe/xe_devcoredump.c b/drivers/gpu/drm/xe/xe_devcoredump.c
index 7263c2a5f3a8..cf41bb6d2172 100644
--- a/drivers/gpu/drm/xe/xe_devcoredump.c
+++ b/drivers/gpu/drm/xe/xe_devcoredump.c
@@ -15,14 +15,13 @@
#include "xe_device.h"
#include "xe_exec_queue.h"
#include "xe_force_wake.h"
-#include "xe_gt.h"
#include "xe_gt_printk.h"
+#include "xe_gt_types.h"
#include "xe_guc_capture.h"
#include "xe_guc_ct.h"
#include "xe_guc_log.h"
#include "xe_guc_submit.h"
#include "xe_hw_engine.h"
-#include "xe_module.h"
#include "xe_pm.h"
#include "xe_sched_job.h"
#include "xe_vm.h"
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index e101d290b2a6..495310a624b5 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -8,7 +8,6 @@
#include <linux/aperture.h>
#include <linux/delay.h>
#include <linux/fault-inject.h>
-#include <linux/iopoll.h>
#include <linux/units.h>
#include <drm/drm_atomic_helper.h>
@@ -36,7 +35,6 @@
#include "xe_exec_queue.h"
#include "xe_force_wake.h"
#include "xe_ggtt.h"
-#include "xe_gsc_proxy.h"
#include "xe_gt.h"
#include "xe_gt_mcr.h"
#include "xe_gt_printk.h"
@@ -180,12 +178,7 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file)
xa_for_each(&xef->exec_queue.xa, idx, q) {
if (q->vm && q->hwe->hw_engine_group)
xe_hw_engine_group_del_exec_queue(q->hwe->hw_engine_group, q);
-
- if (xe_exec_queue_is_multi_queue_primary(q))
- xe_exec_queue_group_kill_put(q->multi_queue.group);
- else
- xe_exec_queue_kill(q);
-
+ xe_exec_queue_kill(q);
xe_exec_queue_put(q);
}
xa_for_each(&xef->vm.xa, idx, vm)
@@ -659,62 +652,14 @@ mask_err:
return err;
}
-static int lmem_initializing(struct xe_device *xe)
+static void assert_lmem_ready(struct xe_device *xe)
{
- if (xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL) & LMEM_INIT)
- return 0;
-
- if (signal_pending(current))
- return -EINTR;
-
- return 1;
-}
-
-static int wait_for_lmem_ready(struct xe_device *xe)
-{
- const unsigned long TIMEOUT_SEC = 60;
- unsigned long prev_jiffies;
- int initializing;
-
- if (!IS_DGFX(xe))
- return 0;
-
- if (IS_SRIOV_VF(xe))
- return 0;
-
- if (!lmem_initializing(xe))
- return 0;
-
- drm_dbg(&xe->drm, "Waiting for lmem initialization\n");
- prev_jiffies = jiffies;
-
- /*
- * The boot firmware initializes local memory and
- * assesses its health. If memory training fails,
- * the punit will have been instructed to keep the GT powered
- * down.we won't be able to communicate with it
- *
- * If the status check is done before punit updates the register,
- * it can lead to the system being unusable.
- * use a timeout and defer the probe to prevent this.
- */
- poll_timeout_us(initializing = lmem_initializing(xe),
- initializing <= 0,
- 20 * USEC_PER_MSEC, TIMEOUT_SEC * USEC_PER_SEC, true);
- if (initializing < 0)
- return initializing;
-
- if (initializing) {
- drm_dbg(&xe->drm, "lmem not initialized by firmware\n");
- return -EPROBE_DEFER;
- }
-
- drm_dbg(&xe->drm, "lmem ready after %ums",
- jiffies_to_msecs(jiffies - prev_jiffies));
+ if (!IS_DGFX(xe) || IS_SRIOV_VF(xe))
+ return;
- return 0;
+ xe_assert(xe, xe_mmio_read32(xe_root_tile_mmio(xe), GU_CNTL) &
+ LMEM_INIT);
}
-ALLOW_ERROR_INJECTION(wait_for_lmem_ready, ERRNO); /* See xe_pci_probe() */
static void vf_update_device_info(struct xe_device *xe)
{
@@ -769,6 +714,11 @@ int xe_device_probe_early(struct xe_device *xe)
if (IS_SRIOV_VF(xe))
vf_update_device_info(xe);
+ /*
+ * Check for pcode uncore_init status to confirm if the SoC
+ * initialization is complete. Until done, any MMIO or lmem access from
+ * the driver will be blocked
+ */
err = xe_pcode_probe_early(xe);
if (err || xe_survivability_mode_is_requested(xe)) {
int save_err = err;
@@ -785,11 +735,17 @@ int xe_device_probe_early(struct xe_device *xe)
return save_err;
}
- err = wait_for_lmem_ready(xe);
- if (err)
- return err;
+ /*
+ * Make sure the lmem is initialized and ready to use. xe_pcode_ready()
+ * is flagged after full initialization is complete. Assert if lmem is
+ * not initialized.
+ */
+ assert_lmem_ready(xe);
- xe->wedged.mode = xe_modparam.wedged_mode;
+ xe->wedged.mode = xe_device_validate_wedged_mode(xe, xe_modparam.wedged_mode) ?
+ XE_WEDGED_MODE_DEFAULT : xe_modparam.wedged_mode;
+ drm_dbg(&xe->drm, "wedged_mode: setting mode (%u) %s\n",
+ xe->wedged.mode, xe_wedged_mode_to_string(xe->wedged.mode));
err = xe_device_vram_alloc(xe);
if (err)
@@ -1272,10 +1228,10 @@ static void xe_device_wedged_fini(struct drm_device *drm, void *arg)
* DOC: Xe Device Wedging
*
* Xe driver uses drm device wedged uevent as documented in Documentation/gpu/drm-uapi.rst.
- * When device is in wedged state, every IOCTL will be blocked and GT cannot be
- * used. Certain critical errors like gt reset failure, firmware failures can cause
- * the device to be wedged. The default recovery method for a wedged state
- * is rebind/bus-reset.
+ * When device is in wedged state, every IOCTL will be blocked and GT cannot
+ * be used. The conditions under which the driver declares the device wedged
+ * depend on the wedged mode configuration (see &enum xe_wedged_mode). The
+ * default recovery method for a wedged state is rebind/bus-reset.
*
* Another recovery method is vendor-specific. Below are the cases that send
* ``WEDGED=vendor-specific`` recovery method in drm device wedged uevent.
@@ -1340,7 +1296,7 @@ void xe_device_declare_wedged(struct xe_device *xe)
struct xe_gt *gt;
u8 id;
- if (xe->wedged.mode == 0) {
+ if (xe->wedged.mode == XE_WEDGED_MODE_NEVER) {
drm_dbg(&xe->drm, "Wedged mode is forcibly disabled\n");
return;
}
@@ -1374,3 +1330,48 @@ void xe_device_declare_wedged(struct xe_device *xe)
drm_dev_wedged_event(&xe->drm, xe->wedged.method, NULL);
}
}
+
+/**
+ * xe_device_validate_wedged_mode - Check if given mode is supported
+ * @xe: the &xe_device
+ * @mode: requested mode to validate
+ *
+ * Check whether the provided wedged mode is supported.
+ *
+ * Return: 0 if mode is supported, error code otherwise.
+ */
+int xe_device_validate_wedged_mode(struct xe_device *xe, unsigned int mode)
+{
+ if (mode > XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET) {
+ drm_dbg(&xe->drm, "wedged_mode: invalid value (%u)\n", mode);
+ return -EINVAL;
+ } else if (mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET && (IS_SRIOV_VF(xe) ||
+ (IS_SRIOV_PF(xe) && !IS_ENABLED(CONFIG_DRM_XE_DEBUG)))) {
+ drm_dbg(&xe->drm, "wedged_mode: (%u) %s mode is not supported for %s\n",
+ mode, xe_wedged_mode_to_string(mode),
+ xe_sriov_mode_to_string(xe_device_sriov_mode(xe)));
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+/**
+ * xe_wedged_mode_to_string - Convert enum value to string.
+ * @mode: the &xe_wedged_mode to convert
+ *
+ * Returns: wedged mode as a user friendly string.
+ */
+const char *xe_wedged_mode_to_string(enum xe_wedged_mode mode)
+{
+ switch (mode) {
+ case XE_WEDGED_MODE_NEVER:
+ return "never";
+ case XE_WEDGED_MODE_UPON_CRITICAL_ERROR:
+ return "upon-critical-error";
+ case XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET:
+ return "upon-any-hang-no-reset";
+ default:
+ return "<invalid>";
+ }
+}
diff --git a/drivers/gpu/drm/xe/xe_device.h b/drivers/gpu/drm/xe/xe_device.h
index 3e72fa4609f8..3740143790db 100644
--- a/drivers/gpu/drm/xe/xe_device.h
+++ b/drivers/gpu/drm/xe/xe_device.h
@@ -194,6 +194,8 @@ static inline bool xe_device_wedged(struct xe_device *xe)
void xe_device_set_wedged_method(struct xe_device *xe, unsigned long method);
void xe_device_declare_wedged(struct xe_device *xe);
+int xe_device_validate_wedged_mode(struct xe_device *xe, unsigned int mode);
+const char *xe_wedged_mode_to_string(enum xe_wedged_mode mode);
struct xe_file *xe_file_get(struct xe_file *xef);
void xe_file_put(struct xe_file *xef);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index a85be9ba175e..f689766adcb1 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -46,6 +46,25 @@ struct xe_pat_ops;
struct xe_pxp;
struct xe_vram_region;
+/**
+ * enum xe_wedged_mode - possible wedged modes
+ * @XE_WEDGED_MODE_NEVER: Device will never be declared wedged.
+ * @XE_WEDGED_MODE_UPON_CRITICAL_ERROR: Device will be declared wedged only
+ * when critical error occurs like GT reset failure or firmware failure.
+ * This is the default mode.
+ * @XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET: Device will be declared wedged on
+ * any hang. In this mode, engine resets are disabled to avoid automatic
+ * recovery attempts. This mode is primarily intended for debugging hangs.
+ */
+enum xe_wedged_mode {
+ XE_WEDGED_MODE_NEVER = 0,
+ XE_WEDGED_MODE_UPON_CRITICAL_ERROR = 1,
+ XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET = 2,
+};
+
+#define XE_WEDGED_MODE_DEFAULT XE_WEDGED_MODE_UPON_CRITICAL_ERROR
+#define XE_WEDGED_MODE_DEFAULT_STR "upon-critical-error"
+
#define XE_BO_INVALID_OFFSET LONG_MAX
#define GRAPHICS_VER(xe) ((xe)->info.graphics_verx100 / 100)
@@ -322,6 +341,8 @@ struct xe_device {
* pcode mailbox commands.
*/
u8 has_mbx_power_limits:1;
+ /** @info.has_mbx_thermal_info: Device supports thermal mailbox commands */
+ u8 has_mbx_thermal_info:1;
/** @info.has_mem_copy_instr: Device supports MEM_COPY instruction */
u8 has_mem_copy_instr:1;
/** @info.has_mert: Device has standalone MERT */
@@ -626,9 +647,11 @@ struct xe_device {
/** @wedged.flag: Xe device faced a critical error and is now blocked. */
atomic_t flag;
/** @wedged.mode: Mode controlled by kernel parameter and debugfs */
- int mode;
+ enum xe_wedged_mode mode;
/** @wedged.method: Recovery method to be sent in the drm device wedged uevent */
unsigned long method;
+ /** @wedged.inconsistent_reset: Inconsistent reset policy state between GTs */
+ bool inconsistent_reset;
} wedged;
/** @bo_device: Struct to control async free of BOs */
diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c
index 730a5c9c2637..a5485fe6e3f1 100644
--- a/drivers/gpu/drm/xe/xe_exec.c
+++ b/drivers/gpu/drm/xe/xe_exec.c
@@ -11,7 +11,6 @@
#include <uapi/drm/xe_drm.h>
#include <linux/delay.h>
-#include "xe_bo.h"
#include "xe_device.h"
#include "xe_exec_queue.h"
#include "xe_hw_engine_group.h"
diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c
index 0b9e074b022f..a940849bb6c7 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.c
+++ b/drivers/gpu/drm/xe/xe_exec_queue.c
@@ -21,13 +21,11 @@
#include "xe_gt_sriov_vf.h"
#include "xe_hw_engine_class_sysfs.h"
#include "xe_hw_engine_group.h"
-#include "xe_hw_fence.h"
#include "xe_irq.h"
#include "xe_lrc.h"
#include "xe_macros.h"
#include "xe_migrate.h"
#include "xe_pm.h"
-#include "xe_ring_ops_types.h"
#include "xe_trace.h"
#include "xe_vm.h"
#include "xe_pxp.h"
@@ -84,9 +82,8 @@
* group is destroyed. The secondary queues hold a reference to the primary
* queue thus preventing the group from being destroyed when user destroys
* the primary queue. Once the primary queue is destroyed, secondary queues
- * can't be added to the queue group, but they can continue to submit the
- * jobs if the DRM_XE_MULTI_GROUP_KEEP_ACTIVE flag is set during the multi
- * queue group creation.
+ * can't be added to the queue group and new job submissions on existing
+ * secondary queues are not allowed.
*
* The queues of a multi queue group can set their priority within the group
* through the DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY property.
@@ -467,26 +464,6 @@ struct xe_exec_queue *xe_exec_queue_create_bind(struct xe_device *xe,
}
ALLOW_ERROR_INJECTION(xe_exec_queue_create_bind, ERRNO);
-static void xe_exec_queue_group_kill(struct kref *ref)
-{
- struct xe_exec_queue_group *group = container_of(ref, struct xe_exec_queue_group,
- kill_refcount);
- xe_exec_queue_kill(group->primary);
-}
-
-static inline void xe_exec_queue_group_kill_get(struct xe_exec_queue_group *group)
-{
- kref_get(&group->kill_refcount);
-}
-
-void xe_exec_queue_group_kill_put(struct xe_exec_queue_group *group)
-{
- if (!group)
- return;
-
- kref_put(&group->kill_refcount, xe_exec_queue_group_kill);
-}
-
void xe_exec_queue_destroy(struct kref *ref)
{
struct xe_exec_queue *q = container_of(ref, struct xe_exec_queue, refcount);
@@ -716,7 +693,6 @@ static int xe_exec_queue_group_init(struct xe_device *xe, struct xe_exec_queue *
group->primary = q;
group->cgp_bo = bo;
INIT_LIST_HEAD(&group->list);
- kref_init(&group->kill_refcount);
xa_init_flags(&group->xa, XA_FLAGS_ALLOC1);
mutex_init(&group->list_lock);
q->multi_queue.group = group;
@@ -792,11 +768,6 @@ static int xe_exec_queue_group_add(struct xe_device *xe, struct xe_exec_queue *q
q->multi_queue.pos = pos;
- if (group->primary->multi_queue.keep_active) {
- xe_exec_queue_group_kill_get(group);
- q->multi_queue.keep_active = true;
- }
-
return 0;
}
@@ -810,11 +781,6 @@ static void xe_exec_queue_group_delete(struct xe_device *xe, struct xe_exec_queu
lrc = xa_erase(&group->xa, q->multi_queue.pos);
xe_assert(xe, lrc);
xe_lrc_put(lrc);
-
- if (q->multi_queue.keep_active) {
- xe_exec_queue_group_kill_put(group);
- q->multi_queue.keep_active = false;
- }
}
static int exec_queue_set_multi_group(struct xe_device *xe, struct xe_exec_queue *q,
@@ -836,24 +802,12 @@ static int exec_queue_set_multi_group(struct xe_device *xe, struct xe_exec_queue
return -EINVAL;
if (value & DRM_XE_MULTI_GROUP_CREATE) {
- if (XE_IOCTL_DBG(xe, value & ~(DRM_XE_MULTI_GROUP_CREATE |
- DRM_XE_MULTI_GROUP_KEEP_ACTIVE)))
- return -EINVAL;
-
- /*
- * KEEP_ACTIVE is not supported in preempt fence mode as in that mode,
- * VM_DESTROY ioctl expects all exec queues of that VM are already killed.
- */
- if (XE_IOCTL_DBG(xe, (value & DRM_XE_MULTI_GROUP_KEEP_ACTIVE) &&
- xe_vm_in_preempt_fence_mode(q->vm)))
+ if (XE_IOCTL_DBG(xe, value & ~DRM_XE_MULTI_GROUP_CREATE))
return -EINVAL;
q->multi_queue.valid = true;
q->multi_queue.is_primary = true;
q->multi_queue.pos = 0;
- if (value & DRM_XE_MULTI_GROUP_KEEP_ACTIVE)
- q->multi_queue.keep_active = true;
-
return 0;
}
@@ -1419,11 +1373,6 @@ void xe_exec_queue_kill(struct xe_exec_queue *q)
q->ops->kill(q);
xe_vm_remove_compute_exec_queue(q->vm, q);
-
- if (!xe_exec_queue_is_multi_queue_primary(q) && q->multi_queue.keep_active) {
- xe_exec_queue_group_kill_put(q->multi_queue.group);
- q->multi_queue.keep_active = false;
- }
}
int xe_exec_queue_destroy_ioctl(struct drm_device *dev, void *data,
@@ -1450,10 +1399,7 @@ int xe_exec_queue_destroy_ioctl(struct drm_device *dev, void *data,
if (q->vm && q->hwe->hw_engine_group)
xe_hw_engine_group_del_exec_queue(q->hwe->hw_engine_group, q);
- if (xe_exec_queue_is_multi_queue_primary(q))
- xe_exec_queue_group_kill_put(q->multi_queue.group);
- else
- xe_exec_queue_kill(q);
+ xe_exec_queue_kill(q);
trace_xe_exec_queue_close(q);
xe_exec_queue_put(q);
diff --git a/drivers/gpu/drm/xe/xe_exec_queue.h b/drivers/gpu/drm/xe/xe_exec_queue.h
index b5ad975d7e97..b1e51789128f 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue.h
+++ b/drivers/gpu/drm/xe/xe_exec_queue.h
@@ -113,8 +113,6 @@ static inline struct xe_exec_queue *xe_exec_queue_multi_queue_primary(struct xe_
return xe_exec_queue_is_multi_queue(q) ? q->multi_queue.group->primary : q;
}
-void xe_exec_queue_group_kill_put(struct xe_exec_queue_group *group);
-
bool xe_exec_queue_is_lr(struct xe_exec_queue *q);
bool xe_exec_queue_is_idle(struct xe_exec_queue *q);
diff --git a/drivers/gpu/drm/xe/xe_exec_queue_types.h b/drivers/gpu/drm/xe/xe_exec_queue_types.h
index 67ea5eebf70b..5fc516b0bb77 100644
--- a/drivers/gpu/drm/xe/xe_exec_queue_types.h
+++ b/drivers/gpu/drm/xe/xe_exec_queue_types.h
@@ -62,8 +62,6 @@ struct xe_exec_queue_group {
struct list_head list;
/** @list_lock: Secondary queue list lock */
struct mutex list_lock;
- /** @kill_refcount: ref count to kill primary queue */
- struct kref kill_refcount;
/** @sync_pending: CGP_SYNC_DONE g2h response pending */
bool sync_pending;
/** @banned: Group banned */
@@ -163,8 +161,6 @@ struct xe_exec_queue {
u8 valid:1;
/** @multi_queue.is_primary: Is primary queue (Q0) of the group */
u8 is_primary:1;
- /** @multi_queue.keep_active: Keep the group active after primary is destroyed */
- u8 keep_active:1;
} multi_queue;
/** @sched_props: scheduling properties */
diff --git a/drivers/gpu/drm/xe/xe_execlist.c b/drivers/gpu/drm/xe/xe_execlist.c
index 46c17a18a3f4..8bf330aeaec0 100644
--- a/drivers/gpu/drm/xe/xe_execlist.c
+++ b/drivers/gpu/drm/xe/xe_execlist.c
@@ -15,8 +15,7 @@
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_exec_queue.h"
-#include "xe_gt.h"
-#include "xe_hw_fence.h"
+#include "xe_gt_types.h"
#include "xe_irq.h"
#include "xe_lrc.h"
#include "xe_macros.h"
diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c
index 48ab8b43fcd0..60665ad1415b 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.c
+++ b/drivers/gpu/drm/xe/xe_ggtt.c
@@ -20,9 +20,8 @@
#include "regs/xe_regs.h"
#include "xe_assert.h"
#include "xe_bo.h"
-#include "xe_device.h"
-#include "xe_gt.h"
#include "xe_gt_printk.h"
+#include "xe_gt_types.h"
#include "xe_map.h"
#include "xe_mmio.h"
#include "xe_pm.h"
@@ -67,6 +66,24 @@
* give us the correct placement for free.
*/
+/**
+ * struct xe_ggtt_node - A node in GGTT.
+ *
+ * This struct needs to be initialized (only-once) with xe_ggtt_node_init() before any node
+ * insertion, reservation, or 'ballooning'.
+ * It will, then, be finalized by either xe_ggtt_node_remove() or xe_ggtt_node_deballoon().
+ */
+struct xe_ggtt_node {
+ /** @ggtt: Back pointer to xe_ggtt where this region will be inserted at */
+ struct xe_ggtt *ggtt;
+ /** @base: A drm_mm_node */
+ struct drm_mm_node base;
+ /** @delayed_removal_work: The work struct for the delayed removal */
+ struct work_struct delayed_removal_work;
+ /** @invalidate_on_remove: If it needs invalidation upon removal */
+ bool invalidate_on_remove;
+};
+
static u64 xelp_ggtt_pte_flags(struct xe_bo *bo, u16 pat_index)
{
u64 pte = XE_PAGE_PRESENT;
@@ -137,10 +154,32 @@ static void ggtt_update_access_counter(struct xe_ggtt *ggtt)
}
}
+/**
+ * xe_ggtt_start - Get starting offset of GGTT.
+ * @ggtt: &xe_ggtt
+ *
+ * Returns: Starting offset for this &xe_ggtt.
+ */
+u64 xe_ggtt_start(struct xe_ggtt *ggtt)
+{
+ return ggtt->start;
+}
+
+/**
+ * xe_ggtt_size - Get size of GGTT.
+ * @ggtt: &xe_ggtt
+ *
+ * Returns: Total usable size of this &xe_ggtt.
+ */
+u64 xe_ggtt_size(struct xe_ggtt *ggtt)
+{
+ return ggtt->size;
+}
+
static void xe_ggtt_set_pte(struct xe_ggtt *ggtt, u64 addr, u64 pte)
{
xe_tile_assert(ggtt->tile, !(addr & XE_PTE_MASK));
- xe_tile_assert(ggtt->tile, addr < ggtt->size);
+ xe_tile_assert(ggtt->tile, addr < ggtt->start + ggtt->size);
writeq(pte, &ggtt->gsm[addr >> XE_PTE_SHIFT]);
}
@@ -256,16 +295,16 @@ static const struct xe_ggtt_pt_ops xelpg_pt_wa_ops = {
.ggtt_get_pte = xe_ggtt_get_pte,
};
-static void __xe_ggtt_init_early(struct xe_ggtt *ggtt, u32 reserved)
+static void __xe_ggtt_init_early(struct xe_ggtt *ggtt, u64 start, u64 size)
{
- drm_mm_init(&ggtt->mm, reserved,
- ggtt->size - reserved);
+ ggtt->start = start;
+ ggtt->size = size;
+ drm_mm_init(&ggtt->mm, start, size);
}
-int xe_ggtt_init_kunit(struct xe_ggtt *ggtt, u32 reserved, u32 size)
+int xe_ggtt_init_kunit(struct xe_ggtt *ggtt, u32 start, u32 size)
{
- ggtt->size = size;
- __xe_ggtt_init_early(ggtt, reserved);
+ __xe_ggtt_init_early(ggtt, start, size);
return 0;
}
EXPORT_SYMBOL_IF_KUNIT(xe_ggtt_init_kunit);
@@ -293,26 +332,32 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt)
struct xe_device *xe = tile_to_xe(ggtt->tile);
struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
unsigned int gsm_size;
+ u64 ggtt_start, wopcm = xe_wopcm_size(xe), ggtt_size;
int err;
- if (IS_SRIOV_VF(xe) || GRAPHICS_VERx100(xe) >= 1250)
- gsm_size = SZ_8M; /* GGTT is expected to be 4GiB */
- else
- gsm_size = probe_gsm_size(pdev);
-
- if (gsm_size == 0) {
- xe_tile_err(ggtt->tile, "Hardware reported no preallocated GSM\n");
- return -ENOMEM;
+ if (!IS_SRIOV_VF(xe)) {
+ if (GRAPHICS_VERx100(xe) >= 1250)
+ gsm_size = SZ_8M; /* GGTT is expected to be 4GiB */
+ else
+ gsm_size = probe_gsm_size(pdev);
+ if (gsm_size == 0) {
+ xe_tile_err(ggtt->tile, "Hardware reported no preallocated GSM\n");
+ return -ENOMEM;
+ }
+ ggtt_start = wopcm;
+ ggtt_size = (gsm_size / 8) * (u64)XE_PAGE_SIZE - ggtt_start;
+ } else {
+ /* GGTT is expected to be 4GiB */
+ ggtt_start = wopcm;
+ ggtt_size = SZ_4G - ggtt_start;
}
ggtt->gsm = ggtt->tile->mmio.regs + SZ_8M;
- ggtt->size = (gsm_size / 8) * (u64) XE_PAGE_SIZE;
-
if (IS_DGFX(xe) && xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K)
ggtt->flags |= XE_GGTT_FLAGS_64K;
- if (ggtt->size > GUC_GGTT_TOP)
- ggtt->size = GUC_GGTT_TOP;
+ if (ggtt_size + ggtt_start > GUC_GGTT_TOP)
+ ggtt_size = GUC_GGTT_TOP - ggtt_start;
if (GRAPHICS_VERx100(xe) >= 1270)
ggtt->pt_ops =
@@ -322,11 +367,11 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt)
else
ggtt->pt_ops = &xelp_pt_ops;
- ggtt->wq = alloc_workqueue("xe-ggtt-wq", 0, WQ_MEM_RECLAIM);
+ ggtt->wq = alloc_workqueue("xe-ggtt-wq", WQ_MEM_RECLAIM, 0);
if (!ggtt->wq)
return -ENOMEM;
- __xe_ggtt_init_early(ggtt, xe_wopcm_size(xe));
+ __xe_ggtt_init_early(ggtt, ggtt_start, ggtt_size);
err = drmm_add_action_or_reset(&xe->drm, ggtt_fini_early, ggtt);
if (err)
@@ -563,11 +608,9 @@ void xe_ggtt_node_remove_balloon_locked(struct xe_ggtt_node *node)
static void xe_ggtt_assert_fit(struct xe_ggtt *ggtt, u64 start, u64 size)
{
struct xe_tile *tile = ggtt->tile;
- struct xe_device *xe = tile_to_xe(tile);
- u64 __maybe_unused wopcm = xe_wopcm_size(xe);
- xe_tile_assert(tile, start >= wopcm);
- xe_tile_assert(tile, start + size < ggtt->size - wopcm);
+ xe_tile_assert(tile, start >= ggtt->start);
+ xe_tile_assert(tile, start + size <= ggtt->start + ggtt->size);
}
/**
@@ -610,20 +653,8 @@ void xe_ggtt_shift_nodes_locked(struct xe_ggtt *ggtt, s64 shift)
}
}
-/**
- * xe_ggtt_node_insert_locked - Locked version to insert a &xe_ggtt_node into the GGTT
- * @node: the &xe_ggtt_node to be inserted
- * @size: size of the node
- * @align: alignment constrain of the node
- * @mm_flags: flags to control the node behavior
- *
- * It cannot be called without first having called xe_ggtt_init() once.
- * To be used in cases where ggtt->lock is already taken.
- *
- * Return: 0 on success or a negative error code on failure.
- */
-int xe_ggtt_node_insert_locked(struct xe_ggtt_node *node,
- u32 size, u32 align, u32 mm_flags)
+static int xe_ggtt_node_insert_locked(struct xe_ggtt_node *node,
+ u32 size, u32 align, u32 mm_flags)
{
return drm_mm_insert_node_generic(&node->ggtt->mm, &node->base, size, align, 0,
mm_flags);
@@ -661,9 +692,11 @@ int xe_ggtt_node_insert(struct xe_ggtt_node *node, u32 size, u32 align)
* This function will allocate the struct %xe_ggtt_node and return its pointer.
* This struct will then be freed after the node removal upon xe_ggtt_node_remove()
* or xe_ggtt_node_remove_balloon_locked().
- * Having %xe_ggtt_node struct allocated doesn't mean that the node is already allocated
- * in GGTT. Only the xe_ggtt_node_insert(), xe_ggtt_node_insert_locked(),
- * xe_ggtt_node_insert_balloon_locked() will ensure the node is inserted or reserved in GGTT.
+ *
+ * Having %xe_ggtt_node struct allocated doesn't mean that the node is already
+ * allocated in GGTT. Only xe_ggtt_node_insert(), allocation through
+ * xe_ggtt_node_insert_transform(), or xe_ggtt_node_insert_balloon_locked() will ensure the node is inserted or reserved
+ * in GGTT.
*
* Return: A pointer to %xe_ggtt_node struct on success. An ERR_PTR otherwise.
**/
@@ -726,13 +759,12 @@ size_t xe_ggtt_node_pt_size(const struct xe_ggtt_node *node)
* @ggtt: the &xe_ggtt where node will be mapped
* @node: the &xe_ggtt_node where this BO is mapped
* @bo: the &xe_bo to be mapped
- * @pat_index: Which pat_index to use.
+ * @pte: The pte flags to append.
*/
-void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
- struct xe_bo *bo, u16 pat_index)
+static void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
+ struct xe_bo *bo, u64 pte)
{
-
- u64 start, pte, end;
+ u64 start, end;
struct xe_res_cursor cur;
if (XE_WARN_ON(!node))
@@ -741,7 +773,6 @@ void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
start = node->base.start;
end = start + xe_bo_size(bo);
- pte = ggtt->pt_ops->pte_encode_flags(bo, pat_index);
if (!xe_bo_is_vram(bo) && !xe_bo_is_stolen(bo)) {
xe_assert(xe_bo_device(bo), bo->ttm.ttm);
@@ -771,12 +802,65 @@ 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];
+ u64 pte;
mutex_lock(&ggtt->lock);
- xe_ggtt_map_bo(ggtt, bo->ggtt_node[ggtt->tile->id], bo, pat_index);
+ pte = ggtt->pt_ops->pte_encode_flags(bo, pat_index);
+ xe_ggtt_map_bo(ggtt, bo->ggtt_node[ggtt->tile->id], bo, pte);
mutex_unlock(&ggtt->lock);
}
+/**
+ * xe_ggtt_node_insert_transform - Insert a newly allocated &xe_ggtt_node into the GGTT
+ * @ggtt: the &xe_ggtt where the node will inserted/reserved.
+ * @bo: The bo to be transformed
+ * @pte_flags: The extra GGTT flags to add to mapping.
+ * @size: size of the node
+ * @align: required alignment for node
+ * @transform: transformation function that will populate the GGTT node, or NULL for linear mapping.
+ * @arg: Extra argument to pass to the transformation function.
+ *
+ * This function allows inserting a GGTT node with a custom transformation function.
+ * This is useful for display to allow inserting rotated framebuffers to GGTT.
+ *
+ * Return: A pointer to %xe_ggtt_node struct on success. An ERR_PTR otherwise.
+ */
+struct xe_ggtt_node *xe_ggtt_node_insert_transform(struct xe_ggtt *ggtt,
+ struct xe_bo *bo, u64 pte_flags,
+ u64 size, u32 align,
+ xe_ggtt_transform_cb transform, void *arg)
+{
+ struct xe_ggtt_node *node;
+ int ret;
+
+ node = xe_ggtt_node_init(ggtt);
+ if (IS_ERR(node))
+ return ERR_CAST(node);
+
+ if (mutex_lock_interruptible(&ggtt->lock) < 0) {
+ ret = -ERESTARTSYS;
+ goto err;
+ }
+
+ ret = xe_ggtt_node_insert_locked(node, size, align, 0);
+ if (ret)
+ goto err_unlock;
+
+ if (transform)
+ transform(ggtt, node, pte_flags, ggtt->pt_ops->ggtt_set_pte, arg);
+ else
+ xe_ggtt_map_bo(ggtt, node, bo, pte_flags);
+
+ mutex_unlock(&ggtt->lock);
+ return node;
+
+err_unlock:
+ mutex_unlock(&ggtt->lock);
+err:
+ xe_ggtt_node_fini(node);
+ return ERR_PTR(ret);
+}
+
static int __xe_ggtt_insert_bo_at(struct xe_ggtt *ggtt, struct xe_bo *bo,
u64 start, u64 end, struct drm_exec *exec)
{
@@ -815,8 +899,9 @@ static int __xe_ggtt_insert_bo_at(struct xe_ggtt *ggtt, struct xe_bo *bo,
} 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];
+ u64 pte = ggtt->pt_ops->pte_encode_flags(bo, pat_index);
- xe_ggtt_map_bo(ggtt, bo->ggtt_node[tile_id], bo, pat_index);
+ xe_ggtt_map_bo(ggtt, bo->ggtt_node[tile_id], bo, pte);
}
mutex_unlock(&ggtt->lock);
@@ -890,14 +975,12 @@ u64 xe_ggtt_largest_hole(struct xe_ggtt *ggtt, u64 alignment, u64 *spare)
{
const struct drm_mm *mm = &ggtt->mm;
const struct drm_mm_node *entry;
- u64 hole_min_start = xe_wopcm_size(tile_to_xe(ggtt->tile));
u64 hole_start, hole_end, hole_size;
u64 max_hole = 0;
mutex_lock(&ggtt->lock);
-
drm_mm_for_each_hole(entry, mm, hole_start, hole_end) {
- hole_start = max(hole_start, hole_min_start);
+ hole_start = max(hole_start, ggtt->start);
hole_start = ALIGN(hole_start, alignment);
hole_end = ALIGN_DOWN(hole_end, alignment);
if (hole_start >= hole_end)
@@ -1069,15 +1152,13 @@ u64 xe_ggtt_print_holes(struct xe_ggtt *ggtt, u64 alignment, struct drm_printer
{
const struct drm_mm *mm = &ggtt->mm;
const struct drm_mm_node *entry;
- u64 hole_min_start = xe_wopcm_size(tile_to_xe(ggtt->tile));
u64 hole_start, hole_end, hole_size;
u64 total = 0;
char buf[10];
mutex_lock(&ggtt->lock);
-
drm_mm_for_each_hole(entry, mm, hole_start, hole_end) {
- hole_start = max(hole_start, hole_min_start);
+ hole_start = max(hole_start, ggtt->start);
hole_start = ALIGN(hole_start, alignment);
hole_end = ALIGN_DOWN(hole_end, alignment);
if (hole_start >= hole_end)
@@ -1121,3 +1202,25 @@ u64 xe_ggtt_read_pte(struct xe_ggtt *ggtt, u64 offset)
{
return ioread64(ggtt->gsm + (offset / XE_PAGE_SIZE));
}
+
+/**
+ * xe_ggtt_node_addr - Get @node offset in GGTT.
+ * @node: &xe_ggtt_node
+ *
+ * Get the GGTT offset for allocated node.
+ */
+u64 xe_ggtt_node_addr(const struct xe_ggtt_node *node)
+{
+ return node->base.start;
+}
+
+/**
+ * xe_ggtt_node_size - Get @node allocation size.
+ * @node: &xe_ggtt_node
+ *
+ * Get the allocated node's size.
+ */
+u64 xe_ggtt_node_size(const struct xe_ggtt_node *node)
+{
+ return node->base.size;
+}
diff --git a/drivers/gpu/drm/xe/xe_ggtt.h b/drivers/gpu/drm/xe/xe_ggtt.h
index 93fea4b6079c..70d5e07ac4b6 100644
--- a/drivers/gpu/drm/xe/xe_ggtt.h
+++ b/drivers/gpu/drm/xe/xe_ggtt.h
@@ -23,15 +23,18 @@ int xe_ggtt_node_insert_balloon_locked(struct xe_ggtt_node *node,
u64 start, u64 size);
void xe_ggtt_node_remove_balloon_locked(struct xe_ggtt_node *node);
void xe_ggtt_shift_nodes_locked(struct xe_ggtt *ggtt, s64 shift);
+u64 xe_ggtt_start(struct xe_ggtt *ggtt);
+u64 xe_ggtt_size(struct xe_ggtt *ggtt);
int xe_ggtt_node_insert(struct xe_ggtt_node *node, u32 size, u32 align);
-int xe_ggtt_node_insert_locked(struct xe_ggtt_node *node,
- u32 size, u32 align, u32 mm_flags);
+struct xe_ggtt_node *
+xe_ggtt_node_insert_transform(struct xe_ggtt *ggtt,
+ struct xe_bo *bo, u64 pte,
+ u64 size, u32 align,
+ xe_ggtt_transform_cb transform, void *arg);
void xe_ggtt_node_remove(struct xe_ggtt_node *node, bool invalidate);
bool xe_ggtt_node_allocated(const struct xe_ggtt_node *node);
size_t xe_ggtt_node_pt_size(const struct xe_ggtt_node *node);
-void xe_ggtt_map_bo(struct xe_ggtt *ggtt, struct xe_ggtt_node *node,
- struct xe_bo *bo, u16 pat_index);
void xe_ggtt_map_bo_unlocked(struct xe_ggtt *ggtt, struct xe_bo *bo);
int xe_ggtt_insert_bo(struct xe_ggtt *ggtt, struct xe_bo *bo, struct drm_exec *exec);
int xe_ggtt_insert_bo_at(struct xe_ggtt *ggtt, struct xe_bo *bo,
@@ -58,4 +61,7 @@ void xe_ggtt_might_lock(struct xe_ggtt *ggtt);
u64 xe_ggtt_encode_pte_flags(struct xe_ggtt *ggtt, struct xe_bo *bo, u16 pat_index);
u64 xe_ggtt_read_pte(struct xe_ggtt *ggtt, u64 offset);
+u64 xe_ggtt_node_addr(const struct xe_ggtt_node *node);
+u64 xe_ggtt_node_size(const struct xe_ggtt_node *node);
+
#endif
diff --git a/drivers/gpu/drm/xe/xe_ggtt_types.h b/drivers/gpu/drm/xe/xe_ggtt_types.h
index dacd796f8184..d82b71a198bc 100644
--- a/drivers/gpu/drm/xe/xe_ggtt_types.h
+++ b/drivers/gpu/drm/xe/xe_ggtt_types.h
@@ -11,6 +11,7 @@
#include "xe_pt_types.h"
struct xe_bo;
+struct xe_ggtt_node;
struct xe_gt;
/**
@@ -22,7 +23,9 @@ struct xe_gt;
struct xe_ggtt {
/** @tile: Back pointer to tile where this GGTT belongs */
struct xe_tile *tile;
- /** @size: Total size of this GGTT */
+ /** @start: Start offset of GGTT */
+ u64 start;
+ /** @size: Total usable size of this GGTT */
u64 size;
#define XE_GGTT_FLAGS_64K BIT(0)
@@ -51,24 +54,11 @@ struct xe_ggtt {
struct workqueue_struct *wq;
};
-/**
- * struct xe_ggtt_node - A node in GGTT.
- *
- * This struct needs to be initialized (only-once) with xe_ggtt_node_init() before any node
- * insertion, reservation, or 'ballooning'.
- * It will, then, be finalized by either xe_ggtt_node_remove() or xe_ggtt_node_deballoon().
- */
-struct xe_ggtt_node {
- /** @ggtt: Back pointer to xe_ggtt where this region will be inserted at */
- struct xe_ggtt *ggtt;
- /** @base: A drm_mm_node */
- struct drm_mm_node base;
- /** @delayed_removal_work: The work struct for the delayed removal */
- struct work_struct delayed_removal_work;
- /** @invalidate_on_remove: If it needs invalidation upon removal */
- bool invalidate_on_remove;
-};
-
+typedef void (*xe_ggtt_set_pte_fn)(struct xe_ggtt *ggtt, u64 addr, u64 pte);
+typedef void (*xe_ggtt_transform_cb)(struct xe_ggtt *ggtt,
+ struct xe_ggtt_node *node,
+ u64 pte_flags,
+ xe_ggtt_set_pte_fn set_pte, void *arg);
/**
* struct xe_ggtt_pt_ops - GGTT Page table operations
* Which can vary from platform to platform.
@@ -76,8 +66,10 @@ struct xe_ggtt_node {
struct xe_ggtt_pt_ops {
/** @pte_encode_flags: Encode PTE flags for a given BO */
u64 (*pte_encode_flags)(struct xe_bo *bo, u16 pat_index);
+
/** @ggtt_set_pte: Directly write into GGTT's PTE */
- void (*ggtt_set_pte)(struct xe_ggtt *ggtt, u64 addr, u64 pte);
+ xe_ggtt_set_pte_fn ggtt_set_pte;
+
/** @ggtt_get_pte: Directly read from GGTT's PTE */
u64 (*ggtt_get_pte)(struct xe_ggtt *ggtt, u64 addr);
};
diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.c b/drivers/gpu/drm/xe/xe_gpu_scheduler.c
index f91e06d03511..9c8004d5dd91 100644
--- a/drivers/gpu/drm/xe/xe_gpu_scheduler.c
+++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.c
@@ -7,7 +7,7 @@
static void xe_sched_process_msg_queue(struct xe_gpu_scheduler *sched)
{
- if (!READ_ONCE(sched->base.pause_submit))
+ if (!drm_sched_is_stopped(&sched->base))
queue_work(sched->base.submit_wq, &sched->work_process_msg);
}
@@ -43,7 +43,7 @@ static void xe_sched_process_msg_work(struct work_struct *w)
container_of(w, struct xe_gpu_scheduler, work_process_msg);
struct xe_sched_msg *msg;
- if (READ_ONCE(sched->base.pause_submit))
+ if (drm_sched_is_stopped(&sched->base))
return;
msg = xe_sched_get_msg(sched);
@@ -77,6 +77,7 @@ int xe_sched_init(struct xe_gpu_scheduler *sched,
};
sched->ops = xe_ops;
+ spin_lock_init(&sched->msg_lock);
INIT_LIST_HEAD(&sched->msgs);
INIT_WORK(&sched->work_process_msg, xe_sched_process_msg_work);
@@ -117,7 +118,7 @@ void xe_sched_add_msg(struct xe_gpu_scheduler *sched,
void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched,
struct xe_sched_msg *msg)
{
- lockdep_assert_held(&sched->base.job_list_lock);
+ lockdep_assert_held(&sched->msg_lock);
list_add_tail(&msg->link, &sched->msgs);
xe_sched_process_msg_queue(sched);
@@ -131,7 +132,7 @@ void xe_sched_add_msg_locked(struct xe_gpu_scheduler *sched,
void xe_sched_add_msg_head(struct xe_gpu_scheduler *sched,
struct xe_sched_msg *msg)
{
- lockdep_assert_held(&sched->base.job_list_lock);
+ lockdep_assert_held(&sched->msg_lock);
list_add(&msg->link, &sched->msgs);
xe_sched_process_msg_queue(sched);
diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler.h b/drivers/gpu/drm/xe/xe_gpu_scheduler.h
index c7a77a3a9681..664c2db56af3 100644
--- a/drivers/gpu/drm/xe/xe_gpu_scheduler.h
+++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.h
@@ -33,12 +33,12 @@ void xe_sched_add_msg_head(struct xe_gpu_scheduler *sched,
static inline void xe_sched_msg_lock(struct xe_gpu_scheduler *sched)
{
- spin_lock(&sched->base.job_list_lock);
+ spin_lock(&sched->msg_lock);
}
static inline void xe_sched_msg_unlock(struct xe_gpu_scheduler *sched)
{
- spin_unlock(&sched->base.job_list_lock);
+ spin_unlock(&sched->msg_lock);
}
static inline void xe_sched_stop(struct xe_gpu_scheduler *sched)
@@ -56,12 +56,9 @@ static inline void xe_sched_resubmit_jobs(struct xe_gpu_scheduler *sched)
struct drm_sched_job *s_job;
bool restore_replay = false;
- list_for_each_entry(s_job, &sched->base.pending_list, list) {
- struct drm_sched_fence *s_fence = s_job->s_fence;
- struct dma_fence *hw_fence = s_fence->parent;
-
+ drm_sched_for_each_pending_job(s_job, &sched->base, NULL) {
restore_replay |= to_xe_sched_job(s_job)->restore_replay;
- if (restore_replay || (hw_fence && !dma_fence_is_signaled(hw_fence)))
+ if (restore_replay || !drm_sched_job_is_signaled(s_job))
sched->base.ops->run_job(s_job);
}
}
@@ -72,14 +69,6 @@ xe_sched_invalidate_job(struct xe_sched_job *job, int threshold)
return drm_sched_invalidate_job(&job->drm, threshold);
}
-static inline void xe_sched_add_pending_job(struct xe_gpu_scheduler *sched,
- struct xe_sched_job *job)
-{
- spin_lock(&sched->base.job_list_lock);
- list_add(&job->drm.list, &sched->base.pending_list);
- spin_unlock(&sched->base.job_list_lock);
-}
-
/**
* xe_sched_first_pending_job() - Find first pending job which is unsignaled
* @sched: Xe GPU scheduler
@@ -89,21 +78,13 @@ static inline void xe_sched_add_pending_job(struct xe_gpu_scheduler *sched,
static inline
struct xe_sched_job *xe_sched_first_pending_job(struct xe_gpu_scheduler *sched)
{
- struct xe_sched_job *job, *r_job = NULL;
-
- spin_lock(&sched->base.job_list_lock);
- list_for_each_entry(job, &sched->base.pending_list, drm.list) {
- struct drm_sched_fence *s_fence = job->drm.s_fence;
- struct dma_fence *hw_fence = s_fence->parent;
+ struct drm_sched_job *job;
- if (hw_fence && !dma_fence_is_signaled(hw_fence)) {
- r_job = job;
- break;
- }
- }
- spin_unlock(&sched->base.job_list_lock);
+ drm_sched_for_each_pending_job(job, &sched->base, NULL)
+ if (!drm_sched_job_is_signaled(job))
+ return to_xe_sched_job(job);
- return r_job;
+ return NULL;
}
static inline int
diff --git a/drivers/gpu/drm/xe/xe_gpu_scheduler_types.h b/drivers/gpu/drm/xe/xe_gpu_scheduler_types.h
index 6731b13da8bb..63d9bf92583c 100644
--- a/drivers/gpu/drm/xe/xe_gpu_scheduler_types.h
+++ b/drivers/gpu/drm/xe/xe_gpu_scheduler_types.h
@@ -47,6 +47,8 @@ struct xe_gpu_scheduler {
const struct xe_sched_backend_ops *ops;
/** @msgs: list of messages to be processed in @work_process_msg */
struct list_head msgs;
+ /** @msg_lock: Message lock */
+ spinlock_t msg_lock;
/** @work_process_msg: processes messages */
struct work_struct work_process_msg;
};
diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c
index a3157b0fe791..e5c234f3d795 100644
--- a/drivers/gpu/drm/xe/xe_gsc.c
+++ b/drivers/gpu/drm/xe/xe_gsc.c
@@ -414,15 +414,16 @@ int xe_gsc_init(struct xe_gsc *gsc)
}
/*
- * Some platforms can have GuC but not GSC. That would cause
- * xe_uc_fw_init(gsc) to return a "not supported" failure code and abort
- * all firmware loading. So check for GSC being enabled before
- * propagating the failure back up. That way the higher level will keep
- * going and load GuC as appropriate.
+ * Starting from BMG the GSC is no longer needed for MC6 entry, so the
+ * only missing features if the FW is lacking would be the content
+ * protection ones. This is acceptable, so we allow the driver load to
+ * continue if the GSC FW is missing.
*/
ret = xe_uc_fw_init(&gsc->fw);
if (!xe_uc_fw_is_enabled(&gsc->fw))
return 0;
+ else if (gt_to_xe(gt)->info.platform >= XE_BATTLEMAGE && !xe_uc_fw_is_available(&gsc->fw))
+ return 0;
else if (ret)
goto out;
@@ -614,7 +615,7 @@ void xe_gsc_print_info(struct xe_gsc *gsc, struct drm_printer *p)
drm_printf(p, "\tfound security version %u\n", gsc->security_version);
- if (!xe_uc_fw_is_enabled(&gsc->fw))
+ if (!xe_uc_fw_is_available(&gsc->fw))
return;
CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GSC);
diff --git a/drivers/gpu/drm/xe/xe_gsc_debugfs.c b/drivers/gpu/drm/xe/xe_gsc_debugfs.c
index b13928b50eb9..d4977e666946 100644
--- a/drivers/gpu/drm/xe/xe_gsc_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_gsc_debugfs.c
@@ -7,11 +7,10 @@
#include <drm/drm_debugfs.h>
#include <drm/drm_managed.h>
+#include <drm/drm_print.h>
-#include "xe_device.h"
-#include "xe_gt.h"
+#include "xe_gt_types.h"
#include "xe_gsc.h"
-#include "xe_macros.h"
#include "xe_pm.h"
static struct xe_gt *
diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c b/drivers/gpu/drm/xe/xe_gsc_proxy.c
index e7573a0c5e5d..42438b21f235 100644
--- a/drivers/gpu/drm/xe/xe_gsc_proxy.c
+++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c
@@ -18,8 +18,8 @@
#include "xe_force_wake.h"
#include "xe_gsc.h"
#include "xe_gsc_submit.h"
-#include "xe_gt.h"
#include "xe_gt_printk.h"
+#include "xe_gt_types.h"
#include "xe_map.h"
#include "xe_mmio.h"
#include "xe_pm.h"
diff --git a/drivers/gpu/drm/xe/xe_gsc_submit.c b/drivers/gpu/drm/xe/xe_gsc_submit.c
index 9ede483d37ef..08082b596501 100644
--- a/drivers/gpu/drm/xe/xe_gsc_submit.c
+++ b/drivers/gpu/drm/xe/xe_gsc_submit.c
@@ -11,12 +11,10 @@
#include "xe_assert.h"
#include "xe_bb.h"
#include "xe_exec_queue.h"
-#include "xe_gt_printk.h"
#include "xe_gt_types.h"
#include "xe_map.h"
#include "xe_sched_job.h"
#include "instructions/xe_gsc_commands.h"
-#include "regs/xe_gsc_regs.h"
#define GSC_HDR_SIZE (sizeof(struct intel_gsc_mtl_header)) /* shorthand define */
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
index 313ce83ab0e5..9d090d0f2438 100644
--- a/drivers/gpu/drm/xe/xe_gt.c
+++ b/drivers/gpu/drm/xe/xe_gt.c
@@ -13,13 +13,11 @@
#include <generated/xe_wa_oob.h>
#include "instructions/xe_alu_commands.h"
-#include "instructions/xe_gfxpipe_commands.h"
#include "instructions/xe_mi_commands.h"
#include "regs/xe_engine_regs.h"
#include "regs/xe_gt_regs.h"
#include "xe_assert.h"
#include "xe_bb.h"
-#include "xe_bo.h"
#include "xe_device.h"
#include "xe_eu_stall.h"
#include "xe_exec_queue.h"
@@ -140,6 +138,36 @@ static void xe_gt_disable_host_l2_vram(struct xe_gt *gt)
xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg);
}
+static void xe_gt_enable_comp_1wcoh(struct xe_gt *gt)
+{
+ struct xe_device *xe = gt_to_xe(gt);
+ unsigned int fw_ref;
+ u32 reg;
+
+ if (IS_SRIOV_VF(xe))
+ return;
+
+ if (GRAPHICS_VER(xe) >= 30 && xe->info.has_flat_ccs) {
+ fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
+ if (!fw_ref)
+ return;
+
+ reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMREQSTRM_CTRL);
+ reg |= EN_CMP_1WCOH;
+ xe_gt_mcr_multicast_write(gt, XE2_GAMREQSTRM_CTRL, reg);
+
+ if (xe_gt_is_media_type(gt)) {
+ xe_mmio_rmw32(&gt->mmio, XE2_GAMWALK_CTRL_MEDIA, 0, EN_CMP_1WCOH_GW);
+ } else {
+ reg = xe_gt_mcr_unicast_read_any(gt, XE2_GAMWALK_CTRL_3D);
+ reg |= EN_CMP_1WCOH_GW;
+ xe_gt_mcr_multicast_write(gt, XE2_GAMWALK_CTRL_3D, reg);
+ }
+
+ xe_force_wake_put(gt_to_fw(gt), fw_ref);
+ }
+}
+
static void gt_reset_worker(struct work_struct *w);
static int emit_job_sync(struct xe_exec_queue *q, struct xe_bb *bb,
@@ -466,6 +494,7 @@ static int gt_init_with_gt_forcewake(struct xe_gt *gt)
xe_gt_topology_init(gt);
xe_gt_mcr_init(gt);
xe_gt_enable_host_l2_vram(gt);
+ xe_gt_enable_comp_1wcoh(gt);
if (xe_gt_is_main_type(gt)) {
err = xe_ggtt_init(gt_to_tile(gt)->mem.ggtt);
@@ -745,6 +774,7 @@ static int do_gt_restart(struct xe_gt *gt)
xe_pat_init(gt);
xe_gt_enable_host_l2_vram(gt);
+ xe_gt_enable_comp_1wcoh(gt);
xe_gt_mcr_set_implicit_defaults(gt);
xe_reg_sr_apply_mmio(&gt->reg_sr, gt);
diff --git a/drivers/gpu/drm/xe/xe_gt_clock.c b/drivers/gpu/drm/xe/xe_gt_clock.c
index bfc25c46f798..53b3835192da 100644
--- a/drivers/gpu/drm/xe/xe_gt_clock.c
+++ b/drivers/gpu/drm/xe/xe_gt_clock.c
@@ -8,12 +8,8 @@
#include "xe_gt_clock.h"
#include "regs/xe_gt_regs.h"
-#include "regs/xe_regs.h"
-#include "xe_assert.h"
-#include "xe_device.h"
-#include "xe_gt.h"
+#include "xe_gt_types.h"
#include "xe_gt_printk.h"
-#include "xe_macros.h"
#include "xe_mmio.h"
#define f19_2_mhz 19200000
diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c
index e4f38b5150fc..4363bc9c3606 100644
--- a/drivers/gpu/drm/xe/xe_gt_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c
@@ -22,7 +22,6 @@
#include "xe_guc_hwconfig.h"
#include "xe_hw_engine.h"
#include "xe_lrc.h"
-#include "xe_macros.h"
#include "xe_mocs.h"
#include "xe_pat.h"
#include "xe_pm.h"
diff --git a/drivers/gpu/drm/xe/xe_gt_idle.c b/drivers/gpu/drm/xe/xe_gt_idle.c
index c1c9bec3c487..7a569e1730a4 100644
--- a/drivers/gpu/drm/xe/xe_gt_idle.c
+++ b/drivers/gpu/drm/xe/xe_gt_idle.c
@@ -13,7 +13,6 @@
#include "xe_gt_sysfs.h"
#include "xe_guc_pc.h"
#include "regs/xe_gt_regs.h"
-#include "xe_macros.h"
#include "xe_mmio.h"
#include "xe_pm.h"
#include "xe_sriov.h"
diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c
index 164010860664..7c1fe9ac120d 100644
--- a/drivers/gpu/drm/xe/xe_gt_mcr.c
+++ b/drivers/gpu/drm/xe/xe_gt_mcr.c
@@ -7,7 +7,6 @@
#include "regs/xe_gt_regs.h"
#include "xe_assert.h"
-#include "xe_gt.h"
#include "xe_gt_printk.h"
#include "xe_gt_topology.h"
#include "xe_gt_types.h"
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
index 5a870914b102..23601ce79348 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
@@ -24,13 +24,11 @@
#include "xe_guc_buf.h"
#include "xe_guc_ct.h"
#include "xe_guc_db_mgr.h"
-#include "xe_guc_fwif.h"
#include "xe_guc_id_mgr.h"
#include "xe_guc_klv_helpers.h"
#include "xe_guc_klv_thresholds_set.h"
#include "xe_guc_submit.h"
#include "xe_lmtt.h"
-#include "xe_map.h"
#include "xe_migrate.h"
#include "xe_sriov.h"
#include "xe_ttm_vram_mgr.h"
@@ -284,7 +282,7 @@ static u32 encode_config_ggtt(u32 *cfg, const struct xe_gt_sriov_config *config,
if (!xe_ggtt_node_allocated(node))
return 0;
- return encode_ggtt(cfg, node->base.start, node->base.size, details);
+ return encode_ggtt(cfg, xe_ggtt_node_addr(node), xe_ggtt_node_size(node), details);
}
static u32 encode_config_sched(struct xe_gt *gt, u32 *cfg, u32 n,
@@ -393,8 +391,8 @@ static int pf_push_full_vf_config(struct xe_gt *gt, unsigned int vfid)
xe_gt_assert(gt, num_dwords <= max_cfg_dwords);
if (vfid == PFID) {
- u64 ggtt_start = xe_wopcm_size(gt_to_xe(gt));
- u64 ggtt_size = gt_to_tile(gt)->mem.ggtt->size - ggtt_start;
+ u64 ggtt_start = xe_ggtt_start(gt_to_tile(gt)->mem.ggtt);
+ u64 ggtt_size = xe_ggtt_size(gt_to_tile(gt)->mem.ggtt);
/* plain PF config data will never include a real GGTT region */
xe_gt_assert(gt, !encode_config_ggtt(cfg + num_dwords, config, true));
@@ -545,9 +543,9 @@ static int pf_provision_vf_ggtt(struct xe_gt *gt, unsigned int vfid, u64 size)
xe_ggtt_assign(node, vfid);
xe_gt_sriov_dbg_verbose(gt, "VF%u assigned GGTT %llx-%llx\n",
- vfid, node->base.start, node->base.start + node->base.size - 1);
+ vfid, xe_ggtt_node_addr(node), xe_ggtt_node_addr(node) + size - 1);
- err = pf_distribute_config_ggtt(gt->tile, vfid, node->base.start, node->base.size);
+ err = pf_distribute_config_ggtt(gt->tile, vfid, xe_ggtt_node_addr(node), size);
if (unlikely(err))
goto err;
@@ -564,7 +562,7 @@ static u64 pf_get_vf_config_ggtt(struct xe_gt *gt, unsigned int vfid)
struct xe_ggtt_node *node = config->ggtt_region;
xe_gt_assert(gt, xe_gt_is_main_type(gt));
- return xe_ggtt_node_allocated(node) ? node->base.size : 0;
+ return xe_ggtt_node_allocated(node) ? xe_ggtt_node_size(node) : 0;
}
/**
@@ -3040,11 +3038,12 @@ int xe_gt_sriov_pf_config_print_ggtt(struct xe_gt *gt, struct drm_printer *p)
if (!xe_ggtt_node_allocated(config->ggtt_region))
continue;
- string_get_size(config->ggtt_region->base.size, 1, STRING_UNITS_2,
+ string_get_size(xe_ggtt_node_size(config->ggtt_region), 1, STRING_UNITS_2,
buf, sizeof(buf));
drm_printf(p, "VF%u:\t%#0llx-%#llx\t(%s)\n",
- n, config->ggtt_region->base.start,
- config->ggtt_region->base.start + config->ggtt_region->base.size - 1,
+ n, xe_ggtt_node_addr(config->ggtt_region),
+ xe_ggtt_node_addr(config->ggtt_region) +
+ xe_ggtt_node_size(config->ggtt_region) - 1,
buf);
}
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c
index 47d288c53539..f97abb02aebd 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c
@@ -8,7 +8,6 @@
#include <drm/drm_print.h>
#include <drm/drm_debugfs.h>
-#include "xe_bo.h"
#include "xe_debugfs.h"
#include "xe_device.h"
#include "xe_gt.h"
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
index 7410e7b93256..87a164efcc33 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c
@@ -14,7 +14,6 @@
#include "xe_gt_sriov_pf.h"
#include "xe_gt_sriov_pf_config.h"
#include "xe_gt_sriov_pf_control.h"
-#include "xe_gt_sriov_pf_helpers.h"
#include "xe_gt_sriov_pf_migration.h"
#include "xe_gt_sriov_printk.h"
#include "xe_guc.h"
@@ -25,6 +24,7 @@
#include "xe_sriov.h"
#include "xe_sriov_packet.h"
#include "xe_sriov_packet_types.h"
+#include "xe_sriov_pf_helpers.h"
#include "xe_sriov_pf_migration.h"
#define XE_GT_SRIOV_PF_MIGRATION_RING_SIZE 5
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_policy.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_policy.c
index c28606ca6623..848e24926ecd 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_policy.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_policy.c
@@ -7,7 +7,6 @@
#include "abi/guc_actions_sriov_abi.h"
-#include "xe_bo.h"
#include "xe_gt.h"
#include "xe_gt_sriov_pf_helpers.h"
#include "xe_gt_sriov_pf_policy.h"
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c
index 2eb21610e5a0..b5e0a5b7723e 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_service.c
@@ -5,20 +5,19 @@
#include <drm/drm_managed.h>
-#include "abi/guc_actions_sriov_abi.h"
#include "abi/guc_relay_actions_abi.h"
#include "regs/xe_gt_regs.h"
#include "regs/xe_guc_regs.h"
-#include "regs/xe_regs.h"
+#include "xe_assert.h"
#include "xe_mmio.h"
#include "xe_gt_sriov_printk.h"
-#include "xe_gt_sriov_pf_helpers.h"
#include "xe_gt_sriov_pf_service.h"
#include "xe_gt_sriov_pf_service_types.h"
#include "xe_guc_ct.h"
#include "xe_guc_hxg_helpers.h"
+#include "xe_sriov.h"
#include "xe_sriov_pf_service.h"
static const struct xe_reg tgl_runtime_regs[] = {
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c
index d91c65dc3496..30e8c2cf5f09 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_vf.c
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf.c
@@ -15,7 +15,6 @@
#include "abi/guc_klvs_abi.h"
#include "abi/guc_relay_actions_abi.h"
#include "regs/xe_gt_regs.h"
-#include "regs/xe_gtt_defs.h"
#include "xe_assert.h"
#include "xe_device.h"
diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_vf_types.h b/drivers/gpu/drm/xe/xe_gt_sriov_vf_types.h
index 9a6b5672d569..4ef881b9b662 100644
--- a/drivers/gpu/drm/xe/xe_gt_sriov_vf_types.h
+++ b/drivers/gpu/drm/xe/xe_gt_sriov_vf_types.h
@@ -43,10 +43,10 @@ struct xe_gt_sriov_vf_runtime {
};
/**
- * xe_gt_sriov_vf_migration - VF migration data.
+ * struct xe_gt_sriov_vf_migration - VF migration data.
*/
struct xe_gt_sriov_vf_migration {
- /** @migration: VF migration recovery worker */
+ /** @worker: VF migration recovery worker */
struct work_struct worker;
/** @lock: Protects recovery_queued, teardown */
spinlock_t lock;
diff --git a/drivers/gpu/drm/xe/xe_gt_stats.c b/drivers/gpu/drm/xe/xe_gt_stats.c
index fb2904bd0abd..37506434d7a3 100644
--- a/drivers/gpu/drm/xe/xe_gt_stats.c
+++ b/drivers/gpu/drm/xe/xe_gt_stats.c
@@ -7,8 +7,8 @@
#include <drm/drm_print.h>
-#include "xe_gt.h"
#include "xe_gt_stats.h"
+#include "xe_gt_types.h"
/**
* xe_gt_stats_incr - Increments the specified stats counter
@@ -76,6 +76,11 @@ static const char *const stat_description[__XE_GT_STATS_NUM_IDS] = {
"hw_engine_group_suspend_lr_queue_us"),
DEF_STAT_STR(HW_ENGINE_GROUP_WAIT_DMA_QUEUE_US,
"hw_engine_group_wait_dma_queue_us"),
+ DEF_STAT_STR(PRL_4K_ENTRY_COUNT, "prl_4k_entry_count"),
+ DEF_STAT_STR(PRL_64K_ENTRY_COUNT, "prl_64k_entry_count"),
+ DEF_STAT_STR(PRL_2M_ENTRY_COUNT, "prl_2m_entry_count"),
+ DEF_STAT_STR(PRL_ISSUED_COUNT, "prl_issued_count"),
+ DEF_STAT_STR(PRL_ABORTED_COUNT, "prl_aborted_count"),
};
/**
diff --git a/drivers/gpu/drm/xe/xe_gt_stats_types.h b/drivers/gpu/drm/xe/xe_gt_stats_types.h
index b92d013091d5..b8accdbc54eb 100644
--- a/drivers/gpu/drm/xe/xe_gt_stats_types.h
+++ b/drivers/gpu/drm/xe/xe_gt_stats_types.h
@@ -49,6 +49,11 @@ enum xe_gt_stats_id {
XE_GT_STATS_ID_HW_ENGINE_GROUP_WAIT_DMA_QUEUE_COUNT,
XE_GT_STATS_ID_HW_ENGINE_GROUP_SUSPEND_LR_QUEUE_US,
XE_GT_STATS_ID_HW_ENGINE_GROUP_WAIT_DMA_QUEUE_US,
+ XE_GT_STATS_ID_PRL_4K_ENTRY_COUNT,
+ XE_GT_STATS_ID_PRL_64K_ENTRY_COUNT,
+ XE_GT_STATS_ID_PRL_2M_ENTRY_COUNT,
+ XE_GT_STATS_ID_PRL_ISSUED_COUNT,
+ XE_GT_STATS_ID_PRL_ABORTED_COUNT,
/* must be the last entry */
__XE_GT_STATS_NUM_IDS,
};
diff --git a/drivers/gpu/drm/xe/xe_gt_sysfs.c b/drivers/gpu/drm/xe/xe_gt_sysfs.c
index ec2b8246204b..1448be047b4a 100644
--- a/drivers/gpu/drm/xe/xe_gt_sysfs.c
+++ b/drivers/gpu/drm/xe/xe_gt_sysfs.c
@@ -10,7 +10,7 @@
#include <drm/drm_managed.h>
-#include "xe_gt.h"
+#include "xe_gt_types.h"
static void xe_gt_sysfs_kobj_release(struct kobject *kobj)
{
diff --git a/drivers/gpu/drm/xe/xe_gt_throttle.c b/drivers/gpu/drm/xe/xe_gt_throttle.c
index 570358310e97..1e7e3a31aa69 100644
--- a/drivers/gpu/drm/xe/xe_gt_throttle.c
+++ b/drivers/gpu/drm/xe/xe_gt_throttle.c
@@ -6,7 +6,7 @@
#include <drm/drm_managed.h>
#include <regs/xe_gt_regs.h>
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_gt.h"
#include "xe_gt_sysfs.h"
#include "xe_gt_throttle.h"
diff --git a/drivers/gpu/drm/xe/xe_guc_ads.c b/drivers/gpu/drm/xe/xe_guc_ads.c
index 5feeb91426ee..f4cbc030f4c8 100644
--- a/drivers/gpu/drm/xe/xe_guc_ads.c
+++ b/drivers/gpu/drm/xe/xe_guc_ads.c
@@ -28,8 +28,6 @@
#include "xe_lrc.h"
#include "xe_map.h"
#include "xe_mmio.h"
-#include "xe_platform_types.h"
-#include "xe_uc_fw.h"
#include "xe_wa.h"
/* Slack of a few additional entries per engine */
@@ -451,7 +449,7 @@ static void guc_policies_init(struct xe_guc_ads *ads)
ads_blob_write(ads, policies.max_num_work_items,
GLOBAL_POLICY_MAX_NUM_WI);
- if (xe->wedged.mode == 2)
+ if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)
global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
ads_blob_write(ads, policies.global_flags, global_flags);
@@ -983,16 +981,17 @@ static int guc_ads_action_update_policies(struct xe_guc_ads *ads, u32 policy_off
/**
* xe_guc_ads_scheduler_policy_toggle_reset - Toggle reset policy
* @ads: Additional data structures object
+ * @enable_engine_reset: true to enable engine resets, false otherwise
*
- * This function update the GuC's engine reset policy based on wedged.mode.
+ * This function update the GuC's engine reset policy.
*
* Return: 0 on success, and negative error code otherwise.
*/
-int xe_guc_ads_scheduler_policy_toggle_reset(struct xe_guc_ads *ads)
+int xe_guc_ads_scheduler_policy_toggle_reset(struct xe_guc_ads *ads,
+ bool enable_engine_reset)
{
struct guc_policies *policies;
struct xe_guc *guc = ads_to_guc(ads);
- struct xe_device *xe = ads_to_xe(ads);
CLASS(xe_guc_buf, buf)(&guc->buf, sizeof(*policies));
if (!xe_guc_buf_is_valid(buf))
@@ -1004,10 +1003,11 @@ int xe_guc_ads_scheduler_policy_toggle_reset(struct xe_guc_ads *ads)
policies->dpc_promote_time = ads_blob_read(ads, policies.dpc_promote_time);
policies->max_num_work_items = ads_blob_read(ads, policies.max_num_work_items);
policies->is_valid = 1;
- if (xe->wedged.mode == 2)
- policies->global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
- else
+
+ if (enable_engine_reset)
policies->global_flags &= ~GLOBAL_POLICY_DISABLE_ENGINE_RESET;
+ else
+ policies->global_flags |= GLOBAL_POLICY_DISABLE_ENGINE_RESET;
return guc_ads_action_update_policies(ads, xe_guc_buf_flush(buf));
}
diff --git a/drivers/gpu/drm/xe/xe_guc_ads.h b/drivers/gpu/drm/xe/xe_guc_ads.h
index 2e6674c760ff..7a39f361cb17 100644
--- a/drivers/gpu/drm/xe/xe_guc_ads.h
+++ b/drivers/gpu/drm/xe/xe_guc_ads.h
@@ -6,6 +6,8 @@
#ifndef _XE_GUC_ADS_H_
#define _XE_GUC_ADS_H_
+#include <linux/types.h>
+
struct xe_guc_ads;
int xe_guc_ads_init(struct xe_guc_ads *ads);
@@ -13,6 +15,7 @@ int xe_guc_ads_init_post_hwconfig(struct xe_guc_ads *ads);
void xe_guc_ads_populate(struct xe_guc_ads *ads);
void xe_guc_ads_populate_minimal(struct xe_guc_ads *ads);
void xe_guc_ads_populate_post_load(struct xe_guc_ads *ads);
-int xe_guc_ads_scheduler_policy_toggle_reset(struct xe_guc_ads *ads);
+int xe_guc_ads_scheduler_policy_toggle_reset(struct xe_guc_ads *ads,
+ bool enable_engine_reset);
#endif
diff --git a/drivers/gpu/drm/xe/xe_guc_buf.c b/drivers/gpu/drm/xe/xe_guc_buf.c
index c36fc31e0438..11f77decd8d1 100644
--- a/drivers/gpu/drm/xe/xe_guc_buf.c
+++ b/drivers/gpu/drm/xe/xe_guc_buf.c
@@ -6,7 +6,6 @@
#include <linux/cleanup.h>
#include <drm/drm_managed.h>
-#include "xe_assert.h"
#include "xe_bo.h"
#include "xe_gt_printk.h"
#include "xe_guc.h"
diff --git a/drivers/gpu/drm/xe/xe_guc_capture.c b/drivers/gpu/drm/xe/xe_guc_capture.c
index 2cda92f7b323..2f5816c78fba 100644
--- a/drivers/gpu/drm/xe/xe_guc_capture.c
+++ b/drivers/gpu/drm/xe/xe_guc_capture.c
@@ -13,17 +13,14 @@
#include "abi/guc_log_abi.h"
#include "regs/xe_engine_regs.h"
#include "regs/xe_gt_regs.h"
-#include "regs/xe_guc_regs.h"
-#include "regs/xe_regs.h"
-#include "xe_bo.h"
+#include "xe_bo_types.h"
#include "xe_device.h"
#include "xe_exec_queue_types.h"
#include "xe_gt.h"
#include "xe_gt_mcr.h"
#include "xe_gt_printk.h"
#include "xe_guc.h"
-#include "xe_guc_ads.h"
#include "xe_guc_capture.h"
#include "xe_guc_capture_types.h"
#include "xe_guc_ct.h"
@@ -1889,7 +1886,14 @@ xe_guc_capture_get_matching_and_lock(struct xe_exec_queue *q)
return NULL;
xe = gt_to_xe(q->gt);
- if (xe->wedged.mode >= 2 || !xe_device_uc_enabled(xe) || IS_SRIOV_VF(xe))
+
+ if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)
+ return NULL;
+
+ if (!xe_device_uc_enabled(xe))
+ return NULL;
+
+ if (IS_SRIOV_VF(xe))
return NULL;
ss = &xe->devcoredump.snapshot;
diff --git a/drivers/gpu/drm/xe/xe_guc_debugfs.c b/drivers/gpu/drm/xe/xe_guc_debugfs.c
index 23827e87450f..2f23119686d4 100644
--- a/drivers/gpu/drm/xe/xe_guc_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_guc_debugfs.c
@@ -8,13 +8,12 @@
#include <drm/drm_debugfs.h>
#include <drm/drm_managed.h>
-#include "xe_device.h"
-#include "xe_gt.h"
+#include "xe_device_types.h"
+#include "xe_gt_types.h"
#include "xe_guc.h"
#include "xe_guc_ct.h"
#include "xe_guc_log.h"
#include "xe_guc_pc.h"
-#include "xe_macros.h"
#include "xe_pm.h"
/*
diff --git a/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h b/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
index a3b034e4b205..fd0915ed8eb1 100644
--- a/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
+++ b/drivers/gpu/drm/xe/xe_guc_exec_queue_types.h
@@ -33,8 +33,6 @@ struct xe_guc_exec_queue {
*/
#define MAX_STATIC_MSG_TYPE 3
struct xe_sched_msg static_msgs[MAX_STATIC_MSG_TYPE];
- /** @lr_tdr: long running TDR worker */
- struct work_struct lr_tdr;
/** @destroy_async: do final destroy async from this worker */
struct work_struct destroy_async;
/** @resume_time: time of last resume */
diff --git a/drivers/gpu/drm/xe/xe_guc_hwconfig.c b/drivers/gpu/drm/xe/xe_guc_hwconfig.c
index af2c817d552c..b300901dbb8e 100644
--- a/drivers/gpu/drm/xe/xe_guc_hwconfig.c
+++ b/drivers/gpu/drm/xe/xe_guc_hwconfig.c
@@ -10,8 +10,8 @@
#include "abi/guc_actions_abi.h"
#include "xe_bo.h"
-#include "xe_device.h"
-#include "xe_gt.h"
+#include "xe_device_types.h"
+#include "xe_gt_types.h"
#include "xe_guc.h"
#include "xe_map.h"
diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c
index d7473b9673bb..acac66a4eca7 100644
--- a/drivers/gpu/drm/xe/xe_guc_log.c
+++ b/drivers/gpu/drm/xe/xe_guc_log.c
@@ -15,8 +15,8 @@
#include "xe_bo.h"
#include "xe_devcoredump.h"
#include "xe_force_wake.h"
-#include "xe_gt.h"
#include "xe_gt_printk.h"
+#include "xe_gt_types.h"
#include "xe_map.h"
#include "xe_mmio.h"
#include "xe_module.h"
diff --git a/drivers/gpu/drm/xe/xe_guc_relay.c b/drivers/gpu/drm/xe/xe_guc_relay.c
index 0c0ff24ba62a..577a315854af 100644
--- a/drivers/gpu/drm/xe/xe_guc_relay.c
+++ b/drivers/gpu/drm/xe/xe_guc_relay.c
@@ -17,8 +17,7 @@
#include "abi/guc_relay_communication_abi.h"
#include "xe_assert.h"
-#include "xe_device.h"
-#include "xe_gt.h"
+#include "xe_device_types.h"
#include "xe_gt_sriov_printk.h"
#include "xe_gt_sriov_pf_service.h"
#include "xe_guc.h"
diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c
index 7a4218f76024..a27ea931b956 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit.c
+++ b/drivers/gpu/drm/xe/xe_guc_submit.c
@@ -17,7 +17,6 @@
#include "abi/guc_actions_abi.h"
#include "abi/guc_actions_slpc_abi.h"
#include "abi/guc_klvs_abi.h"
-#include "regs/xe_lrc_layout.h"
#include "xe_assert.h"
#include "xe_bo.h"
#include "xe_devcoredump.h"
@@ -36,7 +35,6 @@
#include "xe_guc_klv_helpers.h"
#include "xe_guc_submit_types.h"
#include "xe_hw_engine.h"
-#include "xe_hw_fence.h"
#include "xe_lrc.h"
#include "xe_macros.h"
#include "xe_map.h"
@@ -71,11 +69,8 @@ exec_queue_to_guc(struct xe_exec_queue *q)
#define EXEC_QUEUE_STATE_KILLED (1 << 7)
#define EXEC_QUEUE_STATE_WEDGED (1 << 8)
#define EXEC_QUEUE_STATE_BANNED (1 << 9)
-#define EXEC_QUEUE_STATE_CHECK_TIMEOUT (1 << 10)
-#define EXEC_QUEUE_STATE_EXTRA_REF (1 << 11)
-#define EXEC_QUEUE_STATE_PENDING_RESUME (1 << 12)
-#define EXEC_QUEUE_STATE_PENDING_TDR_EXIT (1 << 13)
-#define EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND (1 << 14)
+#define EXEC_QUEUE_STATE_PENDING_RESUME (1 << 10)
+#define EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND (1 << 11)
static bool exec_queue_registered(struct xe_exec_queue *q)
{
@@ -207,36 +202,6 @@ static void set_exec_queue_wedged(struct xe_exec_queue *q)
atomic_or(EXEC_QUEUE_STATE_WEDGED, &q->guc->state);
}
-static bool exec_queue_check_timeout(struct xe_exec_queue *q)
-{
- return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_CHECK_TIMEOUT;
-}
-
-static void set_exec_queue_check_timeout(struct xe_exec_queue *q)
-{
- atomic_or(EXEC_QUEUE_STATE_CHECK_TIMEOUT, &q->guc->state);
-}
-
-static void clear_exec_queue_check_timeout(struct xe_exec_queue *q)
-{
- atomic_and(~EXEC_QUEUE_STATE_CHECK_TIMEOUT, &q->guc->state);
-}
-
-static bool exec_queue_extra_ref(struct xe_exec_queue *q)
-{
- return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_EXTRA_REF;
-}
-
-static void set_exec_queue_extra_ref(struct xe_exec_queue *q)
-{
- atomic_or(EXEC_QUEUE_STATE_EXTRA_REF, &q->guc->state);
-}
-
-static void clear_exec_queue_extra_ref(struct xe_exec_queue *q)
-{
- atomic_and(~EXEC_QUEUE_STATE_EXTRA_REF, &q->guc->state);
-}
-
static bool exec_queue_pending_resume(struct xe_exec_queue *q)
{
return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_PENDING_RESUME;
@@ -252,21 +217,6 @@ static void clear_exec_queue_pending_resume(struct xe_exec_queue *q)
atomic_and(~EXEC_QUEUE_STATE_PENDING_RESUME, &q->guc->state);
}
-static bool exec_queue_pending_tdr_exit(struct xe_exec_queue *q)
-{
- return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_PENDING_TDR_EXIT;
-}
-
-static void set_exec_queue_pending_tdr_exit(struct xe_exec_queue *q)
-{
- atomic_or(EXEC_QUEUE_STATE_PENDING_TDR_EXIT, &q->guc->state);
-}
-
-static void clear_exec_queue_pending_tdr_exit(struct xe_exec_queue *q)
-{
- atomic_and(~EXEC_QUEUE_STATE_PENDING_TDR_EXIT, &q->guc->state);
-}
-
static bool exec_queue_idle_skip_suspend(struct xe_exec_queue *q)
{
return atomic_read(&q->guc->state) & EXEC_QUEUE_STATE_IDLE_SKIP_SUSPEND;
@@ -603,10 +553,7 @@ static void xe_guc_exec_queue_trigger_cleanup(struct xe_exec_queue *q)
/** to wakeup xe_wait_user_fence ioctl if exec queue is reset */
wake_up_all(&xe->ufence_wq);
- if (xe_exec_queue_is_lr(q))
- queue_work(guc_to_gt(guc)->ordered_wq, &q->guc->lr_tdr);
- else
- xe_sched_tdr_queue_imm(&q->guc->sched);
+ xe_sched_tdr_queue_imm(&q->guc->sched);
}
static void xe_guc_exec_queue_group_trigger_cleanup(struct xe_exec_queue *q)
@@ -639,19 +586,19 @@ static void xe_guc_exec_queue_reset_trigger_cleanup(struct xe_exec_queue *q)
WRITE_ONCE(group->banned, true);
set_exec_queue_reset(primary);
- if (!exec_queue_banned(primary) && !exec_queue_check_timeout(primary))
+ if (!exec_queue_banned(primary))
xe_guc_exec_queue_trigger_cleanup(primary);
mutex_lock(&group->list_lock);
list_for_each_entry(eq, &group->list, multi_queue.link) {
set_exec_queue_reset(eq);
- if (!exec_queue_banned(eq) && !exec_queue_check_timeout(eq))
+ if (!exec_queue_banned(eq))
xe_guc_exec_queue_trigger_cleanup(eq);
}
mutex_unlock(&group->list_lock);
} else {
set_exec_queue_reset(q);
- if (!exec_queue_banned(q) && !exec_queue_check_timeout(q))
+ if (!exec_queue_banned(q))
xe_guc_exec_queue_trigger_cleanup(q);
}
}
@@ -994,14 +941,6 @@ static void register_exec_queue(struct xe_exec_queue *q, int ctx_type)
parallel_write(xe, map, wq_desc.wq_status, WQ_STATUS_ACTIVE);
}
- /*
- * We must keep a reference for LR engines if engine is registered with
- * the GuC as jobs signal immediately and can't destroy an engine if the
- * GuC has a reference to it.
- */
- if (xe_exec_queue_is_lr(q))
- xe_exec_queue_get(q);
-
set_exec_queue_registered(q);
trace_xe_exec_queue_register(q);
if (xe_exec_queue_is_multi_queue_primary(q))
@@ -1202,7 +1141,7 @@ guc_exec_queue_run_job(struct drm_sched_job *drm_job)
struct xe_sched_job *job = to_xe_sched_job(drm_job);
struct xe_exec_queue *q = job->q;
struct xe_guc *guc = exec_queue_to_guc(q);
- bool lr = xe_exec_queue_is_lr(q), killed_or_banned_or_wedged =
+ bool killed_or_banned_or_wedged =
exec_queue_killed_or_banned_or_wedged(q);
xe_gt_assert(guc_to_gt(guc), !(exec_queue_destroyed(q) || exec_queue_pending_disable(q)) ||
@@ -1232,14 +1171,6 @@ guc_exec_queue_run_job(struct drm_sched_job *drm_job)
}
run_job_out:
- /*
- * We don't care about job-fence ordering in LR VMs because these fences
- * are never exported; they are used solely to keep jobs on the pending
- * list. Once a queue enters an error state, there's no need to track
- * them.
- */
- if (killed_or_banned_or_wedged && lr)
- xe_sched_job_set_error(job, -ECANCELED);
return job->fence;
}
@@ -1291,8 +1222,7 @@ static void disable_scheduling_deregister(struct xe_guc *guc,
xe_gt_warn(q->gt, "Pending enable/disable failed to respond\n");
xe_sched_submission_start(sched);
xe_gt_reset_async(q->gt);
- if (!xe_exec_queue_is_lr(q))
- xe_sched_tdr_queue_imm(sched);
+ xe_sched_tdr_queue_imm(sched);
return;
}
@@ -1339,8 +1269,9 @@ void xe_guc_submit_wedge(struct xe_guc *guc)
err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev,
guc_submit_wedged_fini, guc);
if (err) {
- xe_gt_err(gt, "Failed to register clean-up on wedged.mode=2; "
- "Although device is wedged.\n");
+ xe_gt_err(gt, "Failed to register clean-up in wedged.mode=%s; "
+ "Although device is wedged.\n",
+ xe_wedged_mode_to_string(XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET));
return;
}
@@ -1355,7 +1286,7 @@ static bool guc_submit_hint_wedged(struct xe_guc *guc)
{
struct xe_device *xe = guc_to_xe(guc);
- if (xe->wedged.mode != 2)
+ if (xe->wedged.mode != XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)
return false;
if (xe_device_wedged(xe))
@@ -1366,84 +1297,6 @@ static bool guc_submit_hint_wedged(struct xe_guc *guc)
return true;
}
-static void xe_guc_exec_queue_lr_cleanup(struct work_struct *w)
-{
- struct xe_guc_exec_queue *ge =
- container_of(w, struct xe_guc_exec_queue, lr_tdr);
- struct xe_exec_queue *q = ge->q;
- struct xe_guc *guc = exec_queue_to_guc(q);
- struct xe_gpu_scheduler *sched = &ge->sched;
- struct xe_sched_job *job;
- bool wedged = false;
-
- xe_gt_assert(guc_to_gt(guc), xe_exec_queue_is_lr(q));
-
- if (vf_recovery(guc))
- return;
-
- trace_xe_exec_queue_lr_cleanup(q);
-
- if (!exec_queue_killed(q))
- wedged = guc_submit_hint_wedged(exec_queue_to_guc(q));
-
- /* Kill the run_job / process_msg entry points */
- xe_sched_submission_stop(sched);
-
- /*
- * Engine state now mostly stable, disable scheduling / deregister if
- * needed. This cleanup routine might be called multiple times, where
- * the actual async engine deregister drops the final engine ref.
- * Calling disable_scheduling_deregister will mark the engine as
- * destroyed and fire off the CT requests to disable scheduling /
- * deregister, which we only want to do once. We also don't want to mark
- * the engine as pending_disable again as this may race with the
- * xe_guc_deregister_done_handler() which treats it as an unexpected
- * state.
- */
- if (!wedged && exec_queue_registered(q) && !exec_queue_destroyed(q)) {
- struct xe_guc *guc = exec_queue_to_guc(q);
- int ret;
-
- set_exec_queue_banned(q);
- disable_scheduling_deregister(guc, q);
-
- /*
- * Must wait for scheduling to be disabled before signalling
- * any fences, if GT broken the GT reset code should signal us.
- */
- ret = wait_event_timeout(guc->ct.wq,
- !exec_queue_pending_disable(q) ||
- xe_guc_read_stopped(guc) ||
- vf_recovery(guc), HZ * 5);
- if (vf_recovery(guc))
- return;
-
- if (!ret) {
- xe_gt_warn(q->gt, "Schedule disable failed to respond, guc_id=%d\n",
- q->guc->id);
- xe_devcoredump(q, NULL, "Schedule disable failed to respond, guc_id=%d\n",
- q->guc->id);
- xe_sched_submission_start(sched);
- xe_gt_reset_async(q->gt);
- return;
- }
- }
-
- if (!exec_queue_killed(q) && !xe_lrc_ring_is_idle(q->lrc[0]))
- xe_devcoredump(q, NULL, "LR job cleanup, guc_id=%d", q->guc->id);
-
- xe_hw_fence_irq_stop(q->fence_irq);
-
- xe_sched_submission_start(sched);
-
- spin_lock(&sched->base.job_list_lock);
- list_for_each_entry(job, &sched->base.pending_list, drm.list)
- xe_sched_job_set_error(job, -ECANCELED);
- spin_unlock(&sched->base.job_list_lock);
-
- xe_hw_fence_irq_start(q->fence_irq);
-}
-
#define ADJUST_FIVE_PERCENT(__t) mul_u64_u32_div(__t, 105, 100)
static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job)
@@ -1462,7 +1315,16 @@ static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job)
return xe_sched_invalidate_job(job, 2);
}
- ctx_timestamp = lower_32_bits(xe_lrc_ctx_timestamp(q->lrc[0]));
+ ctx_timestamp = lower_32_bits(xe_lrc_timestamp(q->lrc[0]));
+ if (ctx_timestamp == job->sample_timestamp) {
+ xe_gt_warn(gt, "Check job timeout: seqno=%u, lrc_seqno=%u, guc_id=%d, timestamp stuck",
+ xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
+ q->guc->id);
+
+ return xe_sched_invalidate_job(job, 0);
+ }
+
+ job->sample_timestamp = ctx_timestamp;
ctx_job_timestamp = xe_lrc_ctx_job_timestamp(q->lrc[0]);
/*
@@ -1516,8 +1378,7 @@ static void enable_scheduling(struct xe_exec_queue *q)
xe_gt_warn(guc_to_gt(guc), "Schedule enable failed to respond");
set_exec_queue_banned(q);
xe_gt_reset_async(q->gt);
- if (!xe_exec_queue_is_lr(q))
- xe_sched_tdr_queue_imm(&q->guc->sched);
+ xe_sched_tdr_queue_imm(&q->guc->sched);
}
}
@@ -1543,33 +1404,11 @@ static void disable_scheduling(struct xe_exec_queue *q, bool immediate)
G2H_LEN_DW_SCHED_CONTEXT_MODE_SET, 1);
}
-static void __deregister_exec_queue(struct xe_guc *guc, struct xe_exec_queue *q)
-{
- u32 action[] = {
- XE_GUC_ACTION_DEREGISTER_CONTEXT,
- q->guc->id,
- };
-
- xe_gt_assert(guc_to_gt(guc), !exec_queue_destroyed(q));
- xe_gt_assert(guc_to_gt(guc), exec_queue_registered(q));
- xe_gt_assert(guc_to_gt(guc), !exec_queue_pending_enable(q));
- xe_gt_assert(guc_to_gt(guc), !exec_queue_pending_disable(q));
-
- set_exec_queue_destroyed(q);
- trace_xe_exec_queue_deregister(q);
-
- if (xe_exec_queue_is_multi_queue_secondary(q))
- handle_deregister_done(guc, q);
- else
- xe_guc_ct_send(&guc->ct, action, ARRAY_SIZE(action),
- G2H_LEN_DW_DEREGISTER_CONTEXT, 1);
-}
-
static enum drm_gpu_sched_stat
guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
{
struct xe_sched_job *job = to_xe_sched_job(drm_job);
- struct xe_sched_job *tmp_job;
+ struct drm_sched_job *tmp_job;
struct xe_exec_queue *q = job->q;
struct xe_gpu_scheduler *sched = &q->guc->sched;
struct xe_guc *guc = exec_queue_to_guc(q);
@@ -1577,10 +1416,9 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
struct xe_device *xe = guc_to_xe(guc);
int err = -ETIME;
pid_t pid = -1;
- int i = 0;
bool wedged = false, skip_timeout_check;
- xe_gt_assert(guc_to_gt(guc), !xe_exec_queue_is_lr(q));
+ xe_gt_assert(guc_to_gt(guc), !exec_queue_destroyed(q));
/*
* TDR has fired before free job worker. Common if exec queue
@@ -1597,14 +1435,17 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
/* Must check all state after stopping scheduler */
skip_timeout_check = exec_queue_reset(q) ||
- exec_queue_killed_or_banned_or_wedged(q) ||
- exec_queue_destroyed(q);
+ exec_queue_killed_or_banned_or_wedged(q);
/* Skip timeout check if multi-queue group is banned */
if (xe_exec_queue_is_multi_queue(q) &&
READ_ONCE(q->multi_queue.group->banned))
skip_timeout_check = true;
+ /* LR jobs can only get here if queue has been killed or hit an error */
+ if (xe_exec_queue_is_lr(q))
+ xe_gt_assert(guc_to_gt(guc), skip_timeout_check);
+
/*
* FIXME: In multi-queue scenario, the TDR must ensure that the whole
* multi-queue group is off the HW before signaling the fences to avoid
@@ -1628,23 +1469,24 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
}
/*
- * XXX: Sampling timeout doesn't work in wedged mode as we have to
- * modify scheduling state to read timestamp. We could read the
- * timestamp from a register to accumulate current running time but this
- * doesn't work for SRIOV. For now assuming timeouts in wedged mode are
- * genuine timeouts.
+ * Check if job is actually timed out, if so restart job execution and TDR
*/
+ if (!skip_timeout_check && !check_timeout(q, job))
+ goto rearm;
+
if (!exec_queue_killed(q))
wedged = guc_submit_hint_wedged(exec_queue_to_guc(q));
- /* Engine state now stable, disable scheduling to check timestamp */
- if (!wedged && exec_queue_registered(q)) {
+ set_exec_queue_banned(q);
+
+ /* Kick job / queue off hardware */
+ if (!wedged && (exec_queue_enabled(q) || exec_queue_pending_disable(q))) {
int ret;
if (exec_queue_reset(q))
err = -EIO;
- if (!exec_queue_destroyed(q)) {
+ if (xe_uc_fw_is_running(&guc->fw)) {
/*
* Wait for any pending G2H to flush out before
* modifying state
@@ -1659,13 +1501,6 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
if (!ret || xe_guc_read_stopped(guc))
goto trigger_reset;
- /*
- * Flag communicates to G2H handler that schedule
- * disable originated from a timeout check. The G2H then
- * avoid triggering cleanup or deregistering the exec
- * queue.
- */
- set_exec_queue_check_timeout(q);
disable_scheduling(q, skip_timeout_check);
}
@@ -1679,6 +1514,7 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
*/
smp_rmb();
ret = wait_event_timeout(guc->ct.wq,
+ !xe_uc_fw_is_running(&guc->fw) ||
!exec_queue_pending_disable(q) ||
xe_guc_read_stopped(guc) ||
vf_recovery(guc), HZ * 5);
@@ -1693,24 +1529,12 @@ trigger_reset:
xe_devcoredump(q, job,
"Schedule disable failed to respond, guc_id=%d, ret=%d, guc_read=%d",
q->guc->id, ret, xe_guc_read_stopped(guc));
- set_exec_queue_extra_ref(q);
- xe_exec_queue_get(q); /* GT reset owns this */
- set_exec_queue_banned(q);
xe_gt_reset_async(q->gt);
xe_sched_tdr_queue_imm(sched);
goto rearm;
}
}
- /*
- * Check if job is actually timed out, if so restart job execution and TDR
- */
- if (!wedged && !skip_timeout_check && !check_timeout(q, job) &&
- !exec_queue_reset(q) && exec_queue_registered(q)) {
- clear_exec_queue_check_timeout(q);
- goto sched_enable;
- }
-
if (q->vm && q->vm->xef) {
process_name = q->vm->xef->process_name;
pid = q->vm->xef->pid;
@@ -1741,28 +1565,16 @@ trigger_reset:
if (!wedged && (q->flags & EXEC_QUEUE_FLAG_KERNEL ||
(q->flags & EXEC_QUEUE_FLAG_VM && !exec_queue_killed(q)))) {
if (!xe_sched_invalidate_job(job, 2)) {
- clear_exec_queue_check_timeout(q);
xe_gt_reset_async(q->gt);
goto rearm;
}
}
- /* Finish cleaning up exec queue via deregister */
- set_exec_queue_banned(q);
- if (!wedged && exec_queue_registered(q) && !exec_queue_destroyed(q)) {
- set_exec_queue_extra_ref(q);
- xe_exec_queue_get(q);
- __deregister_exec_queue(guc, q);
- }
-
- /* Stop fence signaling */
- xe_hw_fence_irq_stop(q->fence_irq);
+ /* Mark all outstanding jobs as bad, thus completing them */
+ xe_sched_job_set_error(job, err);
+ drm_sched_for_each_pending_job(tmp_job, &sched->base, NULL)
+ xe_sched_job_set_error(to_xe_sched_job(tmp_job), -ECANCELED);
- /*
- * Fence state now stable, stop / start scheduler which cleans up any
- * fences that are complete
- */
- xe_sched_add_pending_job(sched, job);
xe_sched_submission_start(sched);
if (xe_exec_queue_is_multi_queue(q))
@@ -1770,20 +1582,12 @@ trigger_reset:
else
xe_guc_exec_queue_trigger_cleanup(q);
- /* Mark all outstanding jobs as bad, thus completing them */
- spin_lock(&sched->base.job_list_lock);
- list_for_each_entry(tmp_job, &sched->base.pending_list, drm.list)
- xe_sched_job_set_error(tmp_job, !i++ ? err : -ECANCELED);
- spin_unlock(&sched->base.job_list_lock);
-
- /* Start fence signaling */
- xe_hw_fence_irq_start(q->fence_irq);
-
- return DRM_GPU_SCHED_STAT_RESET;
+ /*
+ * We want the job added back to the pending list so it gets freed; this
+ * is what DRM_GPU_SCHED_STAT_NO_HANG does.
+ */
+ return DRM_GPU_SCHED_STAT_NO_HANG;
-sched_enable:
- set_exec_queue_pending_tdr_exit(q);
- enable_scheduling(q);
rearm:
/*
* XXX: Ideally want to adjust timeout based on current execution time
@@ -1829,8 +1633,6 @@ static void __guc_exec_queue_destroy_async(struct work_struct *w)
mutex_unlock(&group->list_lock);
}
- if (xe_exec_queue_is_lr(q))
- cancel_work_sync(&ge->lr_tdr);
/* Confirm no work left behind accessing device structures */
cancel_delayed_work_sync(&ge->sched.base.work_tdr);
@@ -2134,9 +1936,6 @@ static int guc_exec_queue_init(struct xe_exec_queue *q)
if (err)
goto err_sched;
- if (xe_exec_queue_is_lr(q))
- INIT_WORK(&q->guc->lr_tdr, xe_guc_exec_queue_lr_cleanup);
-
mutex_lock(&guc->submission_state.lock);
err = alloc_guc_id(guc, q);
@@ -2432,9 +2231,7 @@ static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q)
/* Clean up lost G2H + reset engine state */
if (exec_queue_registered(q)) {
- if (exec_queue_extra_ref(q) || xe_exec_queue_is_lr(q))
- xe_exec_queue_put(q);
- else if (exec_queue_destroyed(q))
+ if (exec_queue_destroyed(q))
__guc_exec_queue_destroy(guc, q);
}
if (q->guc->suspend_pending) {
@@ -2464,9 +2261,6 @@ static void guc_exec_queue_stop(struct xe_guc *guc, struct xe_exec_queue *q)
trace_xe_sched_job_ban(job);
ban = true;
}
- } else if (xe_exec_queue_is_lr(q) &&
- !xe_lrc_ring_is_idle(q->lrc[0])) {
- ban = true;
}
if (ban) {
@@ -2546,11 +2340,8 @@ static void guc_exec_queue_revert_pending_state_change(struct xe_guc *guc,
q->guc->id);
}
- if (pending_enable && !pending_resume &&
- !exec_queue_pending_tdr_exit(q)) {
+ if (pending_enable && !pending_resume) {
clear_exec_queue_registered(q);
- if (xe_exec_queue_is_lr(q))
- xe_exec_queue_put(q);
xe_gt_dbg(guc_to_gt(guc), "Replay REGISTER - guc_id=%d",
q->guc->id);
}
@@ -2558,7 +2349,6 @@ static void guc_exec_queue_revert_pending_state_change(struct xe_guc *guc,
if (pending_enable) {
clear_exec_queue_enabled(q);
clear_exec_queue_pending_resume(q);
- clear_exec_queue_pending_tdr_exit(q);
clear_exec_queue_pending_enable(q);
xe_gt_dbg(guc_to_gt(guc), "Replay ENABLE - guc_id=%d",
q->guc->id);
@@ -2566,11 +2356,7 @@ static void guc_exec_queue_revert_pending_state_change(struct xe_guc *guc,
if (exec_queue_destroyed(q) && exec_queue_registered(q)) {
clear_exec_queue_destroyed(q);
- if (exec_queue_extra_ref(q))
- xe_exec_queue_put(q);
- else
- q->guc->needs_cleanup = true;
- clear_exec_queue_extra_ref(q);
+ q->guc->needs_cleanup = true;
xe_gt_dbg(guc_to_gt(guc), "Replay CLEANUP - guc_id=%d",
q->guc->id);
}
@@ -2588,7 +2374,6 @@ static void guc_exec_queue_revert_pending_state_change(struct xe_guc *guc,
if (!pending_enable)
set_exec_queue_enabled(q);
clear_exec_queue_pending_disable(q);
- clear_exec_queue_check_timeout(q);
xe_gt_dbg(guc_to_gt(guc), "Replay DISABLE - guc_id=%d",
q->guc->id);
}
@@ -2623,10 +2408,7 @@ static void guc_exec_queue_pause(struct xe_guc *guc, struct xe_exec_queue *q)
/* Stop scheduling + flush any DRM scheduler operations */
xe_sched_submission_stop(sched);
- if (xe_exec_queue_is_lr(q))
- cancel_work_sync(&q->guc->lr_tdr);
- else
- cancel_delayed_work_sync(&sched->base.work_tdr);
+ cancel_delayed_work_sync(&sched->base.work_tdr);
guc_exec_queue_revert_pending_state_change(guc, q);
@@ -2753,11 +2535,12 @@ static void guc_exec_queue_unpause_prepare(struct xe_guc *guc,
struct xe_exec_queue *q)
{
struct xe_gpu_scheduler *sched = &q->guc->sched;
- struct xe_sched_job *job = NULL, *__job;
+ struct xe_sched_job *job = NULL;
+ struct drm_sched_job *s_job;
bool restore_replay = false;
- list_for_each_entry(__job, &sched->base.pending_list, drm.list) {
- job = __job;
+ drm_sched_for_each_pending_job(s_job, &sched->base, NULL) {
+ job = to_xe_sched_job(s_job);
restore_replay |= job->restore_replay;
if (restore_replay) {
xe_gt_dbg(guc_to_gt(guc), "Replay JOB - guc_id=%d, seqno=%d",
@@ -2881,7 +2664,7 @@ void xe_guc_submit_unpause_vf(struct xe_guc *guc)
* created after resfix done.
*/
if (q->guc->id != index ||
- !READ_ONCE(q->guc->sched.base.pause_submit))
+ !drm_sched_is_stopped(&q->guc->sched.base))
continue;
guc_exec_queue_unpause(guc, q);
@@ -2967,13 +2750,10 @@ static void handle_sched_done(struct xe_guc *guc, struct xe_exec_queue *q,
q->guc->resume_time = ktime_get();
clear_exec_queue_pending_resume(q);
- clear_exec_queue_pending_tdr_exit(q);
clear_exec_queue_pending_enable(q);
smp_wmb();
wake_up_all(&guc->ct.wq);
} else {
- bool check_timeout = exec_queue_check_timeout(q);
-
xe_gt_assert(guc_to_gt(guc), runnable_state == 0);
xe_gt_assert(guc_to_gt(guc), exec_queue_pending_disable(q));
@@ -2981,11 +2761,11 @@ static void handle_sched_done(struct xe_guc *guc, struct xe_exec_queue *q,
suspend_fence_signal(q);
clear_exec_queue_pending_disable(q);
} else {
- if (exec_queue_banned(q) || check_timeout) {
+ if (exec_queue_banned(q)) {
smp_wmb();
wake_up_all(&guc->ct.wq);
}
- if (!check_timeout && exec_queue_destroyed(q)) {
+ if (exec_queue_destroyed(q)) {
/*
* Make sure to clear the pending_disable only
* after sampling the destroyed state. We want
@@ -3048,11 +2828,7 @@ static void handle_deregister_done(struct xe_guc *guc, struct xe_exec_queue *q)
trace_xe_exec_queue_deregister_done(q);
clear_exec_queue_registered(q);
-
- if (exec_queue_extra_ref(q) || xe_exec_queue_is_lr(q))
- xe_exec_queue_put(q);
- else
- __guc_exec_queue_destroy(guc, q);
+ __guc_exec_queue_destroy(guc, q);
}
int xe_guc_deregister_done_handler(struct xe_guc *guc, u32 *msg, u32 len)
@@ -3386,29 +3162,6 @@ xe_guc_exec_queue_snapshot_capture(struct xe_exec_queue *q)
snapshot->multi_queue.primary = xe_exec_queue_multi_queue_primary(q)->guc->id;
snapshot->multi_queue.pos = q->multi_queue.pos;
}
- spin_lock(&sched->base.job_list_lock);
- snapshot->pending_list_size = list_count_nodes(&sched->base.pending_list);
- snapshot->pending_list = kmalloc_array(snapshot->pending_list_size,
- sizeof(struct pending_list_snapshot),
- GFP_ATOMIC);
-
- if (snapshot->pending_list) {
- struct xe_sched_job *job_iter;
-
- i = 0;
- list_for_each_entry(job_iter, &sched->base.pending_list, drm.list) {
- snapshot->pending_list[i].seqno =
- xe_sched_job_seqno(job_iter);
- snapshot->pending_list[i].fence =
- dma_fence_is_signaled(job_iter->fence) ? 1 : 0;
- snapshot->pending_list[i].finished =
- dma_fence_is_signaled(&job_iter->drm.s_fence->finished)
- ? 1 : 0;
- i++;
- }
- }
-
- spin_unlock(&sched->base.job_list_lock);
return snapshot;
}
@@ -3472,13 +3225,6 @@ xe_guc_exec_queue_snapshot_print(struct xe_guc_submit_exec_queue_snapshot *snaps
drm_printf(p, "\tMulti queue primary GuC ID: %d\n", snapshot->multi_queue.primary);
drm_printf(p, "\tMulti queue position: %d\n", snapshot->multi_queue.pos);
}
-
- for (i = 0; snapshot->pending_list && i < snapshot->pending_list_size;
- i++)
- drm_printf(p, "\tJob: seqno=%d, fence=%d, finished=%d\n",
- snapshot->pending_list[i].seqno,
- snapshot->pending_list[i].fence,
- snapshot->pending_list[i].finished);
}
/**
@@ -3501,7 +3247,6 @@ void xe_guc_exec_queue_snapshot_free(struct xe_guc_submit_exec_queue_snapshot *s
xe_lrc_snapshot_free(snapshot->lrc[i]);
kfree(snapshot->lrc);
}
- kfree(snapshot->pending_list);
kfree(snapshot);
}
diff --git a/drivers/gpu/drm/xe/xe_guc_submit_types.h b/drivers/gpu/drm/xe/xe_guc_submit_types.h
index 25e29e85502c..5ccc5f959bb3 100644
--- a/drivers/gpu/drm/xe/xe_guc_submit_types.h
+++ b/drivers/gpu/drm/xe/xe_guc_submit_types.h
@@ -61,12 +61,6 @@ struct guc_submit_parallel_scratch {
u32 wq[WQ_SIZE / sizeof(u32)];
};
-struct pending_list_snapshot {
- u32 seqno;
- bool fence;
- bool finished;
-};
-
/**
* struct xe_guc_submit_exec_queue_snapshot - Snapshot for devcoredump
*/
@@ -147,11 +141,6 @@ struct xe_guc_submit_exec_queue_snapshot {
/** @valid: The exec queue is part of a multi queue group */
bool valid;
} multi_queue;
-
- /** @pending_list_size: Size of the pending list snapshot array */
- int pending_list_size;
- /** @pending_list: snapshot of the pending list info */
- struct pending_list_snapshot *pending_list;
};
#endif
diff --git a/drivers/gpu/drm/xe/xe_guc_tlb_inval.c b/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
index 6532a88d51e2..774467befbb9 100644
--- a/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
+++ b/drivers/gpu/drm/xe/xe_guc_tlb_inval.c
@@ -97,6 +97,7 @@ static int send_tlb_inval_ggtt(struct xe_tlb_inval *tlb_inval, u32 seqno)
static int send_page_reclaim(struct xe_guc *guc, u32 seqno,
u64 gpu_addr)
{
+ struct xe_gt *gt = guc_to_gt(guc);
u32 action[] = {
XE_GUC_ACTION_PAGE_RECLAMATION,
seqno,
@@ -104,6 +105,8 @@ static int send_page_reclaim(struct xe_guc *guc, u32 seqno,
upper_32_bits(gpu_addr),
};
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_ISSUED_COUNT, 1);
+
return xe_guc_ct_send(&guc->ct, action, ARRAY_SIZE(action),
G2H_LEN_DW_PAGE_RECLAMATION, 1);
}
diff --git a/drivers/gpu/drm/xe/xe_heci_gsc.c b/drivers/gpu/drm/xe/xe_heci_gsc.c
index 495cdd4f948d..c1f15313f92e 100644
--- a/drivers/gpu/drm/xe/xe_heci_gsc.c
+++ b/drivers/gpu/drm/xe/xe_heci_gsc.c
@@ -11,7 +11,6 @@
#include <drm/drm_print.h>
#include "xe_device_types.h"
-#include "xe_drv.h"
#include "xe_heci_gsc.h"
#include "regs/xe_gsc_regs.h"
#include "xe_platform_types.h"
diff --git a/drivers/gpu/drm/xe/xe_huc.c b/drivers/gpu/drm/xe/xe_huc.c
index 4212162913af..57afe21444b1 100644
--- a/drivers/gpu/drm/xe/xe_huc.c
+++ b/drivers/gpu/drm/xe/xe_huc.c
@@ -12,7 +12,6 @@
#include "abi/gsc_pxp_commands_abi.h"
#include "regs/xe_gsc_regs.h"
#include "regs/xe_guc_regs.h"
-#include "xe_assert.h"
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_force_wake.h"
diff --git a/drivers/gpu/drm/xe/xe_huc_debugfs.c b/drivers/gpu/drm/xe/xe_huc_debugfs.c
index df9c4d79b710..80829967b3d7 100644
--- a/drivers/gpu/drm/xe/xe_huc_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_huc_debugfs.c
@@ -7,11 +7,10 @@
#include <drm/drm_debugfs.h>
#include <drm/drm_managed.h>
+#include <drm/drm_print.h>
-#include "xe_device.h"
-#include "xe_gt.h"
+#include "xe_gt_types.h"
#include "xe_huc.h"
-#include "xe_macros.h"
#include "xe_pm.h"
static struct xe_gt *
diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c
index 6a9e2a4272dd..4d3ee5226e3a 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine.c
@@ -33,7 +33,6 @@
#include "xe_hw_fence.h"
#include "xe_irq.h"
#include "xe_lrc.h"
-#include "xe_macros.h"
#include "xe_mmio.h"
#include "xe_reg_sr.h"
#include "xe_reg_whitelist.h"
diff --git a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
index cb45cdceef67..3c65becb39ad 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
@@ -7,7 +7,7 @@
#include <linux/kobject.h>
#include <linux/sysfs.h>
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_gt.h"
#include "xe_hw_engine_class_sysfs.h"
#include "xe_pm.h"
diff --git a/drivers/gpu/drm/xe/xe_hw_engine_group.c b/drivers/gpu/drm/xe/xe_hw_engine_group.c
index f69a32c27458..2ef33dfbe3a2 100644
--- a/drivers/gpu/drm/xe/xe_hw_engine_group.c
+++ b/drivers/gpu/drm/xe/xe_hw_engine_group.c
@@ -6,7 +6,7 @@
#include <drm/drm_managed.h>
#include "xe_assert.h"
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_exec_queue.h"
#include "xe_gt.h"
#include "xe_gt_stats.h"
diff --git a/drivers/gpu/drm/xe/xe_hw_fence.c b/drivers/gpu/drm/xe/xe_hw_fence.c
index f6057456e460..ae8ed15b64c5 100644
--- a/drivers/gpu/drm/xe/xe_hw_fence.c
+++ b/drivers/gpu/drm/xe/xe_hw_fence.c
@@ -8,9 +8,7 @@
#include <linux/device.h>
#include <linux/slab.h>
-#include "xe_bo.h"
-#include "xe_device.h"
-#include "xe_gt.h"
+#include "xe_device_types.h"
#include "xe_hw_engine.h"
#include "xe_macros.h"
#include "xe_map.h"
@@ -108,22 +106,6 @@ void xe_hw_fence_irq_run(struct xe_hw_fence_irq *irq)
irq_work_queue(&irq->work);
}
-void xe_hw_fence_irq_stop(struct xe_hw_fence_irq *irq)
-{
- spin_lock_irq(&irq->lock);
- irq->enabled = false;
- spin_unlock_irq(&irq->lock);
-}
-
-void xe_hw_fence_irq_start(struct xe_hw_fence_irq *irq)
-{
- spin_lock_irq(&irq->lock);
- irq->enabled = true;
- spin_unlock_irq(&irq->lock);
-
- irq_work_queue(&irq->work);
-}
-
void xe_hw_fence_ctx_init(struct xe_hw_fence_ctx *ctx, struct xe_gt *gt,
struct xe_hw_fence_irq *irq, const char *name)
{
diff --git a/drivers/gpu/drm/xe/xe_hw_fence.h b/drivers/gpu/drm/xe/xe_hw_fence.h
index f13a1c4982c7..599492c13f80 100644
--- a/drivers/gpu/drm/xe/xe_hw_fence.h
+++ b/drivers/gpu/drm/xe/xe_hw_fence.h
@@ -17,8 +17,6 @@ void xe_hw_fence_module_exit(void);
void xe_hw_fence_irq_init(struct xe_hw_fence_irq *irq);
void xe_hw_fence_irq_finish(struct xe_hw_fence_irq *irq);
void xe_hw_fence_irq_run(struct xe_hw_fence_irq *irq);
-void xe_hw_fence_irq_stop(struct xe_hw_fence_irq *irq);
-void xe_hw_fence_irq_start(struct xe_hw_fence_irq *irq);
void xe_hw_fence_ctx_init(struct xe_hw_fence_ctx *ctx, struct xe_gt *gt,
struct xe_hw_fence_irq *irq, const char *name);
diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c
index ff2aea52ef75..baf277955b33 100644
--- a/drivers/gpu/drm/xe/xe_hwmon.c
+++ b/drivers/gpu/drm/xe/xe_hwmon.c
@@ -39,10 +39,16 @@ enum xe_hwmon_reg_operation {
REG_READ64,
};
+#define MAX_VRAM_CHANNELS (16)
+
enum xe_hwmon_channel {
CHANNEL_CARD,
CHANNEL_PKG,
CHANNEL_VRAM,
+ CHANNEL_MCTRL,
+ CHANNEL_PCIE,
+ CHANNEL_VRAM_N,
+ CHANNEL_VRAM_N_MAX = CHANNEL_VRAM_N + MAX_VRAM_CHANNELS,
CHANNEL_MAX,
};
@@ -53,6 +59,15 @@ enum xe_fan_channel {
FAN_MAX,
};
+enum xe_temp_limit {
+ TEMP_LIMIT_PKG_SHUTDOWN,
+ TEMP_LIMIT_PKG_CRIT,
+ TEMP_LIMIT_MEM_SHUTDOWN,
+ TEMP_LIMIT_PKG_MAX,
+ TEMP_LIMIT_MEM_CRIT,
+ TEMP_LIMIT_MAX
+};
+
/* Attribute index for powerX_xxx_interval sysfs entries */
enum sensor_attr_power {
SENSOR_INDEX_PSYS_PL1,
@@ -91,6 +106,12 @@ enum sensor_attr_power {
*/
#define PL_WRITE_MBX_TIMEOUT_MS (1)
+/* Index of memory controller in READ_THERMAL_DATA output */
+#define TEMP_INDEX_MCTRL 2
+
+/* Maximum characters in hwmon label name */
+#define MAX_LABEL_SIZE 16
+
/**
* struct xe_hwmon_energy_info - to accumulate energy
*/
@@ -112,6 +133,24 @@ struct xe_hwmon_fan_info {
};
/**
+ * struct xe_hwmon_thermal_info - to store temperature data
+ */
+struct xe_hwmon_thermal_info {
+ union {
+ /** @limit: temperatures limits */
+ u8 limit[TEMP_LIMIT_MAX];
+ /** @data: temperature limits in dwords */
+ u32 data[DIV_ROUND_UP(TEMP_LIMIT_MAX, sizeof(u32))];
+ };
+ /** @count: no of temperature sensors available for the platform */
+ u8 count;
+ /** @value: signed value from each sensor */
+ s8 value[U8_MAX];
+ /** @vram_label: vram label names */
+ char vram_label[MAX_VRAM_CHANNELS][MAX_LABEL_SIZE];
+};
+
+/**
* struct xe_hwmon - xe hwmon data structure
*/
struct xe_hwmon {
@@ -137,7 +176,8 @@ struct xe_hwmon {
u32 pl1_on_boot[CHANNEL_MAX];
/** @pl2_on_boot: power limit PL2 on boot */
u32 pl2_on_boot[CHANNEL_MAX];
-
+ /** @temp: Temperature info */
+ struct xe_hwmon_thermal_info temp;
};
static int xe_hwmon_pcode_read_power_limit(const struct xe_hwmon *hwmon, u32 attr, int channel,
@@ -224,6 +264,8 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg
return BMG_PACKAGE_TEMPERATURE;
else if (channel == CHANNEL_VRAM)
return BMG_VRAM_TEMPERATURE;
+ else if (in_range(channel, CHANNEL_VRAM_N, CHANNEL_VRAM_N_MAX))
+ return BMG_VRAM_TEMPERATURE_N(channel - CHANNEL_VRAM_N);
} else if (xe->info.platform == XE_DG2) {
if (channel == CHANNEL_PKG)
return PCU_CR_PACKAGE_TEMPERATURE;
@@ -677,8 +719,29 @@ static const struct attribute_group *hwmon_groups[] = {
};
static const struct hwmon_channel_info * const hwmon_info[] = {
- HWMON_CHANNEL_INFO(temp, HWMON_T_LABEL, HWMON_T_INPUT | HWMON_T_LABEL,
- HWMON_T_INPUT | HWMON_T_LABEL),
+ HWMON_CHANNEL_INFO(temp,
+ HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL |
+ HWMON_T_MAX,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL,
+ HWMON_T_CRIT | HWMON_T_EMERGENCY | HWMON_T_INPUT | HWMON_T_LABEL),
HWMON_CHANNEL_INFO(power, HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_LABEL | HWMON_P_CRIT |
HWMON_P_CAP,
HWMON_P_MAX | HWMON_P_RATED_MAX | HWMON_P_LABEL | HWMON_P_CAP),
@@ -689,6 +752,75 @@ static const struct hwmon_channel_info * const hwmon_info[] = {
NULL
};
+static int xe_hwmon_pcode_read_thermal_info(struct xe_hwmon *hwmon)
+{
+ struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
+ u32 config = 0;
+ int ret;
+
+ ret = xe_pcode_read(root_tile, PCODE_MBOX(PCODE_THERMAL_INFO, READ_THERMAL_LIMITS, 0),
+ &hwmon->temp.data[0], &hwmon->temp.data[1]);
+ if (ret)
+ return ret;
+
+ drm_dbg(&hwmon->xe->drm, "thermal info read val 0x%x val1 0x%x\n",
+ hwmon->temp.data[0], hwmon->temp.data[1]);
+
+ ret = xe_pcode_read(root_tile, PCODE_MBOX(PCODE_THERMAL_INFO, READ_THERMAL_CONFIG, 0),
+ &config, NULL);
+ if (ret)
+ return ret;
+
+ drm_dbg(&hwmon->xe->drm, "thermal config count 0x%x\n", config);
+ hwmon->temp.count = REG_FIELD_GET(TEMP_MASK, config);
+
+ return ret;
+}
+
+static int get_mc_temp(struct xe_hwmon *hwmon, long *val)
+{
+ struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
+ u32 *dword = (u32 *)hwmon->temp.value;
+ s32 average = 0;
+ int ret, i;
+
+ for (i = 0; i < DIV_ROUND_UP(TEMP_LIMIT_MAX, sizeof(u32)); i++) {
+ ret = xe_pcode_read(root_tile, PCODE_MBOX(PCODE_THERMAL_INFO, READ_THERMAL_DATA, i),
+ (dword + i), NULL);
+ if (ret)
+ return ret;
+ drm_dbg(&hwmon->xe->drm, "thermal data for group %d val 0x%x\n", i, dword[i]);
+ }
+
+ for (i = TEMP_INDEX_MCTRL; i < hwmon->temp.count - 1; i++)
+ average += hwmon->temp.value[i];
+
+ average /= (hwmon->temp.count - TEMP_INDEX_MCTRL - 1);
+ *val = average * MILLIDEGREE_PER_DEGREE;
+ return 0;
+}
+
+static int get_pcie_temp(struct xe_hwmon *hwmon, long *val)
+{
+ struct xe_tile *root_tile = xe_device_get_root_tile(hwmon->xe);
+ u32 data = 0;
+ int ret;
+
+ ret = xe_pcode_read(root_tile, PCODE_MBOX(PCODE_THERMAL_INFO, READ_THERMAL_DATA,
+ PCIE_SENSOR_GROUP_ID), &data, NULL);
+ if (ret)
+ return ret;
+
+ /* Sensor offset is different for G21 */
+ if (hwmon->xe->info.subplatform != XE_SUBPLATFORM_BATTLEMAGE_G21)
+ data = REG_FIELD_GET(PCIE_SENSOR_MASK, data);
+
+ data = REG_FIELD_GET(TEMP_MASK, data);
+ *val = (s8)data * MILLIDEGREE_PER_DEGREE;
+
+ return 0;
+}
+
/* I1 is exposed as power_crit or as curr_crit depending on bit 31 */
static int xe_hwmon_pcode_read_i1(const struct xe_hwmon *hwmon, u32 *uval)
{
@@ -783,13 +915,77 @@ static void xe_hwmon_get_voltage(struct xe_hwmon *hwmon, int channel, long *valu
*value = DIV_ROUND_CLOSEST(REG_FIELD_GET(VOLTAGE_MASK, reg_val) * 2500, SF_VOLTAGE);
}
+static inline bool is_vram_ch_available(struct xe_hwmon *hwmon, int channel)
+{
+ struct xe_mmio *mmio = xe_root_tile_mmio(hwmon->xe);
+ int vram_id = channel - CHANNEL_VRAM_N;
+ struct xe_reg vram_reg;
+
+ vram_reg = xe_hwmon_get_reg(hwmon, REG_TEMP, channel);
+ if (!xe_reg_is_valid(vram_reg) || !xe_mmio_read32(mmio, vram_reg))
+ return false;
+
+ /* Create label only for available vram channel */
+ sprintf(hwmon->temp.vram_label[vram_id], "vram_ch_%d", vram_id);
+ return true;
+}
+
static umode_t
xe_hwmon_temp_is_visible(struct xe_hwmon *hwmon, u32 attr, int channel)
{
switch (attr) {
+ case hwmon_temp_emergency:
+ switch (channel) {
+ case CHANNEL_PKG:
+ return hwmon->temp.limit[TEMP_LIMIT_PKG_SHUTDOWN] ? 0444 : 0;
+ case CHANNEL_VRAM:
+ return hwmon->temp.limit[TEMP_LIMIT_MEM_SHUTDOWN] ? 0444 : 0;
+ case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
+ return hwmon->temp.count ? 0444 : 0;
+ case CHANNEL_VRAM_N...CHANNEL_VRAM_N_MAX:
+ return (is_vram_ch_available(hwmon, channel) &&
+ hwmon->temp.limit[TEMP_LIMIT_MEM_SHUTDOWN]) ? 0444 : 0;
+ default:
+ return 0;
+ }
+ case hwmon_temp_crit:
+ switch (channel) {
+ case CHANNEL_PKG:
+ return hwmon->temp.limit[TEMP_LIMIT_PKG_CRIT] ? 0444 : 0;
+ case CHANNEL_VRAM:
+ return hwmon->temp.limit[TEMP_LIMIT_MEM_CRIT] ? 0444 : 0;
+ case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
+ return hwmon->temp.count ? 0444 : 0;
+ case CHANNEL_VRAM_N...CHANNEL_VRAM_N_MAX:
+ return (is_vram_ch_available(hwmon, channel) &&
+ hwmon->temp.limit[TEMP_LIMIT_MEM_CRIT]) ? 0444 : 0;
+ default:
+ return 0;
+ }
+ case hwmon_temp_max:
+ switch (channel) {
+ case CHANNEL_PKG:
+ return hwmon->temp.limit[TEMP_LIMIT_PKG_MAX] ? 0444 : 0;
+ default:
+ return 0;
+ }
case hwmon_temp_input:
case hwmon_temp_label:
- return xe_reg_is_valid(xe_hwmon_get_reg(hwmon, REG_TEMP, channel)) ? 0444 : 0;
+ switch (channel) {
+ case CHANNEL_PKG:
+ case CHANNEL_VRAM:
+ return xe_reg_is_valid(xe_hwmon_get_reg(hwmon, REG_TEMP,
+ channel)) ? 0444 : 0;
+ case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
+ return hwmon->temp.count ? 0444 : 0;
+ case CHANNEL_VRAM_N...CHANNEL_VRAM_N_MAX:
+ return is_vram_ch_available(hwmon, channel) ? 0444 : 0;
+ default:
+ return 0;
+ }
default:
return 0;
}
@@ -803,11 +999,67 @@ xe_hwmon_temp_read(struct xe_hwmon *hwmon, u32 attr, int channel, long *val)
switch (attr) {
case hwmon_temp_input:
- reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_TEMP, channel));
+ switch (channel) {
+ case CHANNEL_PKG:
+ case CHANNEL_VRAM:
+ reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_TEMP, channel));
- /* HW register value is in degrees Celsius, convert to millidegrees. */
- *val = REG_FIELD_GET(TEMP_MASK, reg_val) * MILLIDEGREE_PER_DEGREE;
- return 0;
+ /* HW register value is in degrees Celsius, convert to millidegrees. */
+ *val = REG_FIELD_GET(TEMP_MASK, reg_val) * MILLIDEGREE_PER_DEGREE;
+ return 0;
+ case CHANNEL_MCTRL:
+ return get_mc_temp(hwmon, val);
+ case CHANNEL_PCIE:
+ return get_pcie_temp(hwmon, val);
+ case CHANNEL_VRAM_N...CHANNEL_VRAM_N_MAX:
+ reg_val = xe_mmio_read32(mmio, xe_hwmon_get_reg(hwmon, REG_TEMP, channel));
+ /*
+ * This temperature format is 24 bit [31:8] signed integer and 8 bit
+ * [7:0] fraction.
+ */
+ *val = (s32)(REG_FIELD_GET(TEMP_MASK_VRAM_N, reg_val)) *
+ (REG_FIELD_GET(TEMP_SIGN_MASK, reg_val) ? -1 : 1) *
+ MILLIDEGREE_PER_DEGREE;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+ case hwmon_temp_emergency:
+ switch (channel) {
+ case CHANNEL_PKG:
+ case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
+ *val = hwmon->temp.limit[TEMP_LIMIT_PKG_SHUTDOWN] * MILLIDEGREE_PER_DEGREE;
+ return 0;
+ case CHANNEL_VRAM:
+ case CHANNEL_VRAM_N...CHANNEL_VRAM_N_MAX:
+ *val = hwmon->temp.limit[TEMP_LIMIT_MEM_SHUTDOWN] * MILLIDEGREE_PER_DEGREE;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+ case hwmon_temp_crit:
+ switch (channel) {
+ case CHANNEL_PKG:
+ case CHANNEL_MCTRL:
+ case CHANNEL_PCIE:
+ *val = hwmon->temp.limit[TEMP_LIMIT_PKG_CRIT] * MILLIDEGREE_PER_DEGREE;
+ return 0;
+ case CHANNEL_VRAM:
+ case CHANNEL_VRAM_N...CHANNEL_VRAM_N_MAX:
+ *val = hwmon->temp.limit[TEMP_LIMIT_MEM_CRIT] * MILLIDEGREE_PER_DEGREE;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+ case hwmon_temp_max:
+ switch (channel) {
+ case CHANNEL_PKG:
+ *val = hwmon->temp.limit[TEMP_LIMIT_PKG_MAX] * MILLIDEGREE_PER_DEGREE;
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
default:
return -EOPNOTSUPP;
}
@@ -1163,12 +1415,20 @@ static int xe_hwmon_read_label(struct device *dev,
enum hwmon_sensor_types type,
u32 attr, int channel, const char **str)
{
+ struct xe_hwmon *hwmon = dev_get_drvdata(dev);
+
switch (type) {
case hwmon_temp:
if (channel == CHANNEL_PKG)
*str = "pkg";
else if (channel == CHANNEL_VRAM)
*str = "vram";
+ else if (channel == CHANNEL_MCTRL)
+ *str = "mctrl";
+ else if (channel == CHANNEL_PCIE)
+ *str = "pcie";
+ else if (in_range(channel, CHANNEL_VRAM_N, CHANNEL_VRAM_N_MAX))
+ *str = hwmon->temp.vram_label[channel - CHANNEL_VRAM_N];
return 0;
case hwmon_power:
case hwmon_energy:
@@ -1263,6 +1523,9 @@ xe_hwmon_get_preregistration_info(struct xe_hwmon *hwmon)
for (channel = 0; channel < FAN_MAX; channel++)
if (xe_hwmon_is_visible(hwmon, hwmon_fan, hwmon_fan_input, channel))
xe_hwmon_fan_input_read(hwmon, channel, &fan_speed);
+
+ if (hwmon->xe->info.has_mbx_thermal_info && xe_hwmon_pcode_read_thermal_info(hwmon))
+ drm_warn(&hwmon->xe->drm, "Thermal mailbox not supported by card firmware\n");
}
int xe_hwmon_register(struct xe_device *xe)
diff --git a/drivers/gpu/drm/xe/xe_i2c.c b/drivers/gpu/drm/xe/xe_i2c.c
index 8eccbae05705..1e1fb72e49bf 100644
--- a/drivers/gpu/drm/xe/xe_i2c.c
+++ b/drivers/gpu/drm/xe/xe_i2c.c
@@ -5,6 +5,7 @@
* Copyright (C) 2025 Intel Corporation.
*/
+#include <drm/drm_print.h>
#include <linux/array_size.h>
#include <linux/container_of.h>
#include <linux/device.h>
@@ -26,11 +27,11 @@
#include "regs/xe_i2c_regs.h"
#include "regs/xe_irq_regs.h"
-#include "xe_device.h"
#include "xe_device_types.h"
#include "xe_i2c.h"
#include "xe_mmio.h"
-#include "xe_platform_types.h"
+#include "xe_sriov.h"
+#include "xe_survivability_mode.h"
/**
* DOC: Xe I2C devices
@@ -213,11 +214,13 @@ static const struct irq_domain_ops xe_i2c_irq_ops = {
.map = xe_i2c_irq_map,
};
-static int xe_i2c_create_irq(struct xe_i2c *i2c)
+static int xe_i2c_create_irq(struct xe_device *xe)
{
+ struct xe_i2c *i2c = xe->i2c;
struct irq_domain *domain;
- if (!(i2c->ep.capabilities & XE_I2C_EP_CAP_IRQ))
+ if (!(i2c->ep.capabilities & XE_I2C_EP_CAP_IRQ) ||
+ xe_survivability_mode_is_boot_enabled(xe))
return 0;
domain = irq_domain_create_linear(dev_fwnode(i2c->drm_dev), 1, &xe_i2c_irq_ops, NULL);
@@ -351,7 +354,7 @@ int xe_i2c_probe(struct xe_device *xe)
if (ret)
return ret;
- ret = xe_i2c_create_irq(i2c);
+ ret = xe_i2c_create_irq(xe);
if (ret)
goto err_unregister_notifier;
diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c
index baf5d2c6e802..7560a45f7f64 100644
--- a/drivers/gpu/drm/xe/xe_irq.c
+++ b/drivers/gpu/drm/xe/xe_irq.c
@@ -10,7 +10,6 @@
#include <drm/drm_managed.h>
#include "display/xe_display.h"
-#include "regs/xe_guc_regs.h"
#include "regs/xe_irq_regs.h"
#include "xe_device.h"
#include "xe_drv.h"
diff --git a/drivers/gpu/drm/xe/xe_late_bind_fw_types.h b/drivers/gpu/drm/xe/xe_late_bind_fw_types.h
index 0f5da89ce98b..2a8a985c37e7 100644
--- a/drivers/gpu/drm/xe/xe_late_bind_fw_types.h
+++ b/drivers/gpu/drm/xe/xe_late_bind_fw_types.h
@@ -15,10 +15,12 @@
#define XE_LB_MAX_PAYLOAD_SIZE SZ_4K
/**
- * xe_late_bind_fw_id - enum to determine late binding fw index
+ * enum xe_late_bind_fw_id - enum to determine late binding fw index
*/
enum xe_late_bind_fw_id {
+ /** @XE_LB_FW_FAN_CONTROL: Fan control */
XE_LB_FW_FAN_CONTROL = 0,
+ /** @XE_LB_FW_MAX_ID: Number of IDs */
XE_LB_FW_MAX_ID
};
diff --git a/drivers/gpu/drm/xe/xe_lmtt.c b/drivers/gpu/drm/xe/xe_lmtt.c
index 3059ea6525bc..2077e1ef8b43 100644
--- a/drivers/gpu/drm/xe/xe_lmtt.c
+++ b/drivers/gpu/drm/xe/xe_lmtt.c
@@ -289,7 +289,7 @@ void xe_lmtt_invalidate_hw(struct xe_lmtt *lmtt)
ERR_PTR(err));
if (xe_device_has_mert(xe) && xe_tile_is_root(tile)) {
- err = xe_mert_invalidate_lmtt(tile);
+ err = xe_mert_invalidate_lmtt(xe);
if (err)
xe_tile_sriov_err(tile, "MERT LMTT invalidation failed (%pe)",
ERR_PTR(err));
diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c
index 70eae7d03a27..f4f31bc240d9 100644
--- a/drivers/gpu/drm/xe/xe_lrc.c
+++ b/drivers/gpu/drm/xe/xe_lrc.c
@@ -857,7 +857,7 @@ u32 xe_lrc_ctx_timestamp_udw_ggtt_addr(struct xe_lrc *lrc)
*
* Returns: ctx timestamp value
*/
-u64 xe_lrc_ctx_timestamp(struct xe_lrc *lrc)
+static u64 xe_lrc_ctx_timestamp(struct xe_lrc *lrc)
{
struct xe_device *xe = lrc_to_xe(lrc);
struct iosys_map map;
@@ -1068,6 +1068,9 @@ static ssize_t setup_utilization_wa(struct xe_lrc *lrc,
{
u32 *cmd = batch;
+ if (IS_SRIOV_VF(gt_to_xe(lrc->gt)))
+ return 0;
+
if (xe_gt_WARN_ON(lrc->gt, max_len < 12))
return -ENOSPC;
@@ -2406,35 +2409,31 @@ static int get_ctx_timestamp(struct xe_lrc *lrc, u32 engine_id, u64 *reg_ctx_ts)
}
/**
- * xe_lrc_update_timestamp() - Update ctx timestamp
+ * xe_lrc_timestamp() - Current ctx timestamp
* @lrc: Pointer to the lrc.
- * @old_ts: Old timestamp value
*
- * Populate @old_ts current saved ctx timestamp, read new ctx timestamp and
- * update saved value. With support for active contexts, the calculation may be
- * slightly racy, so follow a read-again logic to ensure that the context is
- * still active before returning the right timestamp.
+ * Return latest ctx timestamp. With support for active contexts, the
+ * calculation may bb slightly racy, so follow a read-again logic to ensure that
+ * the context is still active before returning the right timestamp.
*
* Returns: New ctx timestamp value
*/
-u64 xe_lrc_update_timestamp(struct xe_lrc *lrc, u64 *old_ts)
+u64 xe_lrc_timestamp(struct xe_lrc *lrc)
{
- u64 lrc_ts, reg_ts;
+ u64 lrc_ts, reg_ts, new_ts;
u32 engine_id;
- *old_ts = lrc->ctx_timestamp;
-
lrc_ts = xe_lrc_ctx_timestamp(lrc);
/* CTX_TIMESTAMP mmio read is invalid on VF, so return the LRC value */
if (IS_SRIOV_VF(lrc_to_xe(lrc))) {
- lrc->ctx_timestamp = lrc_ts;
+ new_ts = lrc_ts;
goto done;
}
if (lrc_ts == CONTEXT_ACTIVE) {
engine_id = xe_lrc_engine_id(lrc);
if (!get_ctx_timestamp(lrc, engine_id, &reg_ts))
- lrc->ctx_timestamp = reg_ts;
+ new_ts = reg_ts;
/* read lrc again to ensure context is still active */
lrc_ts = xe_lrc_ctx_timestamp(lrc);
@@ -2445,9 +2444,27 @@ u64 xe_lrc_update_timestamp(struct xe_lrc *lrc, u64 *old_ts)
* be a separate if condition.
*/
if (lrc_ts != CONTEXT_ACTIVE)
- lrc->ctx_timestamp = lrc_ts;
+ new_ts = lrc_ts;
done:
+ return new_ts;
+}
+
+/**
+ * xe_lrc_update_timestamp() - Update ctx timestamp
+ * @lrc: Pointer to the lrc.
+ * @old_ts: Old timestamp value
+ *
+ * Populate @old_ts current saved ctx timestamp, read new ctx timestamp and
+ * update saved value.
+ *
+ * Returns: New ctx timestamp value
+ */
+u64 xe_lrc_update_timestamp(struct xe_lrc *lrc, u64 *old_ts)
+{
+ *old_ts = lrc->ctx_timestamp;
+ lrc->ctx_timestamp = xe_lrc_timestamp(lrc);
+
trace_xe_lrc_update_timestamp(lrc, *old_ts);
return lrc->ctx_timestamp;
diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h
index 8acf85273c1a..c307a3fd9ea2 100644
--- a/drivers/gpu/drm/xe/xe_lrc.h
+++ b/drivers/gpu/drm/xe/xe_lrc.h
@@ -145,7 +145,6 @@ void xe_lrc_snapshot_free(struct xe_lrc_snapshot *snapshot);
u32 xe_lrc_ctx_timestamp_ggtt_addr(struct xe_lrc *lrc);
u32 xe_lrc_ctx_timestamp_udw_ggtt_addr(struct xe_lrc *lrc);
-u64 xe_lrc_ctx_timestamp(struct xe_lrc *lrc);
u32 xe_lrc_ctx_job_timestamp_ggtt_addr(struct xe_lrc *lrc);
u32 xe_lrc_ctx_job_timestamp(struct xe_lrc *lrc);
int xe_lrc_setup_wa_bb_with_scratch(struct xe_lrc *lrc, struct xe_hw_engine *hwe,
@@ -165,4 +164,6 @@ int xe_lrc_setup_wa_bb_with_scratch(struct xe_lrc *lrc, struct xe_hw_engine *hwe
*/
u64 xe_lrc_update_timestamp(struct xe_lrc *lrc, u64 *old_ts);
+u64 xe_lrc_timestamp(struct xe_lrc *lrc);
+
#endif
diff --git a/drivers/gpu/drm/xe/xe_memirq.c b/drivers/gpu/drm/xe/xe_memirq.c
index b0c7ce0a5d1e..811e07136efb 100644
--- a/drivers/gpu/drm/xe/xe_memirq.c
+++ b/drivers/gpu/drm/xe/xe_memirq.c
@@ -7,7 +7,6 @@
#include "regs/xe_guc_regs.h"
#include "regs/xe_irq_regs.h"
-#include "regs/xe_regs.h"
#include "xe_assert.h"
#include "xe_bo.h"
@@ -16,7 +15,6 @@
#include "xe_gt.h"
#include "xe_guc.h"
#include "xe_hw_engine.h"
-#include "xe_map.h"
#include "xe_memirq.h"
#include "xe_tile_printk.h"
diff --git a/drivers/gpu/drm/xe/xe_mert.c b/drivers/gpu/drm/xe/xe_mert.c
index f7689e922953..f637df95418b 100644
--- a/drivers/gpu/drm/xe/xe_mert.c
+++ b/drivers/gpu/drm/xe/xe_mert.c
@@ -9,25 +9,38 @@
#include "xe_device.h"
#include "xe_mert.h"
#include "xe_mmio.h"
+#include "xe_sriov_printk.h"
#include "xe_tile.h"
/**
- * xe_mert_invalidate_lmtt - Invalidate MERT LMTT
- * @tile: the &xe_tile
+ * xe_mert_init_early() - Initialize MERT data
+ * @xe: the &xe_device with MERT to init
+ */
+void xe_mert_init_early(struct xe_device *xe)
+{
+ struct xe_tile *tile = xe_device_get_root_tile(xe);
+ struct xe_mert *mert = &tile->mert;
+
+ spin_lock_init(&mert->lock);
+ init_completion(&mert->tlb_inv_done);
+}
+
+/**
+ * xe_mert_invalidate_lmtt() - Invalidate MERT LMTT
+ * @xe: the &xe_device with MERT
*
* Trigger invalidation of the MERT LMTT and wait for completion.
*
* Return: 0 on success or -ETIMEDOUT in case of a timeout.
*/
-int xe_mert_invalidate_lmtt(struct xe_tile *tile)
+int xe_mert_invalidate_lmtt(struct xe_device *xe)
{
- struct xe_device *xe = tile_to_xe(tile);
+ struct xe_tile *tile = xe_device_get_root_tile(xe);
struct xe_mert *mert = &tile->mert;
const long timeout = HZ / 4;
unsigned long flags;
xe_assert(xe, xe_device_has_mert(xe));
- xe_assert(xe, xe_tile_is_root(tile));
spin_lock_irqsave(&mert->lock, flags);
if (!mert->tlb_inv_triggered) {
@@ -43,6 +56,37 @@ int xe_mert_invalidate_lmtt(struct xe_tile *tile)
return 0;
}
+static void mert_handle_cat_error(struct xe_device *xe)
+{
+ struct xe_tile *tile = xe_device_get_root_tile(xe);
+ u32 reg_val, vfid, code;
+
+ reg_val = xe_mmio_read32(&tile->mmio, MERT_TLB_CT_INTR_ERR_ID_PORT);
+ if (!reg_val)
+ return;
+ xe_mmio_write32(&tile->mmio, MERT_TLB_CT_INTR_ERR_ID_PORT, 0);
+
+ vfid = FIELD_GET(CATERR_VFID, reg_val);
+ code = FIELD_GET(CATERR_CODES, reg_val);
+
+ switch (code) {
+ case CATERR_NO_ERROR:
+ break;
+ case CATERR_UNMAPPED_GGTT:
+ xe_sriov_err(xe, "MERT: CAT_ERR: Access to an unmapped GGTT!\n");
+ xe_device_declare_wedged(xe);
+ break;
+ case CATERR_LMTT_FAULT:
+ xe_sriov_dbg(xe, "MERT: CAT_ERR: VF%u LMTT fault!\n", vfid);
+ /* XXX: track/report malicious VF activity */
+ break;
+ default:
+ xe_sriov_err(xe, "MERT: Unexpected CAT_ERR code=%#x!\n", code);
+ xe_device_declare_wedged(xe);
+ break;
+ }
+}
+
/**
* xe_mert_irq_handler - Handler for MERT interrupts
* @xe: the &xe_device
@@ -53,30 +97,22 @@ int xe_mert_invalidate_lmtt(struct xe_tile *tile)
void xe_mert_irq_handler(struct xe_device *xe, u32 master_ctl)
{
struct xe_tile *tile = xe_device_get_root_tile(xe);
+ struct xe_mert *mert = &tile->mert;
unsigned long flags;
u32 reg_val;
- u8 err;
if (!(master_ctl & SOC_H2DMEMINT_IRQ))
return;
- reg_val = xe_mmio_read32(&tile->mmio, MERT_TLB_CT_INTR_ERR_ID_PORT);
- xe_mmio_write32(&tile->mmio, MERT_TLB_CT_INTR_ERR_ID_PORT, 0);
-
- err = FIELD_GET(MERT_TLB_CT_ERROR_MASK, reg_val);
- if (err == MERT_TLB_CT_LMTT_FAULT)
- drm_dbg(&xe->drm, "MERT catastrophic error: LMTT fault (VF%u)\n",
- FIELD_GET(MERT_TLB_CT_VFID_MASK, reg_val));
- else if (err)
- drm_dbg(&xe->drm, "MERT catastrophic error: Unexpected fault (0x%x)\n", err);
+ mert_handle_cat_error(xe);
- spin_lock_irqsave(&tile->mert.lock, flags);
- if (tile->mert.tlb_inv_triggered) {
+ spin_lock_irqsave(&mert->lock, flags);
+ if (mert->tlb_inv_triggered) {
reg_val = xe_mmio_read32(&tile->mmio, MERT_TLB_INV_DESC_A);
if (!(reg_val & MERT_TLB_INV_DESC_A_VALID)) {
- tile->mert.tlb_inv_triggered = false;
- complete_all(&tile->mert.tlb_inv_done);
+ mert->tlb_inv_triggered = false;
+ complete_all(&mert->tlb_inv_done);
}
}
- spin_unlock_irqrestore(&tile->mert.lock, flags);
+ spin_unlock_irqrestore(&mert->lock, flags);
}
diff --git a/drivers/gpu/drm/xe/xe_mert.h b/drivers/gpu/drm/xe/xe_mert.h
index 2e14c5dec008..fc977203692d 100644
--- a/drivers/gpu/drm/xe/xe_mert.h
+++ b/drivers/gpu/drm/xe/xe_mert.h
@@ -3,30 +3,33 @@
* Copyright(c) 2025, Intel Corporation. All rights reserved.
*/
-#ifndef __XE_MERT_H__
-#define __XE_MERT_H__
+#ifndef _XE_MERT_H_
+#define _XE_MERT_H_
#include <linux/completion.h>
#include <linux/spinlock.h>
#include <linux/types.h>
struct xe_device;
-struct xe_tile;
+/**
+ * struct xe_mert - MERT related data
+ */
struct xe_mert {
/** @lock: protects the TLB invalidation status */
spinlock_t lock;
/** @tlb_inv_triggered: indicates if TLB invalidation was triggered */
bool tlb_inv_triggered;
- /** @mert.tlb_inv_done: completion of TLB invalidation */
+ /** @tlb_inv_done: completion of TLB invalidation */
struct completion tlb_inv_done;
};
#ifdef CONFIG_PCI_IOV
-int xe_mert_invalidate_lmtt(struct xe_tile *tile);
+void xe_mert_init_early(struct xe_device *xe);
+int xe_mert_invalidate_lmtt(struct xe_device *xe);
void xe_mert_irq_handler(struct xe_device *xe, u32 master_ctl);
#else
static inline void xe_mert_irq_handler(struct xe_device *xe, u32 master_ctl) { }
#endif
-#endif /* __XE_MERT_H__ */
+#endif
diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c
index 350dca1f0925..bcb6674b7dac 100644
--- a/drivers/gpu/drm/xe/xe_mmio.c
+++ b/drivers/gpu/drm/xe/xe_mmio.c
@@ -14,12 +14,8 @@
#include <drm/drm_print.h>
#include "regs/xe_bars.h"
-#include "regs/xe_regs.h"
#include "xe_device.h"
-#include "xe_gt.h"
-#include "xe_gt_printk.h"
#include "xe_gt_sriov_vf.h"
-#include "xe_macros.h"
#include "xe_sriov.h"
#include "xe_trace.h"
#include "xe_wa.h"
diff --git a/drivers/gpu/drm/xe/xe_mocs.c b/drivers/gpu/drm/xe/xe_mocs.c
index 0b7225bd77e0..54822497c21e 100644
--- a/drivers/gpu/drm/xe/xe_mocs.c
+++ b/drivers/gpu/drm/xe/xe_mocs.c
@@ -6,7 +6,6 @@
#include "xe_mocs.h"
#include "regs/xe_gt_regs.h"
-#include "xe_bo.h"
#include "xe_device.h"
#include "xe_exec_queue.h"
#include "xe_force_wake.h"
@@ -17,7 +16,6 @@
#include "xe_platform_types.h"
#include "xe_pm.h"
#include "xe_sriov.h"
-#include "xe_step_types.h"
#if IS_ENABLED(CONFIG_DRM_XE_DEBUG)
#define mocs_dbg xe_gt_dbg
diff --git a/drivers/gpu/drm/xe/xe_module.c b/drivers/gpu/drm/xe/xe_module.c
index d08338fc3bc1..a0048f64ed12 100644
--- a/drivers/gpu/drm/xe/xe_module.c
+++ b/drivers/gpu/drm/xe/xe_module.c
@@ -10,6 +10,7 @@
#include <drm/drm_module.h>
+#include "xe_device_types.h"
#include "xe_drv.h"
#include "xe_configfs.h"
#include "xe_hw_fence.h"
@@ -29,7 +30,8 @@
#define DEFAULT_FORCE_PROBE CONFIG_DRM_XE_FORCE_PROBE
#define DEFAULT_MAX_VFS ~0
#define DEFAULT_MAX_VFS_STR "unlimited"
-#define DEFAULT_WEDGED_MODE 1
+#define DEFAULT_WEDGED_MODE XE_WEDGED_MODE_DEFAULT
+#define DEFAULT_WEDGED_MODE_STR XE_WEDGED_MODE_DEFAULT_STR
#define DEFAULT_SVM_NOTIFIER_SIZE 512
struct xe_modparam xe_modparam = {
@@ -88,10 +90,10 @@ MODULE_PARM_DESC(max_vfs,
"[default=" DEFAULT_MAX_VFS_STR "])");
#endif
-module_param_named_unsafe(wedged_mode, xe_modparam.wedged_mode, int, 0600);
+module_param_named_unsafe(wedged_mode, xe_modparam.wedged_mode, uint, 0600);
MODULE_PARM_DESC(wedged_mode,
- "Module's default policy for the wedged mode (0=never, 1=upon-critical-errors, 2=upon-any-hang "
- "[default=" __stringify(DEFAULT_WEDGED_MODE) "])");
+ "Module's default policy for the wedged mode (0=never, 1=upon-critical-error, 2=upon-any-hang-no-reset "
+ "[default=" DEFAULT_WEDGED_MODE_STR "])");
static int xe_check_nomodeset(void)
{
diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h
index 5a3bfea8b7b4..1c75f38ca393 100644
--- a/drivers/gpu/drm/xe/xe_module.h
+++ b/drivers/gpu/drm/xe/xe_module.h
@@ -21,7 +21,7 @@ struct xe_modparam {
#ifdef CONFIG_PCI_IOV
unsigned int max_vfs;
#endif
- int wedged_mode;
+ unsigned int wedged_mode;
u32 svm_notifier_size;
};
diff --git a/drivers/gpu/drm/xe/xe_nvm.c b/drivers/gpu/drm/xe/xe_nvm.c
index 01510061d4d4..437375046517 100644
--- a/drivers/gpu/drm/xe/xe_nvm.c
+++ b/drivers/gpu/drm/xe/xe_nvm.c
@@ -6,7 +6,6 @@
#include <linux/intel_dg_nvm_aux.h>
#include <linux/pci.h>
-#include "xe_device.h"
#include "xe_device_types.h"
#include "xe_mmio.h"
#include "xe_nvm.h"
diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.c b/drivers/gpu/drm/xe/xe_page_reclaim.c
index fd8c33761127..e13c71a89da2 100644
--- a/drivers/gpu/drm/xe/xe_page_reclaim.c
+++ b/drivers/gpu/drm/xe/xe_page_reclaim.c
@@ -10,14 +10,11 @@
#include "xe_page_reclaim.h"
-#include "regs/xe_gt_regs.h"
-#include "xe_assert.h"
+#include "xe_gt_stats.h"
#include "xe_macros.h"
-#include "xe_mmio.h"
#include "xe_pat.h"
#include "xe_sa.h"
#include "xe_tlb_inval_types.h"
-#include "xe_vm.h"
/**
* xe_page_reclaim_skip() - Decide whether PRL should be skipped for a VMA
@@ -108,7 +105,6 @@ void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl)
*/
void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl)
{
- // xe_page_reclaim_list_invalidate(prl);
prl->entries = NULL;
prl->num_entries = 0;
}
diff --git a/drivers/gpu/drm/xe/xe_page_reclaim.h b/drivers/gpu/drm/xe/xe_page_reclaim.h
index a4f58e0ce9b4..3dd103e37beb 100644
--- a/drivers/gpu/drm/xe/xe_page_reclaim.h
+++ b/drivers/gpu/drm/xe/xe_page_reclaim.h
@@ -19,6 +19,7 @@
struct xe_tlb_inval;
struct xe_tlb_inval_fence;
struct xe_tile;
+struct xe_gt;
struct xe_vma;
struct xe_guc_page_reclaim_entry {
@@ -75,6 +76,25 @@ struct drm_suballoc *xe_page_reclaim_create_prl_bo(struct xe_tlb_inval *tlb_inva
struct xe_page_reclaim_list *prl,
struct xe_tlb_inval_fence *fence);
void xe_page_reclaim_list_invalidate(struct xe_page_reclaim_list *prl);
+
+/**
+ * xe_page_reclaim_list_abort() - Invalidate a PRL and log an abort reason
+ * @gt: GT owning the page reclaim request
+ * @prl: Page reclaim list to invalidate
+ * @fmt: format string for the log message with args
+ *
+ * Abort page reclaim process by invalidating PRL and doing any relevant logging.
+ */
+#define xe_page_reclaim_list_abort(gt, prl, fmt, ...) \
+ do { \
+ struct xe_gt *__gt = (gt); \
+ struct xe_page_reclaim_list *__prl = (prl); \
+ \
+ xe_page_reclaim_list_invalidate(__prl); \
+ xe_gt_stats_incr(__gt, XE_GT_STATS_ID_PRL_ABORTED_COUNT, 1); \
+ vm_dbg(&gt_to_xe(__gt)->drm, "PRL aborted: " fmt, ##__VA_ARGS__); \
+ } while (0)
+
void xe_page_reclaim_list_init(struct xe_page_reclaim_list *prl);
int xe_page_reclaim_list_alloc_entries(struct xe_page_reclaim_list *prl);
/**
diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c
index 2c3375e0250b..14d0dce5190a 100644
--- a/drivers/gpu/drm/xe/xe_pat.c
+++ b/drivers/gpu/drm/xe/xe_pat.c
@@ -132,9 +132,10 @@ static const struct xe_pat_table_entry xelpg_pat_table[] = {
* in the table.
*
* Note: There is an implicit assumption in the driver that compression and
- * coh_1way+ are mutually exclusive. If this is ever not true then userptr
- * and imported dma-buf from external device will have uncleared ccs state. See
- * also xe_bo_needs_ccs_pages().
+ * coh_1way+ are mutually exclusive for platforms prior to Xe3. Starting
+ * with Xe3, compression can be combined with coherency. If using compression
+ * with coherency, userptr and imported dma-buf from external device will
+ * have uncleared ccs state. See also xe_bo_needs_ccs_pages().
*/
#define XE2_PAT(no_promote, comp_en, l3clos, l3_policy, l4_policy, __coh_mode) \
{ \
@@ -144,8 +145,7 @@ static const struct xe_pat_table_entry xelpg_pat_table[] = {
REG_FIELD_PREP(XE2_L3_POLICY, l3_policy) | \
REG_FIELD_PREP(XE2_L4_POLICY, l4_policy) | \
REG_FIELD_PREP(XE2_COH_MODE, __coh_mode), \
- .coh_mode = (BUILD_BUG_ON_ZERO(__coh_mode && comp_en) || __coh_mode) ? \
- XE_COH_AT_LEAST_1WAY : XE_COH_NONE, \
+ .coh_mode = __coh_mode ? XE_COH_AT_LEAST_1WAY : XE_COH_NONE, \
.valid = 1 \
}
@@ -181,6 +181,38 @@ static const struct xe_pat_table_entry xe2_pat_table[] = {
[31] = XE2_PAT( 0, 0, 3, 0, 3, 3 ),
};
+static const struct xe_pat_table_entry xe3_lpg_pat_table[] = {
+ [ 0] = XE2_PAT( 0, 0, 0, 0, 3, 0 ),
+ [ 1] = XE2_PAT( 0, 0, 0, 0, 3, 2 ),
+ [ 2] = XE2_PAT( 0, 0, 0, 0, 3, 3 ),
+ [ 3] = XE2_PAT( 0, 0, 0, 3, 3, 0 ),
+ [ 4] = XE2_PAT( 0, 0, 0, 3, 0, 2 ),
+ [ 5] = XE2_PAT( 0, 0, 0, 3, 3, 2 ),
+ [ 6] = XE2_PAT( 1, 0, 0, 1, 3, 0 ),
+ [ 7] = XE2_PAT( 0, 0, 0, 3, 0, 3 ),
+ [ 8] = XE2_PAT( 0, 0, 0, 3, 0, 0 ),
+ [ 9] = XE2_PAT( 0, 1, 0, 0, 3, 0 ),
+ [10] = XE2_PAT( 0, 1, 0, 3, 0, 0 ),
+ [11] = XE2_PAT( 1, 1, 0, 1, 3, 0 ),
+ [12] = XE2_PAT( 0, 1, 0, 3, 3, 0 ),
+ [13] = XE2_PAT( 0, 0, 0, 0, 0, 0 ),
+ [14] = XE2_PAT( 0, 1, 0, 0, 0, 0 ),
+ [15] = XE2_PAT( 1, 1, 0, 1, 1, 0 ),
+ [16] = XE2_PAT( 0, 1, 0, 0, 3, 2 ),
+ /* 17..19 are reserved; leave set to all 0's */
+ [20] = XE2_PAT( 0, 0, 1, 0, 3, 0 ),
+ [21] = XE2_PAT( 0, 1, 1, 0, 3, 0 ),
+ [22] = XE2_PAT( 0, 0, 1, 0, 3, 2 ),
+ [23] = XE2_PAT( 0, 0, 1, 0, 3, 3 ),
+ [24] = XE2_PAT( 0, 0, 2, 0, 3, 0 ),
+ [25] = XE2_PAT( 0, 1, 2, 0, 3, 0 ),
+ [26] = XE2_PAT( 0, 0, 2, 0, 3, 2 ),
+ [27] = XE2_PAT( 0, 0, 2, 0, 3, 3 ),
+ [28] = XE2_PAT( 0, 0, 3, 0, 3, 0 ),
+ [29] = XE2_PAT( 0, 1, 3, 0, 3, 0 ),
+ [30] = XE2_PAT( 0, 0, 3, 0, 3, 2 ),
+ [31] = XE2_PAT( 0, 0, 3, 0, 3, 3 ),
+};
/* Special PAT values programmed outside the main table */
static const struct xe_pat_table_entry xe2_pat_ats = XE2_PAT( 0, 0, 0, 0, 3, 3 );
static const struct xe_pat_table_entry xe2_pat_pta = XE2_PAT( 0, 0, 0, 0, 3, 0 );
@@ -490,6 +522,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;
if (GRAPHICS_VERx100(xe) == 3511) {
xe->pat.ops = &xe3p_xpc_pat_ops;
xe->pat.table = xe3p_xpc_pat_table;
@@ -501,7 +534,12 @@ void xe_pat_init_early(struct xe_device *xe)
xe->pat.idx[XE_CACHE_WB] = 2;
} else if (GRAPHICS_VER(xe) == 30 || GRAPHICS_VER(xe) == 20) {
xe->pat.ops = &xe2_pat_ops;
- xe->pat.table = xe2_pat_table;
+ if (GRAPHICS_VER(xe) == 30) {
+ xe->pat.table = xe3_lpg_pat_table;
+ xe->pat.idx[XE_CACHE_WB_COMPRESSION] = 16;
+ } else {
+ xe->pat.table = xe2_pat_table;
+ }
xe->pat.pat_ats = &xe2_pat_ats;
if (IS_DGFX(xe))
xe->pat.pat_pta = &xe2_pat_pta;
@@ -658,6 +696,8 @@ int xe_pat_dump_sw_config(struct xe_gt *gt, struct drm_printer *p)
if (GRAPHICS_VER(xe) >= 20) {
drm_printf(p, "IDX[XE_CACHE_NONE_COMPRESSION] = %d\n",
xe->pat.idx[XE_CACHE_NONE_COMPRESSION]);
+ drm_printf(p, "IDX[XE_CACHE_WB_COMPRESSION] = %d\n",
+ xe->pat.idx[XE_CACHE_WB_COMPRESSION]);
}
return 0;
diff --git a/drivers/gpu/drm/xe/xe_pat.h b/drivers/gpu/drm/xe/xe_pat.h
index d5dadfb7f924..c7e2a53d8cee 100644
--- a/drivers/gpu/drm/xe/xe_pat.h
+++ b/drivers/gpu/drm/xe/xe_pat.h
@@ -12,6 +12,8 @@ struct drm_printer;
struct xe_device;
struct xe_gt;
+#define XE_PAT_INVALID_IDX U16_MAX
+
/**
* struct xe_pat_table_entry - The pat_index encoding and other meta information.
*/
diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
index a1fdca451ce0..09189ff3da44 100644
--- a/drivers/gpu/drm/xe/xe_pci.c
+++ b/drivers/gpu/drm/xe/xe_pci.c
@@ -24,7 +24,6 @@
#include "xe_gt.h"
#include "xe_gt_sriov_vf.h"
#include "xe_guc.h"
-#include "xe_macros.h"
#include "xe_mmio.h"
#include "xe_module.h"
#include "xe_pci_rebar.h"
@@ -366,6 +365,7 @@ static const struct xe_device_desc bmg_desc = {
.has_fan_control = true,
.has_flat_ccs = 1,
.has_mbx_power_limits = true,
+ .has_mbx_thermal_info = true,
.has_gsc_nvm = 1,
.has_heci_cscfi = 1,
.has_i2c = true,
@@ -392,6 +392,7 @@ static const struct xe_device_desc ptl_desc = {
.has_sriov = true,
.has_mem_copy_instr = true,
.has_pre_prod_wa = 1,
+ .has_pxp = true,
.max_gt_per_tile = 2,
.needs_scratch = true,
.needs_shared_vf_gt_wq = true,
@@ -421,6 +422,7 @@ static const struct xe_device_desc cri_desc = {
.has_gsc_nvm = 1,
.has_i2c = true,
.has_mbx_power_limits = true,
+ .has_mbx_thermal_info = true,
.has_mert = true,
.has_pre_prod_wa = 1,
.has_soc_remapper_sysctrl = true,
@@ -686,6 +688,7 @@ static int xe_info_init_early(struct xe_device *xe,
/* runtime fusing may force flat_ccs to disabled later */
xe->info.has_flat_ccs = desc->has_flat_ccs;
xe->info.has_mbx_power_limits = desc->has_mbx_power_limits;
+ xe->info.has_mbx_thermal_info = desc->has_mbx_thermal_info;
xe->info.has_gsc_nvm = desc->has_gsc_nvm;
xe->info.has_heci_gscfi = desc->has_heci_gscfi;
xe->info.has_heci_cscfi = desc->has_heci_cscfi;
diff --git a/drivers/gpu/drm/xe/xe_pci_types.h b/drivers/gpu/drm/xe/xe_pci_types.h
index 5f20f56571d1..20acc5349ee6 100644
--- a/drivers/gpu/drm/xe/xe_pci_types.h
+++ b/drivers/gpu/drm/xe/xe_pci_types.h
@@ -48,6 +48,7 @@ struct xe_device_desc {
u8 has_late_bind:1;
u8 has_llc:1;
u8 has_mbx_power_limits:1;
+ u8 has_mbx_thermal_info:1;
u8 has_mem_copy_instr:1;
u8 has_mert:1;
u8 has_pre_prod_wa:1;
diff --git a/drivers/gpu/drm/xe/xe_pcode_api.h b/drivers/gpu/drm/xe/xe_pcode_api.h
index 975892d6b230..85cc7478b787 100644
--- a/drivers/gpu/drm/xe/xe_pcode_api.h
+++ b/drivers/gpu/drm/xe/xe_pcode_api.h
@@ -50,6 +50,13 @@
#define READ_PL_FROM_FW 0x1
#define READ_PL_FROM_PCODE 0x0
+#define PCODE_THERMAL_INFO 0x25
+#define READ_THERMAL_LIMITS 0x0
+#define READ_THERMAL_CONFIG 0x1
+#define READ_THERMAL_DATA 0x2
+#define PCIE_SENSOR_GROUP_ID 0x2
+#define PCIE_SENSOR_MASK REG_GENMASK(31, 16)
+
#define PCODE_LATE_BINDING 0x5C
#define GET_CAPABILITY_STATUS 0x0
#define V1_FAN_SUPPORTED REG_BIT(0)
diff --git a/drivers/gpu/drm/xe/xe_pm.c b/drivers/gpu/drm/xe/xe_pm.c
index 4390ba69610d..559cf5490ac0 100644
--- a/drivers/gpu/drm/xe/xe_pm.c
+++ b/drivers/gpu/drm/xe/xe_pm.c
@@ -260,10 +260,19 @@ int xe_pm_resume(struct xe_device *xe)
xe_irq_resume(xe);
- for_each_gt(gt, xe, id)
- xe_gt_resume(gt);
+ for_each_gt(gt, xe, id) {
+ err = xe_gt_resume(gt);
+ if (err)
+ break;
+ }
+ /*
+ * Try to bring up display before bailing from GT resume failure,
+ * so we don't leave the user clueless with a blank screen.
+ */
xe_display_pm_resume(xe);
+ if (err)
+ goto err;
err = xe_bo_restore_late(xe);
if (err)
@@ -656,10 +665,19 @@ int xe_pm_runtime_resume(struct xe_device *xe)
xe_irq_resume(xe);
- for_each_gt(gt, xe, id)
- xe->d3cold.allowed ? xe_gt_resume(gt) : xe_gt_runtime_resume(gt);
+ for_each_gt(gt, xe, id) {
+ err = xe->d3cold.allowed ? xe_gt_resume(gt) : xe_gt_runtime_resume(gt);
+ if (err)
+ break;
+ }
+ /*
+ * Try to bring up display before bailing from GT resume failure,
+ * so we don't leave the user clueless with a blank screen.
+ */
xe_display_pm_runtime_resume(xe);
+ if (err)
+ goto out;
if (xe->d3cold.allowed) {
err = xe_bo_restore_late(xe);
diff --git a/drivers/gpu/drm/xe/xe_psmi.c b/drivers/gpu/drm/xe/xe_psmi.c
index 6a54e38b81ba..899b01f72ba3 100644
--- a/drivers/gpu/drm/xe/xe_psmi.c
+++ b/drivers/gpu/drm/xe/xe_psmi.c
@@ -6,7 +6,7 @@
#include <linux/debugfs.h>
#include "xe_bo.h"
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_configfs.h"
#include "xe_psmi.h"
diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c
index 6cd78bb2b652..6703a7049227 100644
--- a/drivers/gpu/drm/xe/xe_pt.c
+++ b/drivers/gpu/drm/xe/xe_pt.c
@@ -11,6 +11,7 @@
#include "xe_drm_client.h"
#include "xe_exec_queue.h"
#include "xe_gt.h"
+#include "xe_gt_stats.h"
#include "xe_migrate.h"
#include "xe_page_reclaim.h"
#include "xe_pt_types.h"
@@ -1576,12 +1577,6 @@ static bool xe_pt_check_kill(u64 addr, u64 next, unsigned int level,
return false;
}
-/* Huge 2MB leaf lives directly in a level-1 table and has no children */
-static bool is_2m_pte(struct xe_pt *pte)
-{
- return pte->level == 1 && !pte->base.children;
-}
-
/* page_size = 2^(reclamation_size + XE_PTE_SHIFT) */
#define COMPUTE_RECLAIM_ADDRESS_MASK(page_size) \
({ \
@@ -1593,8 +1588,10 @@ static int generate_reclaim_entry(struct xe_tile *tile,
struct xe_page_reclaim_list *prl,
u64 pte, struct xe_pt *xe_child)
{
+ struct xe_gt *gt = tile->primary_gt;
struct xe_guc_page_reclaim_entry *reclaim_entries = prl->entries;
- u64 phys_page = (pte & XE_PTE_ADDR_MASK) >> XE_PTE_SHIFT;
+ u64 phys_addr = pte & XE_PTE_ADDR_MASK;
+ u64 phys_page = phys_addr >> XE_PTE_SHIFT;
int num_entries = prl->num_entries;
u32 reclamation_size;
@@ -1612,16 +1609,21 @@ static int generate_reclaim_entry(struct xe_tile *tile,
* Only 4K, 64K (level 0), and 2M pages are supported by hardware for page reclaim
*/
if (xe_child->level == 0 && !(pte & XE_PTE_PS64)) {
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_4K_ENTRY_COUNT, 1);
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_4K); /* reclamation_size = 0 */
+ xe_tile_assert(tile, phys_addr % SZ_4K == 0);
} else if (xe_child->level == 0) {
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_64K_ENTRY_COUNT, 1);
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_64K); /* reclamation_size = 4 */
- } else if (is_2m_pte(xe_child)) {
+ xe_tile_assert(tile, phys_addr % SZ_64K == 0);
+ } else if (xe_child->level == 1 && pte & XE_PDE_PS_2M) {
+ xe_gt_stats_incr(gt, XE_GT_STATS_ID_PRL_2M_ENTRY_COUNT, 1);
reclamation_size = COMPUTE_RECLAIM_ADDRESS_MASK(SZ_2M); /* reclamation_size = 9 */
+ xe_tile_assert(tile, phys_addr % SZ_2M == 0);
} else {
- xe_page_reclaim_list_invalidate(prl);
- vm_dbg(&tile_to_xe(tile)->drm,
- "PRL invalidate: unsupported PTE level=%u pte=%#llx\n",
- xe_child->level, pte);
+ xe_page_reclaim_list_abort(tile->primary_gt, prl,
+ "unsupported PTE level=%u pte=%#llx",
+ xe_child->level, pte);
return -EINVAL;
}
@@ -1648,20 +1650,40 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
struct xe_pt_stage_unbind_walk *xe_walk =
container_of(walk, typeof(*xe_walk), base);
struct xe_device *xe = tile_to_xe(xe_walk->tile);
+ pgoff_t first = xe_pt_offset(addr, xe_child->level, walk);
+ bool killed;
XE_WARN_ON(!*child);
XE_WARN_ON(!level);
/* Check for leaf node */
if (xe_walk->prl && xe_page_reclaim_list_valid(xe_walk->prl) &&
- !xe_child->base.children) {
+ (!xe_child->base.children || !xe_child->base.children[first])) {
struct iosys_map *leaf_map = &xe_child->bo->vmap;
- pgoff_t first = xe_pt_offset(addr, 0, walk);
- pgoff_t count = xe_pt_num_entries(addr, next, 0, walk);
+ pgoff_t count = xe_pt_num_entries(addr, next, xe_child->level, walk);
for (pgoff_t i = 0; i < count; i++) {
u64 pte = xe_map_rd(xe, leaf_map, (first + i) * sizeof(u64), u64);
int ret;
+ /*
+ * In rare scenarios, pte may not be written yet due to racy conditions.
+ * In such cases, invalidate the PRL and fallback to full PPC invalidation.
+ */
+ if (!pte) {
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "found zero pte at addr=%#llx", addr);
+ break;
+ }
+
+ /* Ensure it is a defined page */
+ xe_tile_assert(xe_walk->tile,
+ xe_child->level == 0 ||
+ (pte & (XE_PTE_PS64 | XE_PDE_PS_2M | XE_PDPE_PS_1G)));
+
+ /* An entry should be added for 64KB but contigious 4K have XE_PTE_PS64 */
+ if (pte & XE_PTE_PS64)
+ i += 15; /* Skip other 15 consecutive 4K pages in the 64K page */
+
/* Account for NULL terminated entry on end (-1) */
if (xe_walk->prl->num_entries < XE_PAGE_RECLAIM_MAX_ENTRIES - 1) {
ret = generate_reclaim_entry(xe_walk->tile, xe_walk->prl,
@@ -1670,22 +1692,32 @@ static int xe_pt_stage_unbind_entry(struct xe_ptw *parent, pgoff_t offset,
break;
} else {
/* overflow, mark as invalid */
- xe_page_reclaim_list_invalidate(xe_walk->prl);
- vm_dbg(&xe->drm,
- "PRL invalidate: overflow while adding pte=%#llx",
- pte);
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "overflow while adding pte=%#llx",
+ pte);
break;
}
}
}
- /* If aborting page walk early, invalidate PRL since PTE may be dropped from this abort */
- if (xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk) &&
- xe_walk->prl && level > 1 && xe_child->base.children && xe_child->num_live != 0) {
- xe_page_reclaim_list_invalidate(xe_walk->prl);
- vm_dbg(&xe->drm,
- "PRL invalidate: kill at level=%u addr=%#llx next=%#llx num_live=%u\n",
- level, addr, next, xe_child->num_live);
+ killed = xe_pt_check_kill(addr, next, level - 1, xe_child, action, walk);
+
+ /*
+ * Verify PRL is active and if entry is not a leaf pte (base.children conditions),
+ * there is a potential need to invalidate the PRL if any PTE (num_live) are dropped.
+ */
+ if (xe_walk->prl && level > 1 && xe_child->num_live &&
+ xe_child->base.children && xe_child->base.children[first]) {
+ bool covered = xe_pt_covers(addr, next, xe_child->level, &xe_walk->base);
+
+ /*
+ * If aborting page walk early (kill) or page walk completes the full range
+ * we need to invalidate the PRL.
+ */
+ if (killed || covered)
+ xe_page_reclaim_list_abort(xe_walk->tile->primary_gt, xe_walk->prl,
+ "kill at level=%u addr=%#llx next=%#llx num_live=%u",
+ level, addr, next, xe_child->num_live);
}
return 0;
diff --git a/drivers/gpu/drm/xe/xe_pt_types.h b/drivers/gpu/drm/xe/xe_pt_types.h
index 88fabf8e2655..84b51d3762a4 100644
--- a/drivers/gpu/drm/xe/xe_pt_types.h
+++ b/drivers/gpu/drm/xe/xe_pt_types.h
@@ -20,6 +20,7 @@ enum xe_cache_level {
XE_CACHE_WT,
XE_CACHE_WB,
XE_CACHE_NONE_COMPRESSION, /*UC + COH_NONE + COMPRESSION */
+ XE_CACHE_WB_COMPRESSION,
__XE_CACHE_LEVEL_COUNT,
};
diff --git a/drivers/gpu/drm/xe/xe_pxp.c b/drivers/gpu/drm/xe/xe_pxp.c
index 508f4c128a48..d61446bf9c19 100644
--- a/drivers/gpu/drm/xe/xe_pxp.c
+++ b/drivers/gpu/drm/xe/xe_pxp.c
@@ -15,7 +15,6 @@
#include "xe_force_wake.h"
#include "xe_guc_submit.h"
#include "xe_gsc_proxy.h"
-#include "xe_gt.h"
#include "xe_gt_types.h"
#include "xe_huc.h"
#include "xe_mmio.h"
diff --git a/drivers/gpu/drm/xe/xe_pxp_debugfs.c b/drivers/gpu/drm/xe/xe_pxp_debugfs.c
index 525a2f6bb076..d6e2e41bc88c 100644
--- a/drivers/gpu/drm/xe/xe_pxp_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_pxp_debugfs.c
@@ -11,7 +11,7 @@
#include <drm/drm_managed.h>
#include <drm/drm_print.h>
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_pxp.h"
#include "xe_pxp_types.h"
#include "regs/xe_irq_regs.h"
diff --git a/drivers/gpu/drm/xe/xe_reg_sr.c b/drivers/gpu/drm/xe/xe_reg_sr.c
index 1a465385f909..d3e13ea33123 100644
--- a/drivers/gpu/drm/xe/xe_reg_sr.c
+++ b/drivers/gpu/drm/xe/xe_reg_sr.c
@@ -13,16 +13,13 @@
#include <drm/drm_managed.h>
#include <drm/drm_print.h>
-#include "regs/xe_engine_regs.h"
-#include "regs/xe_gt_regs.h"
#include "xe_device.h"
#include "xe_device_types.h"
#include "xe_force_wake.h"
-#include "xe_gt.h"
#include "xe_gt_mcr.h"
#include "xe_gt_printk.h"
+#include "xe_gt_types.h"
#include "xe_hw_engine_types.h"
-#include "xe_macros.h"
#include "xe_mmio.h"
#include "xe_rtp_types.h"
diff --git a/drivers/gpu/drm/xe/xe_reg_whitelist.c b/drivers/gpu/drm/xe/xe_reg_whitelist.c
index 1391cb6ec9c6..1d36c09681aa 100644
--- a/drivers/gpu/drm/xe/xe_reg_whitelist.c
+++ b/drivers/gpu/drm/xe/xe_reg_whitelist.c
@@ -8,7 +8,6 @@
#include "regs/xe_engine_regs.h"
#include "regs/xe_gt_regs.h"
#include "regs/xe_oa_regs.h"
-#include "regs/xe_regs.h"
#include "xe_device.h"
#include "xe_gt_types.h"
#include "xe_gt_printk.h"
diff --git a/drivers/gpu/drm/xe/xe_ring_ops.c b/drivers/gpu/drm/xe/xe_ring_ops.c
index 957b9e2fd138..248620b0901d 100644
--- a/drivers/gpu/drm/xe/xe_ring_ops.c
+++ b/drivers/gpu/drm/xe/xe_ring_ops.c
@@ -11,11 +11,9 @@
#include "instructions/xe_mi_commands.h"
#include "regs/xe_engine_regs.h"
#include "regs/xe_gt_regs.h"
-#include "regs/xe_lrc_layout.h"
#include "xe_exec_queue.h"
-#include "xe_gt.h"
+#include "xe_gt_types.h"
#include "xe_lrc.h"
-#include "xe_macros.h"
#include "xe_sched_job.h"
#include "xe_sriov.h"
#include "xe_vm_types.h"
@@ -235,13 +233,26 @@ static u32 get_ppgtt_flag(struct xe_sched_job *job)
return 0;
}
-static int emit_copy_timestamp(struct xe_lrc *lrc, u32 *dw, int i)
+static int emit_copy_timestamp(struct xe_device *xe, struct xe_lrc *lrc,
+ u32 *dw, int i)
{
dw[i++] = MI_STORE_REGISTER_MEM | MI_SRM_USE_GGTT | MI_SRM_ADD_CS_OFFSET;
dw[i++] = RING_CTX_TIMESTAMP(0).addr;
dw[i++] = xe_lrc_ctx_job_timestamp_ggtt_addr(lrc);
dw[i++] = 0;
+ /*
+ * Ensure CTX timestamp >= Job timestamp during VF sampling to avoid
+ * arithmetic wraparound in TDR.
+ */
+ if (IS_SRIOV_VF(xe)) {
+ dw[i++] = MI_STORE_REGISTER_MEM | MI_SRM_USE_GGTT |
+ MI_SRM_ADD_CS_OFFSET;
+ dw[i++] = RING_CTX_TIMESTAMP(0).addr;
+ dw[i++] = xe_lrc_ctx_timestamp_ggtt_addr(lrc);
+ dw[i++] = 0;
+ }
+
return i;
}
@@ -255,7 +266,7 @@ static void __emit_job_gen12_simple(struct xe_sched_job *job, struct xe_lrc *lrc
*head = lrc->ring.tail;
- i = emit_copy_timestamp(lrc, dw, i);
+ i = emit_copy_timestamp(gt_to_xe(gt), lrc, dw, i);
if (job->ring_ops_flush_tlb) {
dw[i++] = preparser_disable(true);
@@ -310,7 +321,7 @@ static void __emit_job_gen12_video(struct xe_sched_job *job, struct xe_lrc *lrc,
*head = lrc->ring.tail;
- i = emit_copy_timestamp(lrc, dw, i);
+ i = emit_copy_timestamp(xe, lrc, dw, i);
dw[i++] = preparser_disable(true);
@@ -364,7 +375,7 @@ static void __emit_job_gen12_render_compute(struct xe_sched_job *job,
*head = lrc->ring.tail;
- i = emit_copy_timestamp(lrc, dw, i);
+ i = emit_copy_timestamp(xe, lrc, dw, i);
dw[i++] = preparser_disable(true);
if (lacks_render)
@@ -406,12 +417,14 @@ static void emit_migration_job_gen12(struct xe_sched_job *job,
struct xe_lrc *lrc, u32 *head,
u32 seqno)
{
+ struct xe_gt *gt = job->q->gt;
+ struct xe_device *xe = gt_to_xe(gt);
u32 saddr = xe_lrc_start_seqno_ggtt_addr(lrc);
u32 dw[MAX_JOB_SIZE_DW], i = 0;
*head = lrc->ring.tail;
- i = emit_copy_timestamp(lrc, dw, i);
+ i = emit_copy_timestamp(xe, lrc, dw, i);
i = emit_store_imm_ggtt(saddr, seqno, dw, i);
diff --git a/drivers/gpu/drm/xe/xe_rtp.c b/drivers/gpu/drm/xe/xe_rtp.c
index ed509b1c8cfc..b7c26e2fb411 100644
--- a/drivers/gpu/drm/xe/xe_rtp.c
+++ b/drivers/gpu/drm/xe/xe_rtp.c
@@ -12,7 +12,6 @@
#include "xe_configfs.h"
#include "xe_gt.h"
#include "xe_gt_topology.h"
-#include "xe_macros.h"
#include "xe_reg_sr.h"
#include "xe_sriov.h"
diff --git a/drivers/gpu/drm/xe/xe_sa.c b/drivers/gpu/drm/xe/xe_sa.c
index a87c1436c7c1..b738102575d4 100644
--- a/drivers/gpu/drm/xe/xe_sa.c
+++ b/drivers/gpu/drm/xe/xe_sa.c
@@ -10,7 +10,7 @@
#include <drm/drm_managed.h>
#include "xe_bo.h"
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_map.h"
static void xe_sa_bo_manager_fini(struct drm_device *drm, void *arg)
diff --git a/drivers/gpu/drm/xe/xe_sched_job.c b/drivers/gpu/drm/xe/xe_sched_job.c
index cb674a322113..3927666fe556 100644
--- a/drivers/gpu/drm/xe/xe_sched_job.c
+++ b/drivers/gpu/drm/xe/xe_sched_job.c
@@ -11,7 +11,7 @@
#include "xe_device.h"
#include "xe_exec_queue.h"
-#include "xe_gt.h"
+#include "xe_gt_types.h"
#include "xe_hw_engine_types.h"
#include "xe_hw_fence.h"
#include "xe_lrc.h"
@@ -110,6 +110,7 @@ struct xe_sched_job *xe_sched_job_create(struct xe_exec_queue *q,
return ERR_PTR(-ENOMEM);
job->q = q;
+ job->sample_timestamp = U64_MAX;
kref_init(&job->refcount);
xe_exec_queue_get(job->q);
diff --git a/drivers/gpu/drm/xe/xe_sched_job_types.h b/drivers/gpu/drm/xe/xe_sched_job_types.h
index 7c4c54fe920a..13c2970e81a8 100644
--- a/drivers/gpu/drm/xe/xe_sched_job_types.h
+++ b/drivers/gpu/drm/xe/xe_sched_job_types.h
@@ -59,6 +59,8 @@ struct xe_sched_job {
u32 lrc_seqno;
/** @migrate_flush_flags: Additional flush flags for migration jobs */
u32 migrate_flush_flags;
+ /** @sample_timestamp: Sampling of job timestamp in TDR */
+ u64 sample_timestamp;
/** @ring_ops_flush_tlb: The ring ops need to flush TLB before payload. */
bool ring_ops_flush_tlb;
/** @ggtt: mapped in ggtt. */
diff --git a/drivers/gpu/drm/xe/xe_sriov_packet.c b/drivers/gpu/drm/xe/xe_sriov_packet.c
index 2cefefaed9ba..7a4c3de662e5 100644
--- a/drivers/gpu/drm/xe/xe_sriov_packet.c
+++ b/drivers/gpu/drm/xe/xe_sriov_packet.c
@@ -6,7 +6,6 @@
#include "xe_bo.h"
#include "xe_device.h"
#include "xe_guc_klv_helpers.h"
-#include "xe_printk.h"
#include "xe_sriov_packet.h"
#include "xe_sriov_packet_types.h"
#include "xe_sriov_pf_helpers.h"
diff --git a/drivers/gpu/drm/xe/xe_sriov_pf.c b/drivers/gpu/drm/xe/xe_sriov_pf.c
index 72423bb17e6f..6ce3c58e003c 100644
--- a/drivers/gpu/drm/xe/xe_sriov_pf.c
+++ b/drivers/gpu/drm/xe/xe_sriov_pf.c
@@ -90,7 +90,6 @@ bool xe_sriov_pf_readiness(struct xe_device *xe)
*/
int xe_sriov_pf_init_early(struct xe_device *xe)
{
- struct xe_mert *mert = &xe_device_get_root_tile(xe)->mert;
int err;
xe_assert(xe, IS_SRIOV_PF(xe));
@@ -112,8 +111,7 @@ int xe_sriov_pf_init_early(struct xe_device *xe)
xe_sriov_pf_service_init(xe);
- spin_lock_init(&mert->lock);
- init_completion(&mert->tlb_inv_done);
+ xe_mert_init_early(xe);
return 0;
}
diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
index e84bdde9bc80..81b377830d6d 100644
--- a/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c
@@ -16,7 +16,6 @@
#include "xe_sriov_pf_migration.h"
#include "xe_sriov_pf_provision.h"
#include "xe_sriov_pf_service.h"
-#include "xe_sriov_printk.h"
#include "xe_tile_sriov_pf_debugfs.h"
/*
diff --git a/drivers/gpu/drm/xe/xe_sriov_vf.c b/drivers/gpu/drm/xe/xe_sriov_vf.c
index 1b75405b8d02..29894bd081c0 100644
--- a/drivers/gpu/drm/xe/xe_sriov_vf.c
+++ b/drivers/gpu/drm/xe/xe_sriov_vf.c
@@ -6,7 +6,6 @@
#include <drm/drm_debugfs.h>
#include <drm/drm_managed.h>
-#include "xe_gt.h"
#include "xe_gt_sriov_vf.h"
#include "xe_guc.h"
#include "xe_sriov_printk.h"
diff --git a/drivers/gpu/drm/xe/xe_step.c b/drivers/gpu/drm/xe/xe_step.c
index 10e88f2c9615..2860986f82f7 100644
--- a/drivers/gpu/drm/xe/xe_step.c
+++ b/drivers/gpu/drm/xe/xe_step.c
@@ -5,10 +5,11 @@
#include "xe_step.h"
+#include <drm/drm_print.h>
#include <kunit/visibility.h>
#include <linux/bitfield.h>
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_platform_types.h"
/*
diff --git a/drivers/gpu/drm/xe/xe_survivability_mode.c b/drivers/gpu/drm/xe/xe_survivability_mode.c
index 4c716182ad3b..6578ffc77bd5 100644
--- a/drivers/gpu/drm/xe/xe_survivability_mode.c
+++ b/drivers/gpu/drm/xe/xe_survivability_mode.c
@@ -12,7 +12,6 @@
#include "xe_configfs.h"
#include "xe_device.h"
-#include "xe_gt.h"
#include "xe_heci_gsc.h"
#include "xe_i2c.h"
#include "xe_mmio.h"
@@ -321,7 +320,7 @@ static int enable_boot_survivability_mode(struct pci_dev *pdev)
if (ret)
return ret;
- /* Make sure xe_heci_gsc_init() knows about survivability mode */
+ /* Make sure xe_heci_gsc_init() and xe_i2c_probe() are aware of survivability */
survivability->mode = true;
xe_heci_gsc_init(xe);
diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c
index fa2ee2c08f31..213f0334518a 100644
--- a/drivers/gpu/drm/xe/xe_svm.c
+++ b/drivers/gpu/drm/xe/xe_svm.c
@@ -988,6 +988,8 @@ bool xe_svm_range_validate(struct xe_vm *vm,
ret = (range->tile_present & ~range->tile_invalidated & tile_mask) == tile_mask;
if (dpagemap)
ret = ret && xe_svm_range_has_pagemap_locked(range, dpagemap);
+ else
+ ret = ret && !range->base.pages.dpagemap;
xe_svm_notifier_unlock(vm);
diff --git a/drivers/gpu/drm/xe/xe_tile.c b/drivers/gpu/drm/xe/xe_tile.c
index eb262aad11da..c465aae7883c 100644
--- a/drivers/gpu/drm/xe/xe_tile.c
+++ b/drivers/gpu/drm/xe/xe_tile.c
@@ -9,9 +9,8 @@
#include <drm/drm_pagemap_util.h>
#include "xe_bo.h"
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_ggtt.h"
-#include "xe_gt.h"
#include "xe_memirq.h"
#include "xe_migrate.h"
#include "xe_pcode.h"
diff --git a/drivers/gpu/drm/xe/xe_tlb_inval.c b/drivers/gpu/drm/xe/xe_tlb_inval.c
index dec042248164..e837888367c4 100644
--- a/drivers/gpu/drm/xe/xe_tlb_inval.c
+++ b/drivers/gpu/drm/xe/xe_tlb_inval.c
@@ -5,13 +5,10 @@
#include <drm/drm_managed.h>
-#include "abi/guc_actions_abi.h"
-#include "xe_device.h"
+#include "xe_device_types.h"
#include "xe_force_wake.h"
-#include "xe_gt.h"
-#include "xe_gt_printk.h"
#include "xe_gt_stats.h"
-#include "xe_guc.h"
+#include "xe_gt_types.h"
#include "xe_guc_ct.h"
#include "xe_guc_tlb_inval.h"
#include "xe_mmio.h"
@@ -94,7 +91,7 @@ static void xe_tlb_inval_fence_timeout(struct work_struct *work)
xe_tlb_inval_fence_signal(fence);
}
if (!list_empty(&tlb_inval->pending_fences))
- queue_delayed_work(system_wq, &tlb_inval->fence_tdr,
+ queue_delayed_work(tlb_inval->timeout_wq, &tlb_inval->fence_tdr,
timeout_delay);
spin_unlock_irq(&tlb_inval->pending_lock);
}
@@ -146,6 +143,10 @@ int xe_gt_tlb_inval_init_early(struct xe_gt *gt)
if (IS_ERR(tlb_inval->job_wq))
return PTR_ERR(tlb_inval->job_wq);
+ tlb_inval->timeout_wq = gt->ordered_wq;
+ if (IS_ERR(tlb_inval->timeout_wq))
+ return PTR_ERR(tlb_inval->timeout_wq);
+
/* XXX: Blindly setting up backend to GuC */
xe_guc_tlb_inval_init_early(&gt->uc.guc, tlb_inval);
@@ -240,7 +241,7 @@ static void xe_tlb_inval_fence_prep(struct xe_tlb_inval_fence *fence)
list_add_tail(&fence->link, &tlb_inval->pending_fences);
if (list_is_singular(&tlb_inval->pending_fences))
- queue_delayed_work(system_wq, &tlb_inval->fence_tdr,
+ queue_delayed_work(tlb_inval->timeout_wq, &tlb_inval->fence_tdr,
tlb_inval->ops->timeout_delay(tlb_inval));
spin_unlock_irq(&tlb_inval->pending_lock);
@@ -399,7 +400,7 @@ void xe_tlb_inval_done_handler(struct xe_tlb_inval *tlb_inval, int seqno)
}
if (!list_empty(&tlb_inval->pending_fences))
- mod_delayed_work(system_wq,
+ mod_delayed_work(tlb_inval->timeout_wq,
&tlb_inval->fence_tdr,
tlb_inval->ops->timeout_delay(tlb_inval));
else
diff --git a/drivers/gpu/drm/xe/xe_tlb_inval_types.h b/drivers/gpu/drm/xe/xe_tlb_inval_types.h
index 48d1503e8460..3b089f90f002 100644
--- a/drivers/gpu/drm/xe/xe_tlb_inval_types.h
+++ b/drivers/gpu/drm/xe/xe_tlb_inval_types.h
@@ -109,6 +109,8 @@ struct xe_tlb_inval {
struct workqueue_struct *job_wq;
/** @tlb_inval.lock: protects TLB invalidation fences */
spinlock_t lock;
+ /** @timeout_wq: schedules TLB invalidation fence timeouts */
+ struct workqueue_struct *timeout_wq;
};
/**
diff --git a/drivers/gpu/drm/xe/xe_trace.h b/drivers/gpu/drm/xe/xe_trace.h
index 6d12fcc13f43..750fa32c13b2 100644
--- a/drivers/gpu/drm/xe/xe_trace.h
+++ b/drivers/gpu/drm/xe/xe_trace.h
@@ -228,11 +228,6 @@ DEFINE_EVENT(xe_exec_queue, xe_exec_queue_resubmit,
TP_ARGS(q)
);
-DEFINE_EVENT(xe_exec_queue, xe_exec_queue_lr_cleanup,
- TP_PROTO(struct xe_exec_queue *q),
- TP_ARGS(q)
-);
-
DECLARE_EVENT_CLASS(xe_sched_job,
TP_PROTO(struct xe_sched_job *job),
TP_ARGS(job),
diff --git a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c
index 1bddecfb723a..27c9d72222cf 100644
--- a/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_stolen_mgr.c
@@ -17,7 +17,6 @@
#include "regs/xe_regs.h"
#include "xe_bo.h"
#include "xe_device.h"
-#include "xe_gt.h"
#include "xe_gt_printk.h"
#include "xe_mmio.h"
#include "xe_res_cursor.h"
diff --git a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
index 3e404eb8d098..99fb7e99eb7f 100644
--- a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c
@@ -13,7 +13,6 @@
#include <drm/ttm/ttm_tt.h>
#include "xe_bo.h"
-#include "xe_gt.h"
struct xe_ttm_sys_node {
struct ttm_buffer_object *tbo;
diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
index 9f70802fce92..6553a19f7cf2 100644
--- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
+++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c
@@ -12,7 +12,6 @@
#include "xe_bo.h"
#include "xe_device.h"
-#include "xe_gt.h"
#include "xe_res_cursor.h"
#include "xe_ttm_vram_mgr.h"
#include "xe_vram_types.h"
diff --git a/drivers/gpu/drm/xe/xe_uc.c b/drivers/gpu/drm/xe/xe_uc.c
index 157520ea1783..3f63c2a7e86d 100644
--- a/drivers/gpu/drm/xe/xe_uc.c
+++ b/drivers/gpu/drm/xe/xe_uc.c
@@ -8,7 +8,6 @@
#include "xe_assert.h"
#include "xe_device.h"
#include "xe_gsc.h"
-#include "xe_gsc_proxy.h"
#include "xe_gt.h"
#include "xe_gt_printk.h"
#include "xe_gt_sriov_vf.h"
@@ -17,7 +16,6 @@
#include "xe_guc_engine_activity.h"
#include "xe_huc.h"
#include "xe_sriov.h"
-#include "xe_uc_fw.h"
#include "xe_wopcm.h"
static struct xe_gt *
diff --git a/drivers/gpu/drm/xe/xe_uc_debugfs.c b/drivers/gpu/drm/xe/xe_uc_debugfs.c
index 24a4209051ee..45119993f5cb 100644
--- a/drivers/gpu/drm/xe/xe_uc_debugfs.c
+++ b/drivers/gpu/drm/xe/xe_uc_debugfs.c
@@ -7,12 +7,12 @@
#include <drm/drm_debugfs.h>
-#include "xe_gt.h"
#include "xe_gsc_debugfs.h"
#include "xe_guc_debugfs.h"
#include "xe_huc_debugfs.h"
#include "xe_macros.h"
#include "xe_uc_debugfs.h"
+#include "xe_uc_types.h"
void xe_uc_debugfs_register(struct xe_uc *uc, struct dentry *parent)
{
diff --git a/drivers/gpu/drm/xe/xe_uc_fw.c b/drivers/gpu/drm/xe/xe_uc_fw.c
index dcb4a32e7a64..d35bc4989144 100644
--- a/drivers/gpu/drm/xe/xe_uc_fw.c
+++ b/drivers/gpu/drm/xe/xe_uc_fw.c
@@ -14,9 +14,9 @@
#include "xe_device_types.h"
#include "xe_force_wake.h"
#include "xe_gsc.h"
-#include "xe_gt.h"
#include "xe_gt_printk.h"
#include "xe_gt_sriov_vf.h"
+#include "xe_gt_types.h"
#include "xe_guc.h"
#include "xe_map.h"
#include "xe_mmio.h"
@@ -115,6 +115,7 @@ struct fw_blobs_by_type {
#define XE_GT_TYPE_ANY XE_GT_TYPE_UNINITIALIZED
#define XE_GUC_FIRMWARE_DEFS(fw_def, mmp_ver, major_ver) \
+ fw_def(NOVALAKE_S, GT_TYPE_ANY, mmp_ver(xe, guc, nvl, 70, 55, 4)) \
fw_def(PANTHERLAKE, GT_TYPE_ANY, major_ver(xe, guc, ptl, 70, 54, 0)) \
fw_def(BATTLEMAGE, GT_TYPE_ANY, major_ver(xe, guc, bmg, 70, 54, 0)) \
fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, guc, lnl, 70, 53, 0)) \
@@ -140,6 +141,7 @@ struct fw_blobs_by_type {
/* for the GSC FW we match the compatibility version and not the release one */
#define XE_GSC_FIRMWARE_DEFS(fw_def, major_ver) \
+ fw_def(PANTHERLAKE, GT_TYPE_ANY, major_ver(xe, gsc, ptl, 105, 1, 0)) \
fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, gsc, lnl, 104, 1, 0)) \
fw_def(METEORLAKE, GT_TYPE_ANY, major_ver(i915, gsc, mtl, 102, 1, 0))
@@ -738,7 +740,7 @@ static int uc_fw_request(struct xe_uc_fw *uc_fw, const struct firmware **firmwar
return 0;
}
- err = request_firmware(&fw, uc_fw->path, dev);
+ err = firmware_request_nowarn(&fw, uc_fw->path, dev);
if (err)
goto fail;
@@ -767,8 +769,12 @@ fail:
XE_UC_FIRMWARE_MISSING :
XE_UC_FIRMWARE_ERROR);
- xe_gt_notice(gt, "%s firmware %s: fetch failed with error %pe\n",
- xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, ERR_PTR(err));
+ if (err == -ENOENT)
+ xe_gt_info(gt, "%s firmware %s not found\n",
+ xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
+ else
+ xe_gt_notice(gt, "%s firmware %s: fetch failed with error %pe\n",
+ xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, ERR_PTR(err));
xe_gt_info(gt, "%s firmware(s) can be downloaded from %s\n",
xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);
diff --git a/drivers/gpu/drm/xe/xe_validation.c b/drivers/gpu/drm/xe/xe_validation.c
index 826cd09966ef..a611438eaafe 100644
--- a/drivers/gpu/drm/xe/xe_validation.c
+++ b/drivers/gpu/drm/xe/xe_validation.c
@@ -2,7 +2,6 @@
/*
* Copyright © 2024 Intel Corporation
*/
-#include "xe_bo.h"
#include <drm/drm_exec.h>
#include <drm/drm_gem.h>
#include <drm/drm_gpuvm.h>
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 02df403a5b28..4a316bd49135 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -33,7 +33,6 @@
#include "xe_preempt_fence.h"
#include "xe_pt.h"
#include "xe_pxp.h"
-#include "xe_res_cursor.h"
#include "xe_sriov_vf.h"
#include "xe_svm.h"
#include "xe_sync.h"
@@ -2209,7 +2208,7 @@ static void print_op(struct xe_device *xe, struct drm_gpuva_op *op)
(ULL)xe_vma_start(vma), (ULL)xe_vma_size(vma));
break;
default:
- drm_warn(&xe->drm, "NOT POSSIBLE");
+ drm_warn(&xe->drm, "NOT POSSIBLE\n");
}
}
#else
@@ -2312,7 +2311,7 @@ vm_bind_ioctl_ops_create(struct xe_vm *vm, struct xe_vma_ops *vops,
xe_bo_unlock(bo);
break;
default:
- drm_warn(&vm->xe->drm, "NOT POSSIBLE");
+ drm_warn(&vm->xe->drm, "NOT POSSIBLE\n");
ops = ERR_PTR(-EINVAL);
}
if (IS_ERR(ops))
@@ -2584,7 +2583,7 @@ static int xe_vma_op_commit(struct xe_vm *vm, struct xe_vma_op *op)
op->flags |= XE_VMA_OP_COMMITTED;
break;
default:
- drm_warn(&vm->xe->drm, "NOT POSSIBLE");
+ drm_warn(&vm->xe->drm, "NOT POSSIBLE\n");
}
return err;
@@ -2783,7 +2782,7 @@ static int vm_bind_ioctl_ops_parse(struct xe_vm *vm, struct drm_gpuva_ops *ops,
break;
default:
- drm_warn(&vm->xe->drm, "NOT POSSIBLE");
+ drm_warn(&vm->xe->drm, "NOT POSSIBLE\n");
}
err = xe_vma_op_commit(vm, op);
@@ -2845,7 +2844,7 @@ static void xe_vma_op_unwind(struct xe_vm *vm, struct xe_vma_op *op,
/* Nothing to do */
break;
default:
- drm_warn(&vm->xe->drm, "NOT POSSIBLE");
+ drm_warn(&vm->xe->drm, "NOT POSSIBLE\n");
}
}
@@ -3029,7 +3028,7 @@ static int op_lock_and_prep(struct drm_exec *exec, struct xe_vm *vm,
break;
}
default:
- drm_warn(&vm->xe->drm, "NOT POSSIBLE");
+ drm_warn(&vm->xe->drm, "NOT POSSIBLE\n");
}
return err;
@@ -3268,7 +3267,7 @@ static void op_add_ufence(struct xe_vm *vm, struct xe_vma_op *op,
vma_add_ufence(gpuva_to_vma(op->base.prefetch.va), ufence);
break;
default:
- drm_warn(&vm->xe->drm, "NOT POSSIBLE");
+ drm_warn(&vm->xe->drm, "NOT POSSIBLE\n");
}
}
@@ -3405,6 +3404,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
DRM_XE_VM_BIND_FLAG_CPU_ADDR_MIRROR;
u16 pat_index = (*bind_ops)[i].pat_index;
u16 coh_mode;
+ bool comp_en;
if (XE_IOCTL_DBG(xe, is_cpu_addr_mirror &&
(!xe_vm_in_fault_mode(vm) ||
@@ -3421,6 +3421,7 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
pat_index = array_index_nospec(pat_index, xe->pat.n_entries);
(*bind_ops)[i].pat_index = pat_index;
coh_mode = xe_pat_index_get_coh_mode(xe, pat_index);
+ comp_en = xe_pat_index_get_comp_en(xe, pat_index);
if (XE_IOCTL_DBG(xe, !coh_mode)) { /* hw reserved */
err = -EINVAL;
goto free_bind_ops;
@@ -3451,6 +3452,8 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, coh_mode == XE_COH_NONE &&
op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
+ XE_IOCTL_DBG(xe, comp_en &&
+ op == DRM_XE_VM_BIND_OP_MAP_USERPTR) ||
XE_IOCTL_DBG(xe, op == DRM_XE_VM_BIND_OP_MAP_USERPTR &&
!IS_ENABLED(CONFIG_DRM_GPUSVM)) ||
XE_IOCTL_DBG(xe, obj &&
@@ -3529,6 +3532,7 @@ static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo,
u16 pat_index, u32 op, u32 bind_flags)
{
u16 coh_mode;
+ bool comp_en;
if (XE_IOCTL_DBG(xe, (bo->flags & XE_BO_FLAG_NO_COMPRESSION) &&
xe_pat_index_get_comp_en(xe, pat_index)))
@@ -3574,6 +3578,14 @@ static int xe_vm_bind_ioctl_validate_bo(struct xe_device *xe, struct xe_bo *bo,
return -EINVAL;
}
+ /*
+ * Ensures that imported buffer objects (dma-bufs) are not mapped
+ * with a PAT index that enables compression.
+ */
+ comp_en = xe_pat_index_get_comp_en(xe, pat_index);
+ if (XE_IOCTL_DBG(xe, bo->ttm.base.import_attach && comp_en))
+ return -EINVAL;
+
/* If a BO is protected it can only be mapped if the key is still valid */
if ((bind_flags & DRM_XE_VM_BIND_FLAG_CHECK_PXP) && xe_bo_is_protected(bo) &&
op != DRM_XE_VM_BIND_OP_UNMAP && op != DRM_XE_VM_BIND_OP_UNMAP_ALL)
diff --git a/drivers/gpu/drm/xe/xe_vm.h b/drivers/gpu/drm/xe/xe_vm.h
index 7d11ca47d73e..6cc98df47291 100644
--- a/drivers/gpu/drm/xe/xe_vm.h
+++ b/drivers/gpu/drm/xe/xe_vm.h
@@ -382,7 +382,7 @@ static inline void xe_vm_set_validation_exec(struct xe_vm *vm, struct drm_exec *
}
/**
- * xe_vm_set_validation_exec() - Accessor to read the drm_exec object
+ * xe_vm_validation_exec() - Accessor to read the drm_exec object
* @vm: The vm we want to register a drm_exec object with.
*
* Return: The drm_exec object used to lock the vm's resv. The value
diff --git a/drivers/gpu/drm/xe/xe_vram.c b/drivers/gpu/drm/xe/xe_vram.c
index c64d98bf1723..0538dcb8b18c 100644
--- a/drivers/gpu/drm/xe/xe_vram.c
+++ b/drivers/gpu/drm/xe/xe_vram.c
@@ -13,12 +13,10 @@
#include "regs/xe_gt_regs.h"
#include "regs/xe_regs.h"
#include "xe_assert.h"
-#include "xe_bo.h"
#include "xe_device.h"
#include "xe_force_wake.h"
#include "xe_gt_mcr.h"
#include "xe_mmio.h"
-#include "xe_module.h"
#include "xe_sriov.h"
#include "xe_tile_sriov_vf.h"
#include "xe_ttm_vram_mgr.h"
@@ -155,7 +153,7 @@ static int tile_vram_size(struct xe_tile *tile, u64 *vram_size,
*tile_offset = 0;
} else {
reg = xe_mmio_read32(&tile->mmio, SG_TILE_ADDR_RANGE(tile->id));
- *tile_size = (u64)REG_FIELD_GET(GENMASK(14, 8), reg) * SZ_1G;
+ *tile_size = (u64)REG_FIELD_GET(GENMASK(17, 8), reg) * SZ_1G;
*tile_offset = (u64)REG_FIELD_GET(GENMASK(7, 1), reg) * SZ_1G;
}
diff --git a/drivers/gpu/drm/xe/xe_vram_freq.c b/drivers/gpu/drm/xe/xe_vram_freq.c
index 17bc84da4cdc..6f8281e0b96a 100644
--- a/drivers/gpu/drm/xe/xe_vram_freq.c
+++ b/drivers/gpu/drm/xe/xe_vram_freq.c
@@ -5,7 +5,6 @@
#include <linux/sysfs.h>
#include <drm/drm_managed.h>
-#include "xe_gt_types.h"
#include "xe_pcode.h"
#include "xe_pcode_api.h"
#include "xe_tile.h"
diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c
index c83ea3d48fae..4ebb4dbe1c9b 100644
--- a/drivers/gpu/drm/xe/xe_vsec.c
+++ b/drivers/gpu/drm/xe/xe_vsec.c
@@ -12,7 +12,6 @@
#include "xe_device.h"
#include "xe_device_types.h"
-#include "xe_drv.h"
#include "xe_mmio.h"
#include "xe_platform_types.h"
#include "xe_pm.h"
diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
index a93717e77da0..a991ee2b8781 100644
--- a/drivers/gpu/drm/xe/xe_wa.c
+++ b/drivers/gpu/drm/xe/xe_wa.c
@@ -19,7 +19,7 @@
#include "regs/xe_regs.h"
#include "xe_device_types.h"
#include "xe_force_wake.h"
-#include "xe_gt.h"
+#include "xe_gt_types.h"
#include "xe_hw_engine_types.h"
#include "xe_mmio.h"
#include "xe_platform_types.h"
diff --git a/drivers/gpu/drm/xe/xe_wait_user_fence.c b/drivers/gpu/drm/xe/xe_wait_user_fence.c
index 5b4264ea38bd..51eb940ceb4e 100644
--- a/drivers/gpu/drm/xe/xe_wait_user_fence.c
+++ b/drivers/gpu/drm/xe/xe_wait_user_fence.c
@@ -11,7 +11,6 @@
#include <uapi/drm/xe_drm.h>
#include "xe_device.h"
-#include "xe_gt.h"
#include "xe_macros.h"
#include "xe_exec_queue.h"
diff --git a/drivers/gpu/drm/xe/xe_wopcm.c b/drivers/gpu/drm/xe/xe_wopcm.c
index ada0d0aa6b74..dde4f4967ca3 100644
--- a/drivers/gpu/drm/xe/xe_wopcm.c
+++ b/drivers/gpu/drm/xe/xe_wopcm.c
@@ -10,7 +10,7 @@
#include "regs/xe_guc_regs.h"
#include "xe_device.h"
#include "xe_force_wake.h"
-#include "xe_gt.h"
+#include "xe_gt_types.h"
#include "xe_mmio.h"
#include "xe_uc_fw.h"
diff --git a/include/uapi/drm/xe_drm.h b/include/uapi/drm/xe_drm.h
index bb69f9b30c7d..077e66a682e2 100644
--- a/include/uapi/drm/xe_drm.h
+++ b/include/uapi/drm/xe_drm.h
@@ -1280,9 +1280,6 @@ struct drm_xe_vm_bind {
* then a new multi-queue group is created with this queue as the primary queue
* (Q0). Otherwise, the queue gets added to the multi-queue group whose primary
* queue's exec_queue_id is specified in the lower 32 bits of the 'value' field.
- * If the extension's 'value' field has %DRM_XE_MULTI_GROUP_KEEP_ACTIVE flag
- * set, then the multi-queue group is kept active after the primary queue is
- * destroyed.
* All the other non-relevant bits of extension's 'value' field while adding the
* primary or the secondary queues of the group must be set to 0.
* - %DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY - Set the queue
@@ -1331,7 +1328,6 @@ struct drm_xe_exec_queue_create {
#define DRM_XE_EXEC_QUEUE_SET_HANG_REPLAY_STATE 3
#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_GROUP 4
#define DRM_XE_MULTI_GROUP_CREATE (1ull << 63)
-#define DRM_XE_MULTI_GROUP_KEEP_ACTIVE (1ull << 62)
#define DRM_XE_EXEC_QUEUE_SET_PROPERTY_MULTI_QUEUE_PRIORITY 5
/** @extensions: Pointer to the first extension struct, if any */
__u64 extensions;