mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 15:03:53 +02:00
drm-fixes for 6.16-rc6
Cross-subsystem Changes: - agp/amd64 binding dmesg noise regression fix Core Changes: - fix race in gem_handle_create_tail - fixup handle_count fb refcount regression from -rc5, popular with reports ... - call rust dtor for drm_device release Driver Changes: - nouveau: magic 50ms suspend fix, acpi leak fix - tegra: dma api error in nvdec - pvr: fix device reset - habanalbs maintainer update - intel display: fix some dsi mipi sequences - xe fixes: SRIOV fixes, small GuC fixes, disable indirect ring due to issues, compression fix for fragmented BO, doc update -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEciDa6W7nX7VwIxa1EpWk/0GBDXwFAmhxiyEACgkQEpWk/0GB DXya2g//VrFDRXgSVuDpsJaqw90cnI3MS5a1xMaoF/I3wnAX3a4xMJsEKkN1mNgr dZdVzJGEi9AAWejbq058iKGPP3sOKigVa8VWKURiSvq2HlQQqbUOur1H8L0fAYW3 ELsvAEtzrNC4OsqPy1aCIrd9JpYB70oVeU+DjALn5CELFAahhk47DtZhosZDDzIw QywEmSKotkE2Nh9i2ELpsN6MlgFgWorJS5S81vegvgejJiEHnFc0640oQdEefuhy W+SthOmV4qege2NTQrESoEpvoxYRpuKg1gulz1h0snBEeGTHYt14txjBosYTeeQo tPNiDN0HQdN0Rga+Kh8bluaHe1bK6H9BWRHziznypPM8gLGuWUFS20D0F86aLkpf hsOMPjpA4TeeU2nczmWg2966aXINoRgaWCNTkF8gG092Ag24OKrw+WxH0DB+XaST y/AkqsDgMMJgk9t8Nl3gvn0FG7vxWvshp/ew7hWdhr9TdPy9ooiUbsJ4TKdznPue sKw26i2J0Cv/EaWe3b5bz5rFhJm28EDZMvofEcg/k97UXI92QCeU9XgPEAVlzV3P SKakr8DaIS4EqQPI11kNrhXeVsN5kVYlqUOd4jnkRDu/8MjsNBFwTfHHX/paM0Ry woP88hbNA+zpbW/RZSNuI9kuRvIIyXuE3fb1GmNzsZrdSwyAVnE= =urPs -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2025-07-12' of https://gitlab.freedesktop.org/drm/kernel Pull drm fixes from Simona Vetter: "Cross-subsystem Changes: - agp/amd64 binding dmesg noise regression fix Core Changes: - fix race in gem_handle_create_tail - fixup handle_count fb refcount regression from -rc5, popular with reports ... - call rust dtor for drm_device release Driver Changes: - nouveau: magic 50ms suspend fix, acpi leak fix - tegra: dma api error in nvdec - pvr: fix device reset - habanalbs maintainer update - intel display: fix some dsi mipi sequences - xe fixes: SRIOV fixes, small GuC fixes, disable indirect ring due to issues, compression fix for fragmented BO, doc update * tag 'drm-fixes-2025-07-12' of https://gitlab.freedesktop.org/drm/kernel: (22 commits) drm/xe/guc: Default log level to non-verbose drm/xe/bmg: Don't use WA 16023588340 and 22019338487 on VF drm/xe/guc: Recommend GuC v70.46.2 for BMG, LNL, DG2 drm/xe/pm: Correct comment of xe_pm_set_vram_threshold() drm/xe: Release runtime pm for error path of xe_devcoredump_read() drm/xe/pm: Restore display pm if there is error after display suspend drm/i915/bios: Apply vlv_fixup_mipi_sequences() to v2 mipi-sequences too drm/gem: Fix race in drm_gem_handle_create_tail() drm/framebuffer: Acquire internal references on GEM handles agp/amd64: Check AGP Capability before binding to unsupported devices drm/xe/bmg: fix compressed VRAM handling Revert "drm/xe/xe2: Enable Indirect Ring State support for Xe2" drm/xe: Allocate PF queue size on pow2 boundary drm/xe/pf: Clear all LMTT pages on alloc drm/nouveau/gsp: fix potential leak of memory used during acpi init rust: drm: remove unnecessary imports MAINTAINERS: Change habanalabs maintainer drm/imagination: Fix kernel crash when hard resetting the GPU drm/tegra: nvdec: Fix dma_alloc_coherent error check rust: drm: device: drop_in_place() the drm::Device in release() ...
This commit is contained in:
commit
3c2fe27971
|
@ -10506,7 +10506,7 @@ S: Maintained
|
|||
F: block/partitions/efi.*
|
||||
|
||||
HABANALABS PCI DRIVER
|
||||
M: Ofir Bitton <obitton@habana.ai>
|
||||
M: Yaron Avizrat <yaron.avizrat@intel.com>
|
||||
L: dri-devel@lists.freedesktop.org
|
||||
S: Supported
|
||||
C: irc://irc.oftc.net/dri-devel
|
||||
|
|
|
@ -720,11 +720,6 @@ static const struct pci_device_id agp_amd64_pci_table[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
|
||||
|
||||
static const struct pci_device_id agp_amd64_pci_promisc_table[] = {
|
||||
{ PCI_DEVICE_CLASS(0, 0) },
|
||||
{ }
|
||||
};
|
||||
|
||||
static DEFINE_SIMPLE_DEV_PM_OPS(agp_amd64_pm_ops, NULL, agp_amd64_resume);
|
||||
|
||||
static struct pci_driver agp_amd64_pci_driver = {
|
||||
|
@ -739,6 +734,7 @@ static struct pci_driver agp_amd64_pci_driver = {
|
|||
/* Not static due to IOMMU code calling it early. */
|
||||
int __init agp_amd64_init(void)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
int err = 0;
|
||||
|
||||
if (agp_off)
|
||||
|
@ -767,9 +763,13 @@ int __init agp_amd64_init(void)
|
|||
}
|
||||
|
||||
/* Look for any AGP bridge */
|
||||
agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table;
|
||||
err = driver_attach(&agp_amd64_pci_driver.driver);
|
||||
if (err == 0 && agp_bridges_found == 0) {
|
||||
for_each_pci_dev(pdev)
|
||||
if (pci_find_capability(pdev, PCI_CAP_ID_AGP))
|
||||
pci_add_dynid(&agp_amd64_pci_driver,
|
||||
pdev->vendor, pdev->device,
|
||||
pdev->subsystem_vendor,
|
||||
pdev->subsystem_device, 0, 0, 0);
|
||||
if (agp_bridges_found == 0) {
|
||||
pci_unregister_driver(&agp_amd64_pci_driver);
|
||||
err = -ENODEV;
|
||||
}
|
||||
|
|
|
@ -862,11 +862,23 @@ EXPORT_SYMBOL_FOR_TESTS_ONLY(drm_framebuffer_free);
|
|||
int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
||||
const struct drm_framebuffer_funcs *funcs)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
bool exists;
|
||||
|
||||
if (WARN_ON_ONCE(fb->dev != dev || !fb->format))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
if (drm_WARN_ON_ONCE(dev, fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)))
|
||||
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
|
||||
if (fb->obj[i]) {
|
||||
exists = drm_gem_object_handle_get_if_exists_unlocked(fb->obj[i]);
|
||||
if (exists)
|
||||
fb->internal_flags |= DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
|
||||
}
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&fb->filp_head);
|
||||
|
||||
fb->funcs = funcs;
|
||||
|
@ -875,7 +887,7 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
|||
ret = __drm_mode_object_add(dev, &fb->base, DRM_MODE_OBJECT_FB,
|
||||
false, drm_framebuffer_free);
|
||||
if (ret)
|
||||
goto out;
|
||||
goto err;
|
||||
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
dev->mode_config.num_fb++;
|
||||
|
@ -883,7 +895,16 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
|
|||
mutex_unlock(&dev->mode_config.fb_lock);
|
||||
|
||||
drm_mode_object_register(dev, &fb->base);
|
||||
out:
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i)) {
|
||||
drm_gem_object_handle_put_unlocked(fb->obj[i]);
|
||||
fb->internal_flags &= ~DRM_FRAMEBUFFER_HAS_HANDLE_REF(i);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_framebuffer_init);
|
||||
|
@ -960,6 +981,12 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);
|
|||
void drm_framebuffer_cleanup(struct drm_framebuffer *fb)
|
||||
{
|
||||
struct drm_device *dev = fb->dev;
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
if (fb->internal_flags & DRM_FRAMEBUFFER_HAS_HANDLE_REF(i))
|
||||
drm_gem_object_handle_put_unlocked(fb->obj[i]);
|
||||
}
|
||||
|
||||
mutex_lock(&dev->mode_config.fb_lock);
|
||||
list_del(&fb->head);
|
||||
|
|
|
@ -223,23 +223,34 @@ static void drm_gem_object_handle_get(struct drm_gem_object *obj)
|
|||
}
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_get_unlocked - acquire reference on user-space handles
|
||||
* drm_gem_object_handle_get_if_exists_unlocked - acquire reference on user-space handle, if any
|
||||
* @obj: GEM object
|
||||
*
|
||||
* Acquires a reference on the GEM buffer object's handle. Required
|
||||
* to keep the GEM object alive. Call drm_gem_object_handle_put_unlocked()
|
||||
* to release the reference.
|
||||
* Acquires a reference on the GEM buffer object's handle. Required to keep
|
||||
* the GEM object alive. Call drm_gem_object_handle_put_if_exists_unlocked()
|
||||
* to release the reference. Does nothing if the buffer object has no handle.
|
||||
*
|
||||
* Returns:
|
||||
* True if a handle exists, or false otherwise
|
||||
*/
|
||||
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj)
|
||||
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj)
|
||||
{
|
||||
struct drm_device *dev = obj->dev;
|
||||
|
||||
guard(mutex)(&dev->object_name_lock);
|
||||
|
||||
drm_WARN_ON(dev, !obj->handle_count); /* first ref taken in create-tail helper */
|
||||
/*
|
||||
* First ref taken during GEM object creation, if any. Some
|
||||
* drivers set up internal framebuffers with GEM objects that
|
||||
* do not have a GEM handle. Hence, this counter can be zero.
|
||||
*/
|
||||
if (!obj->handle_count)
|
||||
return false;
|
||||
|
||||
drm_gem_object_handle_get(obj);
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_object_handle_get_unlocked);
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_free - release resources bound to userspace handles
|
||||
|
@ -272,7 +283,7 @@ static void drm_gem_object_exported_dma_buf_free(struct drm_gem_object *obj)
|
|||
}
|
||||
|
||||
/**
|
||||
* drm_gem_object_handle_put_unlocked - releases reference on user-space handles
|
||||
* drm_gem_object_handle_put_unlocked - releases reference on user-space handle
|
||||
* @obj: GEM object
|
||||
*
|
||||
* Releases a reference on the GEM buffer object's handle. Possibly releases
|
||||
|
@ -283,14 +294,14 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
|
|||
struct drm_device *dev = obj->dev;
|
||||
bool final = false;
|
||||
|
||||
if (WARN_ON(READ_ONCE(obj->handle_count) == 0))
|
||||
if (drm_WARN_ON(dev, READ_ONCE(obj->handle_count) == 0))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Must bump handle count first as this may be the last
|
||||
* ref, in which case the object would disappear before we
|
||||
* checked for a name
|
||||
*/
|
||||
* Must bump handle count first as this may be the last
|
||||
* ref, in which case the object would disappear before
|
||||
* we checked for a name.
|
||||
*/
|
||||
|
||||
mutex_lock(&dev->object_name_lock);
|
||||
if (--obj->handle_count == 0) {
|
||||
|
@ -303,7 +314,6 @@ void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj)
|
|||
if (final)
|
||||
drm_gem_object_put(obj);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_gem_object_handle_put_unlocked);
|
||||
|
||||
/*
|
||||
* Called at device or object close to release the file's
|
||||
|
@ -315,6 +325,9 @@ drm_gem_object_release_handle(int id, void *ptr, void *data)
|
|||
struct drm_file *file_priv = data;
|
||||
struct drm_gem_object *obj = ptr;
|
||||
|
||||
if (drm_WARN_ON(obj->dev, !data))
|
||||
return 0;
|
||||
|
||||
if (obj->funcs->close)
|
||||
obj->funcs->close(obj, file_priv);
|
||||
|
||||
|
@ -435,7 +448,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
|
|||
idr_preload(GFP_KERNEL);
|
||||
spin_lock(&file_priv->table_lock);
|
||||
|
||||
ret = idr_alloc(&file_priv->object_idr, obj, 1, 0, GFP_NOWAIT);
|
||||
ret = idr_alloc(&file_priv->object_idr, NULL, 1, 0, GFP_NOWAIT);
|
||||
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
idr_preload_end();
|
||||
|
@ -456,6 +469,11 @@ drm_gem_handle_create_tail(struct drm_file *file_priv,
|
|||
goto err_revoke;
|
||||
}
|
||||
|
||||
/* mirrors drm_gem_handle_delete to avoid races */
|
||||
spin_lock(&file_priv->table_lock);
|
||||
obj = idr_replace(&file_priv->object_idr, obj, handle);
|
||||
WARN_ON(obj != NULL);
|
||||
spin_unlock(&file_priv->table_lock);
|
||||
*handlep = handle;
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void drm_gem_fb_destroy(struct drm_framebuffer *fb)
|
|||
unsigned int i;
|
||||
|
||||
for (i = 0; i < fb->format->num_planes; i++)
|
||||
drm_gem_object_handle_put_unlocked(fb->obj[i]);
|
||||
drm_gem_object_put(fb->obj[i]);
|
||||
|
||||
drm_framebuffer_cleanup(fb);
|
||||
kfree(fb);
|
||||
|
@ -182,10 +182,8 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
|
|||
if (!objs[i]) {
|
||||
drm_dbg_kms(dev, "Failed to lookup GEM object\n");
|
||||
ret = -ENOENT;
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
goto err_gem_object_put;
|
||||
}
|
||||
drm_gem_object_handle_get_unlocked(objs[i]);
|
||||
drm_gem_object_put(objs[i]);
|
||||
|
||||
min_size = (height - 1) * mode_cmd->pitches[i]
|
||||
+ drm_format_info_min_pitch(info, i, width)
|
||||
|
@ -195,22 +193,22 @@ int drm_gem_fb_init_with_funcs(struct drm_device *dev,
|
|||
drm_dbg_kms(dev,
|
||||
"GEM object size (%zu) smaller than minimum size (%u) for plane %d\n",
|
||||
objs[i]->size, min_size, i);
|
||||
drm_gem_object_handle_put_unlocked(objs[i]);
|
||||
drm_gem_object_put(objs[i]);
|
||||
ret = -EINVAL;
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
goto err_gem_object_put;
|
||||
}
|
||||
}
|
||||
|
||||
ret = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
|
||||
if (ret)
|
||||
goto err_gem_object_handle_put_unlocked;
|
||||
goto err_gem_object_put;
|
||||
|
||||
return 0;
|
||||
|
||||
err_gem_object_handle_put_unlocked:
|
||||
err_gem_object_put:
|
||||
while (i > 0) {
|
||||
--i;
|
||||
drm_gem_object_handle_put_unlocked(objs[i]);
|
||||
drm_gem_object_put(objs[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -161,7 +161,7 @@ void drm_sysfs_lease_event(struct drm_device *dev);
|
|||
|
||||
/* drm_gem.c */
|
||||
int drm_gem_init(struct drm_device *dev);
|
||||
void drm_gem_object_handle_get_unlocked(struct drm_gem_object *obj);
|
||||
bool drm_gem_object_handle_get_if_exists_unlocked(struct drm_gem_object *obj);
|
||||
void drm_gem_object_handle_put_unlocked(struct drm_gem_object *obj);
|
||||
int drm_gem_handle_create_tail(struct drm_file *file_priv,
|
||||
struct drm_gem_object *obj,
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
//! * <https://github.com/erwanvivien/fast_qr>
|
||||
//! * <https://github.com/bjguillot/qr>
|
||||
|
||||
use kernel::{prelude::*, str::CStr};
|
||||
use kernel::prelude::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
|
||||
struct Version(usize);
|
||||
|
|
|
@ -1938,7 +1938,7 @@ static int get_init_otp_deassert_fragment_len(struct intel_display *display,
|
|||
int index, len;
|
||||
|
||||
if (drm_WARN_ON(display->drm,
|
||||
!data || panel->vbt.dsi.seq_version != 1))
|
||||
!data || panel->vbt.dsi.seq_version >= 3))
|
||||
return 0;
|
||||
|
||||
/* index = 1 to skip sequence byte */
|
||||
|
@ -1961,7 +1961,7 @@ static int get_init_otp_deassert_fragment_len(struct intel_display *display,
|
|||
}
|
||||
|
||||
/*
|
||||
* Some v1 VBT MIPI sequences do the deassert in the init OTP sequence.
|
||||
* Some v1/v2 VBT MIPI sequences do the deassert in the init OTP sequence.
|
||||
* The deassert must be done before calling intel_dsi_device_ready, so for
|
||||
* these devices we split the init OTP sequence into a deassert sequence and
|
||||
* the actual init OTP part.
|
||||
|
@ -1972,9 +1972,9 @@ static void vlv_fixup_mipi_sequences(struct intel_display *display,
|
|||
u8 *init_otp;
|
||||
int len;
|
||||
|
||||
/* Limit this to v1 vid-mode sequences */
|
||||
/* Limit this to v1/v2 vid-mode sequences */
|
||||
if (panel->vbt.dsi.config->is_cmd_mode ||
|
||||
panel->vbt.dsi.seq_version != 1)
|
||||
panel->vbt.dsi.seq_version >= 3)
|
||||
return;
|
||||
|
||||
/* Only do this if there are otp and assert seqs and no deassert seq */
|
||||
|
|
|
@ -386,13 +386,13 @@ pvr_power_reset(struct pvr_device *pvr_dev, bool hard_reset)
|
|||
if (!err) {
|
||||
if (hard_reset) {
|
||||
pvr_dev->fw_dev.booted = false;
|
||||
WARN_ON(pm_runtime_force_suspend(from_pvr_device(pvr_dev)->dev));
|
||||
WARN_ON(pvr_power_device_suspend(from_pvr_device(pvr_dev)->dev));
|
||||
|
||||
err = pvr_fw_hard_reset(pvr_dev);
|
||||
if (err)
|
||||
goto err_device_lost;
|
||||
|
||||
err = pm_runtime_force_resume(from_pvr_device(pvr_dev)->dev);
|
||||
err = pvr_power_device_resume(from_pvr_device(pvr_dev)->dev);
|
||||
pvr_dev->fw_dev.booted = true;
|
||||
if (err)
|
||||
goto err_device_lost;
|
||||
|
|
|
@ -314,14 +314,10 @@ nouveau_debugfs_fini(struct nouveau_drm *drm)
|
|||
drm->debugfs = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
nouveau_module_debugfs_init(void)
|
||||
{
|
||||
nouveau_debugfs_root = debugfs_create_dir("nouveau", NULL);
|
||||
if (IS_ERR(nouveau_debugfs_root))
|
||||
return PTR_ERR(nouveau_debugfs_root);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -24,7 +24,7 @@ extern void nouveau_debugfs_fini(struct nouveau_drm *);
|
|||
|
||||
extern struct dentry *nouveau_debugfs_root;
|
||||
|
||||
int nouveau_module_debugfs_init(void);
|
||||
void nouveau_module_debugfs_init(void);
|
||||
void nouveau_module_debugfs_fini(void);
|
||||
#else
|
||||
static inline void
|
||||
|
@ -42,10 +42,9 @@ nouveau_debugfs_fini(struct nouveau_drm *drm)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int
|
||||
static inline void
|
||||
nouveau_module_debugfs_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
@ -1461,9 +1461,7 @@ nouveau_drm_init(void)
|
|||
if (!nouveau_modeset)
|
||||
return 0;
|
||||
|
||||
ret = nouveau_module_debugfs_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
nouveau_module_debugfs_init();
|
||||
|
||||
#ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER
|
||||
platform_driver_register(&nouveau_platform_driver);
|
||||
|
|
|
@ -719,7 +719,6 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
|
|||
union acpi_object argv4 = {
|
||||
.buffer.type = ACPI_TYPE_BUFFER,
|
||||
.buffer.length = 4,
|
||||
.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL),
|
||||
}, *obj;
|
||||
|
||||
caps->status = 0xffff;
|
||||
|
@ -727,17 +726,22 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
|
|||
if (!acpi_check_dsm(handle, &NVOP_DSM_GUID, NVOP_DSM_REV, BIT_ULL(0x1a)))
|
||||
return;
|
||||
|
||||
argv4.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL);
|
||||
if (!argv4.buffer.pointer)
|
||||
return;
|
||||
|
||||
obj = acpi_evaluate_dsm(handle, &NVOP_DSM_GUID, NVOP_DSM_REV, 0x1a, &argv4);
|
||||
if (!obj)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
return;
|
||||
goto done;
|
||||
|
||||
caps->status = 0;
|
||||
caps->optimusCaps = *(u32 *)obj->buffer.pointer;
|
||||
|
||||
done:
|
||||
ACPI_FREE(obj);
|
||||
|
||||
kfree(argv4.buffer.pointer);
|
||||
|
@ -754,24 +758,28 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt)
|
|||
union acpi_object argv4 = {
|
||||
.buffer.type = ACPI_TYPE_BUFFER,
|
||||
.buffer.length = sizeof(caps),
|
||||
.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL),
|
||||
}, *obj;
|
||||
|
||||
jt->status = 0xffff;
|
||||
|
||||
argv4.buffer.pointer = kmalloc(argv4.buffer.length, GFP_KERNEL);
|
||||
if (!argv4.buffer.pointer)
|
||||
return;
|
||||
|
||||
obj = acpi_evaluate_dsm(handle, &JT_DSM_GUID, JT_DSM_REV, 0x1, &argv4);
|
||||
if (!obj)
|
||||
return;
|
||||
goto done;
|
||||
|
||||
if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
WARN_ON(obj->buffer.length != 4))
|
||||
return;
|
||||
goto done;
|
||||
|
||||
jt->status = 0;
|
||||
jt->jtCaps = *(u32 *)obj->buffer.pointer;
|
||||
jt->jtRevId = (jt->jtCaps & 0xfff00000) >> 20;
|
||||
jt->bSBIOSCaps = 0;
|
||||
|
||||
done:
|
||||
ACPI_FREE(obj);
|
||||
|
||||
kfree(argv4.buffer.pointer);
|
||||
|
@ -1744,6 +1752,13 @@ r535_gsp_fini(struct nvkm_gsp *gsp, bool suspend)
|
|||
nvkm_gsp_sg_free(gsp->subdev.device, &gsp->sr.sgt);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Debug the GSP firmware / RPC handling to find out why
|
||||
* without this Turing (but none of the other architectures)
|
||||
* ends up resetting all channels after resume.
|
||||
*/
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
ret = r535_gsp_rpc_unloading_guest_driver(gsp, suspend);
|
||||
|
|
|
@ -261,10 +261,8 @@ static int nvdec_load_falcon_firmware(struct nvdec *nvdec)
|
|||
|
||||
if (!client->group) {
|
||||
virt = dma_alloc_coherent(nvdec->dev, size, &iova, GFP_KERNEL);
|
||||
|
||||
err = dma_mapping_error(nvdec->dev, iova);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (!virt)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
virt = tegra_drm_alloc(tegra, size, &iova);
|
||||
if (IS_ERR(virt))
|
||||
|
|
|
@ -171,14 +171,32 @@ static void xe_devcoredump_snapshot_free(struct xe_devcoredump_snapshot *ss)
|
|||
|
||||
#define XE_DEVCOREDUMP_CHUNK_MAX (SZ_512M + SZ_1G)
|
||||
|
||||
/**
|
||||
* xe_devcoredump_read() - Read data from the Xe device coredump snapshot
|
||||
* @buffer: Destination buffer to copy the coredump data into
|
||||
* @offset: Offset in the coredump data to start reading from
|
||||
* @count: Number of bytes to read
|
||||
* @data: Pointer to the xe_devcoredump structure
|
||||
* @datalen: Length of the data (unused)
|
||||
*
|
||||
* Reads a chunk of the coredump snapshot data into the provided buffer.
|
||||
* If the devcoredump is smaller than 1.5 GB (XE_DEVCOREDUMP_CHUNK_MAX),
|
||||
* it is read directly from a pre-written buffer. For larger devcoredumps,
|
||||
* the pre-written buffer must be periodically repopulated from the snapshot
|
||||
* state due to kmalloc size limitations.
|
||||
*
|
||||
* Return: Number of bytes copied on success, or a negative error code on failure.
|
||||
*/
|
||||
static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
||||
size_t count, void *data, size_t datalen)
|
||||
{
|
||||
struct xe_devcoredump *coredump = data;
|
||||
struct xe_devcoredump_snapshot *ss;
|
||||
ssize_t byte_copied;
|
||||
ssize_t byte_copied = 0;
|
||||
u32 chunk_offset;
|
||||
ssize_t new_chunk_position;
|
||||
bool pm_needed = false;
|
||||
int ret = 0;
|
||||
|
||||
if (!coredump)
|
||||
return -ENODEV;
|
||||
|
@ -188,20 +206,19 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
|||
/* Ensure delayed work is captured before continuing */
|
||||
flush_work(&ss->work);
|
||||
|
||||
if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
|
||||
pm_needed = ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX;
|
||||
if (pm_needed)
|
||||
xe_pm_runtime_get(gt_to_xe(ss->gt));
|
||||
|
||||
mutex_lock(&coredump->lock);
|
||||
|
||||
if (!ss->read.buffer) {
|
||||
mutex_unlock(&coredump->lock);
|
||||
return -ENODEV;
|
||||
ret = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (offset >= ss->read.size) {
|
||||
mutex_unlock(&coredump->lock);
|
||||
return 0;
|
||||
}
|
||||
if (offset >= ss->read.size)
|
||||
goto unlock;
|
||||
|
||||
new_chunk_position = div_u64_rem(offset,
|
||||
XE_DEVCOREDUMP_CHUNK_MAX,
|
||||
|
@ -221,12 +238,13 @@ static ssize_t xe_devcoredump_read(char *buffer, loff_t offset,
|
|||
ss->read.size - offset;
|
||||
memcpy(buffer, ss->read.buffer + chunk_offset, byte_copied);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&coredump->lock);
|
||||
|
||||
if (ss->read.size > XE_DEVCOREDUMP_CHUNK_MAX)
|
||||
if (pm_needed)
|
||||
xe_pm_runtime_put(gt_to_xe(ss->gt));
|
||||
|
||||
return byte_copied;
|
||||
return byte_copied ? byte_copied : ret;
|
||||
}
|
||||
|
||||
static void xe_devcoredump_free(void *data)
|
||||
|
|
|
@ -444,6 +444,7 @@ static int xe_alloc_pf_queue(struct xe_gt *gt, struct pf_queue *pf_queue)
|
|||
#define PF_MULTIPLIER 8
|
||||
pf_queue->num_dw =
|
||||
(num_eus + XE_NUM_HW_ENGINES) * PF_MSG_LEN_DW * PF_MULTIPLIER;
|
||||
pf_queue->num_dw = roundup_pow_of_two(pf_queue->num_dw);
|
||||
#undef PF_MULTIPLIER
|
||||
|
||||
pf_queue->gt = gt;
|
||||
|
|
|
@ -78,6 +78,9 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level
|
|||
}
|
||||
|
||||
lmtt_assert(lmtt, xe_bo_is_vram(bo));
|
||||
lmtt_debug(lmtt, "level=%u addr=%#llx\n", level, (u64)xe_bo_main_addr(bo, XE_PAGE_SIZE));
|
||||
|
||||
xe_map_memset(lmtt_to_xe(lmtt), &bo->vmap, 0, 0, bo->size);
|
||||
|
||||
pt->level = level;
|
||||
pt->bo = bo;
|
||||
|
@ -91,6 +94,9 @@ out:
|
|||
|
||||
static void lmtt_pt_free(struct xe_lmtt_pt *pt)
|
||||
{
|
||||
lmtt_debug(&pt->bo->tile->sriov.pf.lmtt, "level=%u addr=%llx\n",
|
||||
pt->level, (u64)xe_bo_main_addr(pt->bo, XE_PAGE_SIZE));
|
||||
|
||||
xe_bo_unpin_map_no_vm(pt->bo);
|
||||
kfree(pt);
|
||||
}
|
||||
|
@ -226,9 +232,14 @@ static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt,
|
|||
|
||||
switch (lmtt->ops->lmtt_pte_size(level)) {
|
||||
case sizeof(u32):
|
||||
lmtt_assert(lmtt, !overflows_type(pte, u32));
|
||||
lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u32), u32));
|
||||
|
||||
xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u32), u32, pte);
|
||||
break;
|
||||
case sizeof(u64):
|
||||
lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u64), u64));
|
||||
|
||||
xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u64), u64, pte);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -863,7 +863,7 @@ struct dma_fence *xe_migrate_copy(struct xe_migrate *m,
|
|||
if (src_is_vram && xe_migrate_allow_identity(src_L0, &src_it))
|
||||
xe_res_next(&src_it, src_L0);
|
||||
else
|
||||
emit_pte(m, bb, src_L0_pt, src_is_vram, copy_system_ccs,
|
||||
emit_pte(m, bb, src_L0_pt, src_is_vram, copy_system_ccs || use_comp_pat,
|
||||
&src_it, src_L0, src);
|
||||
|
||||
if (dst_is_vram && xe_migrate_allow_identity(src_L0, &dst_it))
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
struct xe_modparam xe_modparam = {
|
||||
.probe_display = true,
|
||||
.guc_log_level = 3,
|
||||
.guc_log_level = IS_ENABLED(CONFIG_DRM_XE_DEBUG) ? 3 : 1,
|
||||
.force_probe = CONFIG_DRM_XE_FORCE_PROBE,
|
||||
.wedged_mode = 1,
|
||||
.svm_notifier_size = 512,
|
||||
|
|
|
@ -140,7 +140,6 @@ static const struct xe_graphics_desc graphics_xelpg = {
|
|||
.has_asid = 1, \
|
||||
.has_atomic_enable_pte_bit = 1, \
|
||||
.has_flat_ccs = 1, \
|
||||
.has_indirect_ring_state = 1, \
|
||||
.has_range_tlb_invalidation = 1, \
|
||||
.has_usm = 1, \
|
||||
.has_64bit_timestamp = 1, \
|
||||
|
|
|
@ -134,7 +134,7 @@ int xe_pm_suspend(struct xe_device *xe)
|
|||
/* FIXME: Super racey... */
|
||||
err = xe_bo_evict_all(xe);
|
||||
if (err)
|
||||
goto err_pxp;
|
||||
goto err_display;
|
||||
|
||||
for_each_gt(gt, xe, id) {
|
||||
err = xe_gt_suspend(gt);
|
||||
|
@ -151,7 +151,6 @@ int xe_pm_suspend(struct xe_device *xe)
|
|||
|
||||
err_display:
|
||||
xe_display_pm_resume(xe);
|
||||
err_pxp:
|
||||
xe_pxp_pm_resume(xe->pxp);
|
||||
err:
|
||||
drm_dbg(&xe->drm, "Device suspend failed %d\n", err);
|
||||
|
@ -753,11 +752,13 @@ void xe_pm_assert_unbounded_bridge(struct xe_device *xe)
|
|||
}
|
||||
|
||||
/**
|
||||
* xe_pm_set_vram_threshold - Set a vram threshold for allowing/blocking D3Cold
|
||||
* xe_pm_set_vram_threshold - Set a VRAM threshold for allowing/blocking D3Cold
|
||||
* @xe: xe device instance
|
||||
* @threshold: VRAM size in bites for the D3cold threshold
|
||||
* @threshold: VRAM size in MiB for the D3cold threshold
|
||||
*
|
||||
* Returns 0 for success, negative error code otherwise.
|
||||
* Return:
|
||||
* * 0 - success
|
||||
* * -EINVAL - invalid argument
|
||||
*/
|
||||
int xe_pm_set_vram_threshold(struct xe_device *xe, u32 threshold)
|
||||
{
|
||||
|
|
|
@ -114,10 +114,10 @@ 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(BATTLEMAGE, GT_TYPE_ANY, major_ver(xe, guc, bmg, 70, 44, 1)) \
|
||||
fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, guc, lnl, 70, 44, 1)) \
|
||||
fw_def(BATTLEMAGE, GT_TYPE_ANY, major_ver(xe, guc, bmg, 70, 45, 2)) \
|
||||
fw_def(LUNARLAKE, GT_TYPE_ANY, major_ver(xe, guc, lnl, 70, 45, 2)) \
|
||||
fw_def(METEORLAKE, GT_TYPE_ANY, major_ver(i915, guc, mtl, 70, 44, 1)) \
|
||||
fw_def(DG2, GT_TYPE_ANY, major_ver(i915, guc, dg2, 70, 44, 1)) \
|
||||
fw_def(DG2, GT_TYPE_ANY, major_ver(i915, guc, dg2, 70, 45, 2)) \
|
||||
fw_def(DG1, GT_TYPE_ANY, major_ver(i915, guc, dg1, 70, 44, 1)) \
|
||||
fw_def(ALDERLAKE_N, GT_TYPE_ANY, major_ver(i915, guc, tgl, 70, 44, 1)) \
|
||||
fw_def(ALDERLAKE_P, GT_TYPE_ANY, major_ver(i915, guc, adlp, 70, 44, 1)) \
|
||||
|
|
|
@ -38,10 +38,10 @@
|
|||
GRAPHICS_VERSION(2004)
|
||||
GRAPHICS_VERSION_RANGE(3000, 3001)
|
||||
22019338487 MEDIA_VERSION(2000)
|
||||
GRAPHICS_VERSION(2001)
|
||||
GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
MEDIA_VERSION(3000), MEDIA_STEP(A0, B0), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
22019338487_display PLATFORM(LUNARLAKE)
|
||||
16023588340 GRAPHICS_VERSION(2001)
|
||||
16023588340 GRAPHICS_VERSION(2001), FUNC(xe_rtp_match_not_sriov_vf)
|
||||
14019789679 GRAPHICS_VERSION(1255)
|
||||
GRAPHICS_VERSION_RANGE(1270, 2004)
|
||||
no_media_l3 MEDIA_VERSION(3000)
|
||||
|
|
|
@ -300,6 +300,9 @@ struct drm_file {
|
|||
*
|
||||
* Mapping of mm object handles to object pointers. Used by the GEM
|
||||
* subsystem. Protected by @table_lock.
|
||||
*
|
||||
* Note that allocated entries might be NULL as a transient state when
|
||||
* creating or deleting a handle.
|
||||
*/
|
||||
struct idr object_idr;
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef __DRM_FRAMEBUFFER_H__
|
||||
#define __DRM_FRAMEBUFFER_H__
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/sched.h>
|
||||
|
@ -100,6 +101,8 @@ struct drm_framebuffer_funcs {
|
|||
unsigned num_clips);
|
||||
};
|
||||
|
||||
#define DRM_FRAMEBUFFER_HAS_HANDLE_REF(_i) BIT(0u + (_i))
|
||||
|
||||
/**
|
||||
* struct drm_framebuffer - frame buffer object
|
||||
*
|
||||
|
@ -188,6 +191,10 @@ struct drm_framebuffer {
|
|||
* DRM_MODE_FB_MODIFIERS.
|
||||
*/
|
||||
int flags;
|
||||
/**
|
||||
* @internal_flags: Framebuffer flags like DRM_FRAMEBUFFER_HAS_HANDLE_REF.
|
||||
*/
|
||||
unsigned int internal_flags;
|
||||
/**
|
||||
* @filp_head: Placed on &drm_file.fbs, protected by &drm_file.fbs_lock.
|
||||
*/
|
||||
|
|
|
@ -66,7 +66,7 @@ impl<T: drm::Driver> Device<T> {
|
|||
open: Some(drm::File::<T::File>::open_callback),
|
||||
postclose: Some(drm::File::<T::File>::postclose_callback),
|
||||
unload: None,
|
||||
release: None,
|
||||
release: Some(Self::release),
|
||||
master_set: None,
|
||||
master_drop: None,
|
||||
debugfs_init: None,
|
||||
|
@ -162,6 +162,16 @@ impl<T: drm::Driver> Device<T> {
|
|||
// SAFETY: `ptr` is valid by the safety requirements of this function.
|
||||
unsafe { &*ptr.cast() }
|
||||
}
|
||||
|
||||
extern "C" fn release(ptr: *mut bindings::drm_device) {
|
||||
// SAFETY: `ptr` is a valid pointer to a `struct drm_device` and embedded in `Self`.
|
||||
let this = unsafe { Self::from_drm_device(ptr) };
|
||||
|
||||
// SAFETY:
|
||||
// - When `release` runs it is guaranteed that there is no further access to `this`.
|
||||
// - `this` is valid for dropping.
|
||||
unsafe { core::ptr::drop_in_place(this) };
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: drm::Driver> Deref for Device<T> {
|
||||
|
|
|
@ -10,7 +10,6 @@ use crate::{
|
|||
drm,
|
||||
error::{to_result, Result},
|
||||
prelude::*,
|
||||
str::CStr,
|
||||
types::ARef,
|
||||
};
|
||||
use macros::vtable;
|
||||
|
|
Loading…
Reference in New Issue
Block a user