mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
UAPI Changes:
- Expose PCIe link downgrade attributes (Raag) Cross-subsystem Changes: Core Changes: - gpusvm has_dma_mapping fix (Dafna) Driver Changes: - Forcewake hold fix (Tejas) - Fix guc_info debugfs for VFs (Daniele) - Fix devcoredump chunk alignment calculation (Arnd) - Don't print timedout job message on killed exec queues (Matt Brost) - Don't flush the GSC worker from the reset path (Daniele) - Use copy_from_user() instead of __copy_from_user() (Harish) - Only flush SVM garbage collector if CONFIG_DRM_XE_GPUSVM (Shuicheng) - Fix forcewake vs runtime pm ref release ordering (Shuicheng) - Move xe_device_sysfs_init() to xe_device_probe() (Raag) - Append PCIe Gen5 limitations to xe_firmware document (Raag) -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRskUM7w1oG5rx2IZO4FpNVCsYGvwUCaBzURgAKCRC4FpNVCsYG v/SOAQDrXSwMhiU8NFDI5+W2cGKqZa0Z9Jl69J/by97Cr38eMgEArl0wY5+aaSOs DYg6OADl6ZHlRdU4kpisHtOzG9V5OA8= =680Y -----END PGP SIGNATURE----- Merge tag 'drm-xe-next-2025-05-08' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next UAPI Changes: - Expose PCIe link downgrade attributes (Raag) Cross-subsystem Changes: Core Changes: - gpusvm has_dma_mapping fix (Dafna) Driver Changes: - Forcewake hold fix (Tejas) - Fix guc_info debugfs for VFs (Daniele) - Fix devcoredump chunk alignment calculation (Arnd) - Don't print timedout job message on killed exec queues (Matt Brost) - Don't flush the GSC worker from the reset path (Daniele) - Use copy_from_user() instead of __copy_from_user() (Harish) - Only flush SVM garbage collector if CONFIG_DRM_XE_GPUSVM (Shuicheng) - Fix forcewake vs runtime pm ref release ordering (Shuicheng) - Move xe_device_sysfs_init() to xe_device_probe() (Raag) - Append PCIe Gen5 limitations to xe_firmware document (Raag) Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Hellstrom <thomas.hellstrom@linux.intel.com> Link: https://lore.kernel.org/r/aBzUwbzCzz7Qo7fA@fedora
This commit is contained in:
commit
67322d35c3
|
|
@ -31,6 +31,12 @@ GuC Power Conservation (PC)
|
|||
.. kernel-doc:: drivers/gpu/drm/xe/xe_guc_pc.c
|
||||
:doc: GuC Power Conservation (PC)
|
||||
|
||||
PCIe Gen5 Limitations
|
||||
=====================
|
||||
|
||||
.. kernel-doc:: drivers/gpu/drm/xe/xe_device_sysfs.c
|
||||
:doc: PCIe Gen5 Limitations
|
||||
|
||||
Internal API
|
||||
============
|
||||
|
||||
|
|
|
|||
|
|
@ -46,8 +46,11 @@ static void read_l3cc_table(struct xe_gt *gt,
|
|||
unsigned int fw_ref, i;
|
||||
u32 reg_val;
|
||||
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
|
||||
KUNIT_ASSERT_NE_MSG(test, fw_ref, 0, "Forcewake Failed.\n");
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
|
||||
if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) {
|
||||
xe_force_wake_put(gt_to_fw(gt), fw_ref);
|
||||
KUNIT_ASSERT_TRUE_MSG(test, true, "Forcewake Failed.\n");
|
||||
}
|
||||
|
||||
for (i = 0; i < info->num_mocs_regs; i++) {
|
||||
if (!(i & 1)) {
|
||||
|
|
|
|||
|
|
@ -2569,7 +2569,7 @@ static int gem_create_user_ext_set_property(struct xe_device *xe,
|
|||
int err;
|
||||
u32 idx;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -2606,7 +2606,7 @@ static int gem_create_user_extensions(struct xe_device *xe, struct xe_bo *bo,
|
|||
if (XE_IOCTL_DBG(xe, ext_number >= MAX_USER_EXTENSIONS))
|
||||
return -E2BIG;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
|||
struct xe_devcoredump *coredump = data;
|
||||
struct xe_devcoredump_snapshot *ss;
|
||||
ssize_t byte_copied;
|
||||
u32 chunk_offset;
|
||||
ssize_t new_chunk_position;
|
||||
|
||||
if (!coredump)
|
||||
return -ENODEV;
|
||||
|
|
@ -201,10 +203,14 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
|||
return 0;
|
||||
}
|
||||
|
||||
new_chunk_position = div_u64_rem(offset,
|
||||
XE_DEVCOREDUMP_CHUNK_MAX,
|
||||
&chunk_offset);
|
||||
|
||||
if (offset >= ss->read.chunk_position + XE_DEVCOREDUMP_CHUNK_MAX ||
|
||||
offset < ss->read.chunk_position) {
|
||||
ss->read.chunk_position =
|
||||
ALIGN_DOWN(offset, XE_DEVCOREDUMP_CHUNK_MAX);
|
||||
ss->read.chunk_position = new_chunk_position *
|
||||
XE_DEVCOREDUMP_CHUNK_MAX;
|
||||
|
||||
__xe_devcoredump_read(ss->read.buffer,
|
||||
XE_DEVCOREDUMP_CHUNK_MAX,
|
||||
|
|
@ -213,8 +219,7 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
|||
|
||||
byte_copied = count < ss->read.size - offset ? count :
|
||||
ss->read.size - offset;
|
||||
memcpy(buffer, ss->read.buffer +
|
||||
(offset % XE_DEVCOREDUMP_CHUNK_MAX), byte_copied);
|
||||
memcpy(buffer, ss->read.buffer + chunk_offset, byte_copied);
|
||||
|
||||
mutex_unlock(&coredump->lock);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "xe_bo_evict.h"
|
||||
#include "xe_debugfs.h"
|
||||
#include "xe_devcoredump.h"
|
||||
#include "xe_device_sysfs.h"
|
||||
#include "xe_dma_buf.h"
|
||||
#include "xe_drm_client.h"
|
||||
#include "xe_drv.h"
|
||||
|
|
@ -915,6 +916,10 @@ int xe_device_probe(struct xe_device *xe)
|
|||
if (err)
|
||||
goto err_unregister_display;
|
||||
|
||||
err = xe_device_sysfs_init(xe);
|
||||
if (err)
|
||||
goto err_unregister_display;
|
||||
|
||||
xe_debugfs_register(xe);
|
||||
|
||||
err = xe_hwmon_register(xe);
|
||||
|
|
|
|||
|
|
@ -3,14 +3,16 @@
|
|||
* Copyright © 2023 Intel Corporation
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/kobject.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <drm/drm_managed.h>
|
||||
|
||||
#include "xe_device.h"
|
||||
#include "xe_device_sysfs.h"
|
||||
#include "xe_mmio.h"
|
||||
#include "xe_pcode_api.h"
|
||||
#include "xe_pcode.h"
|
||||
#include "xe_pm.h"
|
||||
|
||||
/**
|
||||
|
|
@ -63,11 +65,93 @@ vram_d3cold_threshold_store(struct device *dev, struct device_attribute *attr,
|
|||
|
||||
static DEVICE_ATTR_RW(vram_d3cold_threshold);
|
||||
|
||||
/**
|
||||
* DOC: PCIe Gen5 Limitations
|
||||
*
|
||||
* Default link speed of discrete GPUs is determined by configuration parameters
|
||||
* stored in their flash memory, which are subject to override through user
|
||||
* initiated firmware updates. It has been observed that devices configured with
|
||||
* PCIe Gen5 as their default link speed can come across link quality issues due
|
||||
* to host or motherboard limitations and may have to auto-downgrade their link
|
||||
* to PCIe Gen4 speed when faced with unstable link at Gen5, which makes
|
||||
* firmware updates rather risky on such setups. It is required to ensure that
|
||||
* the device is capable of auto-downgrading its link to PCIe Gen4 speed before
|
||||
* pushing the firmware image with PCIe Gen5 as default configuration. This can
|
||||
* be done by reading ``auto_link_downgrade_capable`` sysfs entry, which will
|
||||
* denote if the device is capable of auto-downgrading its link to PCIe Gen4
|
||||
* speed with boolean output value of ``0`` or ``1``, meaning `incapable` or
|
||||
* `capable` respectively.
|
||||
*
|
||||
* .. code-block:: shell
|
||||
*
|
||||
* $ cat /sys/bus/pci/devices/<bdf>/auto_link_downgrade_capable
|
||||
*
|
||||
* Pushing the firmware image with PCIe Gen5 as default configuration on a auto
|
||||
* link downgrade incapable device and facing link instability due to host or
|
||||
* motherboard limitations can result in driver failing to bind to the device,
|
||||
* making further firmware updates impossible with RMA being the only last
|
||||
* resort.
|
||||
*
|
||||
* Link downgrade status of auto link downgrade capable devices is available
|
||||
* through ``auto_link_downgrade_status`` sysfs entry with boolean output value
|
||||
* of ``0`` or ``1``, where ``0`` means no auto-downgrading was required during
|
||||
* link training (which is the optimal scenario) and ``1`` means the device has
|
||||
* auto-downgraded its link to PCIe Gen4 speed due to unstable Gen5 link.
|
||||
*
|
||||
* .. code-block:: shell
|
||||
*
|
||||
* $ cat /sys/bus/pci/devices/<bdf>/auto_link_downgrade_status
|
||||
*/
|
||||
|
||||
static ssize_t
|
||||
auto_link_downgrade_capable_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct xe_device *xe = pdev_to_xe_device(pdev);
|
||||
u32 cap, val;
|
||||
|
||||
xe_pm_runtime_get(xe);
|
||||
val = xe_mmio_read32(xe_root_tile_mmio(xe), BMG_PCIE_CAP);
|
||||
xe_pm_runtime_put(xe);
|
||||
|
||||
cap = REG_FIELD_GET(LINK_DOWNGRADE, val);
|
||||
return sysfs_emit(buf, "%u\n", cap == DOWNGRADE_CAPABLE ? true : false);
|
||||
}
|
||||
static DEVICE_ATTR_ADMIN_RO(auto_link_downgrade_capable);
|
||||
|
||||
static ssize_t
|
||||
auto_link_downgrade_status_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct xe_device *xe = pdev_to_xe_device(pdev);
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
xe_pm_runtime_get(xe);
|
||||
ret = xe_pcode_read(xe_device_get_root_tile(xe),
|
||||
PCODE_MBOX(DGFX_PCODE_STATUS, DGFX_GET_INIT_STATUS, 0),
|
||||
&val, NULL);
|
||||
xe_pm_runtime_put(xe);
|
||||
|
||||
return ret ?: sysfs_emit(buf, "%u\n", REG_FIELD_GET(DGFX_LINK_DOWNGRADE_STATUS, val));
|
||||
}
|
||||
static DEVICE_ATTR_ADMIN_RO(auto_link_downgrade_status);
|
||||
|
||||
static const struct attribute *auto_link_downgrade_attrs[] = {
|
||||
&dev_attr_auto_link_downgrade_capable.attr,
|
||||
&dev_attr_auto_link_downgrade_status.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void xe_device_sysfs_fini(void *arg)
|
||||
{
|
||||
struct xe_device *xe = arg;
|
||||
|
||||
sysfs_remove_file(&xe->drm.dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
|
||||
if (xe->d3cold.capable)
|
||||
sysfs_remove_file(&xe->drm.dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
|
||||
|
||||
if (xe->info.platform == XE_BATTLEMAGE)
|
||||
sysfs_remove_files(&xe->drm.dev->kobj, auto_link_downgrade_attrs);
|
||||
}
|
||||
|
||||
int xe_device_sysfs_init(struct xe_device *xe)
|
||||
|
|
@ -75,9 +159,17 @@ int xe_device_sysfs_init(struct xe_device *xe)
|
|||
struct device *dev = xe->drm.dev;
|
||||
int ret;
|
||||
|
||||
ret = sysfs_create_file(&dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (xe->d3cold.capable) {
|
||||
ret = sysfs_create_file(&dev->kobj, &dev_attr_vram_d3cold_threshold.attr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (xe->info.platform == XE_BATTLEMAGE) {
|
||||
ret = sysfs_create_files(&dev->kobj, auto_link_downgrade_attrs);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(dev, xe_device_sysfs_fini, xe);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ static int xe_eu_stall_user_ext_set_property(struct xe_device *xe, u64 extension
|
|||
int err;
|
||||
u32 idx;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -313,7 +313,7 @@ static int xe_eu_stall_user_extensions(struct xe_device *xe, u64 extension,
|
|||
if (XE_IOCTL_DBG(xe, ext_number >= MAX_USER_EXTENSIONS))
|
||||
return -E2BIG;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -176,8 +176,8 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
}
|
||||
|
||||
if (xe_exec_queue_is_parallel(q)) {
|
||||
err = __copy_from_user(addresses, addresses_user, sizeof(u64) *
|
||||
q->width);
|
||||
err = copy_from_user(addresses, addresses_user, sizeof(u64) *
|
||||
q->width);
|
||||
if (err) {
|
||||
err = -EFAULT;
|
||||
goto err_syncs;
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ static int exec_queue_user_ext_set_property(struct xe_device *xe,
|
|||
int err;
|
||||
u32 idx;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -518,7 +518,7 @@ static int exec_queue_user_extensions(struct xe_device *xe, struct xe_exec_queue
|
|||
if (XE_IOCTL_DBG(xe, ext_number >= MAX_USER_EXTENSIONS))
|
||||
return -E2BIG;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -618,9 +618,8 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data,
|
|||
if (XE_IOCTL_DBG(xe, !len || len > XE_HW_ENGINE_MAX_INSTANCE))
|
||||
return -EINVAL;
|
||||
|
||||
err = __copy_from_user(eci, user_eci,
|
||||
sizeof(struct drm_xe_engine_class_instance) *
|
||||
len);
|
||||
err = copy_from_user(eci, user_eci,
|
||||
sizeof(struct drm_xe_engine_class_instance) * len);
|
||||
if (XE_IOCTL_DBG(xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -555,6 +555,28 @@ void xe_gsc_wait_for_worker_completion(struct xe_gsc *gsc)
|
|||
flush_work(&gsc->work);
|
||||
}
|
||||
|
||||
void xe_gsc_stop_prepare(struct xe_gsc *gsc)
|
||||
{
|
||||
struct xe_gt *gt = gsc_to_gt(gsc);
|
||||
int ret;
|
||||
|
||||
if (!xe_uc_fw_is_loadable(&gsc->fw) || xe_uc_fw_is_in_error_state(&gsc->fw))
|
||||
return;
|
||||
|
||||
xe_force_wake_assert_held(gt_to_fw(gt), XE_FW_GSC);
|
||||
|
||||
/*
|
||||
* If the GSC FW load or the proxy init are interrupted, the only way
|
||||
* to recover it is to do an FLR and reload the GSC from scratch.
|
||||
* Therefore, let's wait for the init to complete before stopping
|
||||
* operations. The proxy init is the last step, so we can just wait on
|
||||
* that
|
||||
*/
|
||||
ret = xe_gsc_wait_for_proxy_init_done(gsc);
|
||||
if (ret)
|
||||
xe_gt_err(gt, "failed to wait for GSC init completion before uc stop\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* wa_14015076503: if the GSC FW is loaded, we need to alert it before doing a
|
||||
* GSC engine reset by writing a notification bit in the GS1 register and then
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ struct xe_hw_engine;
|
|||
int xe_gsc_init(struct xe_gsc *gsc);
|
||||
int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc);
|
||||
void xe_gsc_wait_for_worker_completion(struct xe_gsc *gsc);
|
||||
void xe_gsc_stop_prepare(struct xe_gsc *gsc);
|
||||
void xe_gsc_load_start(struct xe_gsc *gsc);
|
||||
void xe_gsc_hwe_irq_handler(struct xe_hw_engine *hwe, u16 intr_vec);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,17 @@ bool xe_gsc_proxy_init_done(struct xe_gsc *gsc)
|
|||
HECI1_FWSTS1_PROXY_STATE_NORMAL;
|
||||
}
|
||||
|
||||
int xe_gsc_wait_for_proxy_init_done(struct xe_gsc *gsc)
|
||||
{
|
||||
struct xe_gt *gt = gsc_to_gt(gsc);
|
||||
|
||||
/* Proxy init can take up to 500ms, so wait double that for safety */
|
||||
return xe_mmio_wait32(>->mmio, HECI_FWSTS1(MTL_GSC_HECI1_BASE),
|
||||
HECI1_FWSTS1_CURRENT_STATE,
|
||||
HECI1_FWSTS1_PROXY_STATE_NORMAL,
|
||||
USEC_PER_SEC, NULL, false);
|
||||
}
|
||||
|
||||
static void __gsc_proxy_irq_rmw(struct xe_gsc *gsc, u32 clr, u32 set)
|
||||
{
|
||||
struct xe_gt *gt = gsc_to_gt(gsc);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ struct xe_gsc;
|
|||
|
||||
int xe_gsc_proxy_init(struct xe_gsc *gsc);
|
||||
bool xe_gsc_proxy_init_done(struct xe_gsc *gsc);
|
||||
int xe_gsc_wait_for_proxy_init_done(struct xe_gsc *gsc);
|
||||
int xe_gsc_proxy_start(struct xe_gsc *gsc);
|
||||
|
||||
int xe_gsc_proxy_request_handler(struct xe_gsc *gsc);
|
||||
|
|
|
|||
|
|
@ -899,7 +899,7 @@ void xe_gt_suspend_prepare(struct xe_gt *gt)
|
|||
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
|
||||
|
||||
xe_uc_stop_prepare(>->uc);
|
||||
xe_uc_suspend_prepare(>->uc);
|
||||
|
||||
xe_force_wake_put(gt_to_fw(gt), fw_ref);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,22 +92,23 @@ static int hw_engines(struct xe_gt *gt, struct drm_printer *p)
|
|||
struct xe_hw_engine *hwe;
|
||||
enum xe_hw_engine_id id;
|
||||
unsigned int fw_ref;
|
||||
int ret = 0;
|
||||
|
||||
xe_pm_runtime_get(xe);
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
|
||||
if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) {
|
||||
xe_pm_runtime_put(xe);
|
||||
xe_force_wake_put(gt_to_fw(gt), fw_ref);
|
||||
return -ETIMEDOUT;
|
||||
ret = -ETIMEDOUT;
|
||||
goto fw_put;
|
||||
}
|
||||
|
||||
for_each_hw_engine(hwe, gt, id)
|
||||
xe_hw_engine_print(hwe, p);
|
||||
|
||||
fw_put:
|
||||
xe_force_wake_put(gt_to_fw(gt), fw_ref);
|
||||
xe_pm_runtime_put(xe);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int powergate_info(struct xe_gt *gt, struct drm_printer *p)
|
||||
|
|
|
|||
|
|
@ -1510,30 +1510,32 @@ void xe_guc_print_info(struct xe_guc *guc, struct drm_printer *p)
|
|||
|
||||
xe_uc_fw_print(&guc->fw, p);
|
||||
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
|
||||
if (!fw_ref)
|
||||
return;
|
||||
if (!IS_SRIOV_VF(gt_to_xe(gt))) {
|
||||
fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GT);
|
||||
if (!fw_ref)
|
||||
return;
|
||||
|
||||
status = xe_mmio_read32(>->mmio, GUC_STATUS);
|
||||
status = xe_mmio_read32(>->mmio, GUC_STATUS);
|
||||
|
||||
drm_printf(p, "\nGuC status 0x%08x:\n", status);
|
||||
drm_printf(p, "\tBootrom status = 0x%x\n",
|
||||
REG_FIELD_GET(GS_BOOTROM_MASK, status));
|
||||
drm_printf(p, "\tuKernel status = 0x%x\n",
|
||||
REG_FIELD_GET(GS_UKERNEL_MASK, status));
|
||||
drm_printf(p, "\tMIA Core status = 0x%x\n",
|
||||
REG_FIELD_GET(GS_MIA_MASK, status));
|
||||
drm_printf(p, "\tLog level = %d\n",
|
||||
xe_guc_log_get_level(&guc->log));
|
||||
drm_printf(p, "\nGuC status 0x%08x:\n", status);
|
||||
drm_printf(p, "\tBootrom status = 0x%x\n",
|
||||
REG_FIELD_GET(GS_BOOTROM_MASK, status));
|
||||
drm_printf(p, "\tuKernel status = 0x%x\n",
|
||||
REG_FIELD_GET(GS_UKERNEL_MASK, status));
|
||||
drm_printf(p, "\tMIA Core status = 0x%x\n",
|
||||
REG_FIELD_GET(GS_MIA_MASK, status));
|
||||
drm_printf(p, "\tLog level = %d\n",
|
||||
xe_guc_log_get_level(&guc->log));
|
||||
|
||||
drm_puts(p, "\nScratch registers:\n");
|
||||
for (i = 0; i < SOFT_SCRATCH_COUNT; i++) {
|
||||
drm_printf(p, "\t%2d: \t0x%x\n",
|
||||
i, xe_mmio_read32(>->mmio, SOFT_SCRATCH(i)));
|
||||
drm_puts(p, "\nScratch registers:\n");
|
||||
for (i = 0; i < SOFT_SCRATCH_COUNT; i++) {
|
||||
drm_printf(p, "\t%2d: \t0x%x\n",
|
||||
i, xe_mmio_read32(>->mmio, SOFT_SCRATCH(i)));
|
||||
}
|
||||
|
||||
xe_force_wake_put(gt_to_fw(gt), fw_ref);
|
||||
}
|
||||
|
||||
xe_force_wake_put(gt_to_fw(gt), fw_ref);
|
||||
|
||||
drm_puts(p, "\n");
|
||||
xe_guc_ct_print(&guc->ct, p, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -1179,9 +1179,12 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job)
|
|||
process_name = q->vm->xef->process_name;
|
||||
pid = q->vm->xef->pid;
|
||||
}
|
||||
xe_gt_notice(guc_to_gt(guc), "Timedout job: seqno=%u, lrc_seqno=%u, guc_id=%d, flags=0x%lx in %s [%d]",
|
||||
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
|
||||
q->guc->id, q->flags, process_name, pid);
|
||||
|
||||
if (!exec_queue_killed(q))
|
||||
xe_gt_notice(guc_to_gt(guc),
|
||||
"Timedout job: seqno=%u, lrc_seqno=%u, guc_id=%d, flags=0x%lx in %s [%d]",
|
||||
xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job),
|
||||
q->guc->id, q->flags, process_name, pid);
|
||||
|
||||
trace_xe_sched_job_timedout(job);
|
||||
|
||||
|
|
|
|||
|
|
@ -1301,7 +1301,7 @@ static int xe_oa_user_ext_set_property(struct xe_oa *oa, enum xe_oa_user_extn_fr
|
|||
int err;
|
||||
u32 idx;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(oa->xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -1338,7 +1338,7 @@ static int xe_oa_user_extensions(struct xe_oa *oa, enum xe_oa_user_extn_from fro
|
|||
if (XE_IOCTL_DBG(oa->xe, ext_number >= MAX_USER_EXTENSIONS))
|
||||
return -E2BIG;
|
||||
|
||||
err = __copy_from_user(&ext, address, sizeof(ext));
|
||||
err = copy_from_user(&ext, address, sizeof(ext));
|
||||
if (XE_IOCTL_DBG(oa->xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
@ -2281,7 +2281,7 @@ int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *fi
|
|||
return -EACCES;
|
||||
}
|
||||
|
||||
err = __copy_from_user(¶m, u64_to_user_ptr(data), sizeof(param));
|
||||
err = copy_from_user(¶m, u64_to_user_ptr(data), sizeof(param));
|
||||
if (XE_IOCTL_DBG(oa->xe, err))
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#define DGFX_PCODE_STATUS 0x7E
|
||||
#define DGFX_GET_INIT_STATUS 0x0
|
||||
#define DGFX_INIT_STATUS_COMPLETE 0x1
|
||||
#define DGFX_LINK_DOWNGRADE_STATUS REG_BIT(31)
|
||||
|
||||
#define PCODE_POWER_SETUP 0x7C
|
||||
#define POWER_SETUP_SUBCOMMAND_READ_I1 0x4
|
||||
|
|
@ -66,6 +67,10 @@
|
|||
/* Auxiliary info bits */
|
||||
#define AUXINFO_HISTORY_OFFSET REG_GENMASK(31, 29)
|
||||
|
||||
#define BMG_PCIE_CAP XE_REG(0x138340)
|
||||
#define LINK_DOWNGRADE REG_GENMASK(1, 0)
|
||||
#define DOWNGRADE_CAPABLE 2
|
||||
|
||||
struct pcode_err_decode {
|
||||
int errno;
|
||||
const char *str;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
#include "xe_bo.h"
|
||||
#include "xe_bo_evict.h"
|
||||
#include "xe_device.h"
|
||||
#include "xe_device_sysfs.h"
|
||||
#include "xe_ggtt.h"
|
||||
#include "xe_gt.h"
|
||||
#include "xe_guc.h"
|
||||
|
|
@ -273,6 +272,7 @@ int xe_pm_init_early(struct xe_device *xe)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
xe->d3cold.capable = xe_pm_pci_d3cold_capable(xe);
|
||||
return 0;
|
||||
}
|
||||
ALLOW_ERROR_INJECTION(xe_pm_init_early, ERRNO); /* See xe_pci_probe() */
|
||||
|
|
@ -344,13 +344,7 @@ int xe_pm_init(struct xe_device *xe)
|
|||
if (!xe_device_uc_enabled(xe))
|
||||
return 0;
|
||||
|
||||
xe->d3cold.capable = xe_pm_pci_d3cold_capable(xe);
|
||||
|
||||
if (xe->d3cold.capable) {
|
||||
err = xe_device_sysfs_init(xe);
|
||||
if (err)
|
||||
goto err_unregister;
|
||||
|
||||
vram_threshold = vram_threshold_value(xe);
|
||||
err = xe_pm_set_vram_threshold(xe, vram_threshold);
|
||||
if (err)
|
||||
|
|
|
|||
|
|
@ -726,7 +726,6 @@ static int xe_svm_alloc_vram(struct xe_vm *vm, struct xe_tile *tile,
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* xe_svm_handle_pagefault() - SVM handle page fault
|
||||
* @vm: The VM.
|
||||
|
|
@ -966,3 +965,15 @@ int xe_devm_add(struct xe_tile *tile, struct xe_vram_region *vr)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* xe_svm_flush() - SVM flush
|
||||
* @vm: The VM.
|
||||
*
|
||||
* Flush all SVM actions.
|
||||
*/
|
||||
void xe_svm_flush(struct xe_vm *vm)
|
||||
{
|
||||
if (xe_vm_in_fault_mode(vm))
|
||||
flush_work(&vm->svm.garbage_collector.work);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ static inline bool xe_svm_range_has_dma_mapping(struct xe_svm_range *range)
|
|||
#define xe_svm_notifier_unlock(vm__) \
|
||||
drm_gpusvm_notifier_unlock(&(vm__)->svm.gpusvm)
|
||||
|
||||
void xe_svm_flush(struct xe_vm *vm);
|
||||
|
||||
#else
|
||||
#include <linux/interval_tree.h>
|
||||
|
||||
|
|
@ -180,5 +182,9 @@ static inline void xe_svm_notifier_lock(struct xe_vm *vm)
|
|||
static inline void xe_svm_notifier_unlock(struct xe_vm *vm)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void xe_svm_flush(struct xe_vm *vm)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ void xe_uc_gucrc_disable(struct xe_uc *uc)
|
|||
|
||||
void xe_uc_stop_prepare(struct xe_uc *uc)
|
||||
{
|
||||
xe_gsc_wait_for_worker_completion(&uc->gsc);
|
||||
xe_gsc_stop_prepare(&uc->gsc);
|
||||
xe_guc_stop_prepare(&uc->guc);
|
||||
}
|
||||
|
||||
|
|
@ -278,6 +278,12 @@ static void uc_reset_wait(struct xe_uc *uc)
|
|||
goto again;
|
||||
}
|
||||
|
||||
void xe_uc_suspend_prepare(struct xe_uc *uc)
|
||||
{
|
||||
xe_gsc_wait_for_worker_completion(&uc->gsc);
|
||||
xe_guc_stop_prepare(&uc->guc);
|
||||
}
|
||||
|
||||
int xe_uc_suspend(struct xe_uc *uc)
|
||||
{
|
||||
/* GuC submission not enabled, nothing to do */
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ int xe_uc_reset_prepare(struct xe_uc *uc);
|
|||
void xe_uc_stop_prepare(struct xe_uc *uc);
|
||||
void xe_uc_stop(struct xe_uc *uc);
|
||||
int xe_uc_start(struct xe_uc *uc);
|
||||
void xe_uc_suspend_prepare(struct xe_uc *uc);
|
||||
int xe_uc_suspend(struct xe_uc *uc);
|
||||
int xe_uc_sanitize_reset(struct xe_uc *uc);
|
||||
void xe_uc_declare_wedged(struct xe_uc *uc);
|
||||
|
|
|
|||
|
|
@ -3101,9 +3101,9 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm,
|
|||
if (!*bind_ops)
|
||||
return args->num_binds > 1 ? -ENOBUFS : -ENOMEM;
|
||||
|
||||
err = __copy_from_user(*bind_ops, bind_user,
|
||||
sizeof(struct drm_xe_vm_bind_op) *
|
||||
args->num_binds);
|
||||
err = copy_from_user(*bind_ops, bind_user,
|
||||
sizeof(struct drm_xe_vm_bind_op) *
|
||||
args->num_binds);
|
||||
if (XE_IOCTL_DBG(xe, err)) {
|
||||
err = -EFAULT;
|
||||
goto free_bind_ops;
|
||||
|
|
@ -3331,8 +3331,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
|
|||
}
|
||||
|
||||
/* Ensure all UNMAPs visible */
|
||||
if (xe_vm_in_fault_mode(vm))
|
||||
flush_work(&vm->svm.garbage_collector.work);
|
||||
xe_svm_flush(vm);
|
||||
|
||||
err = down_write_killable(&vm->lock);
|
||||
if (err)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user