projects/linux·commit bb934c29

Merge tag 'drm-fixes-2026-10-11' of https://gitlab.freedesktop.org/drm/kernel

bb934c29 · Linus Torvalds <[email protected]> · 2026-10-10 16:50:50 -07:00

Pull drm fixes from Dave Ailie:
 "Live from Dublin Airport, it's Saturday Night drm fixes.

  This week has the missing misc fixes from last week which I tracked
  down and seemed to be a race/bug in my lei setup somehow, once I asked
  lei to ignore it's cache I got the missing email. But there are more
  misc fixes this week and amd and intel ones.

  The main ones in this are amdgpu and xe, with vc4, vmwgfx, nouveau and
  imagination in the middle, with a bunch of small single fixes.

  Bit busier than I'd like, but the missing misc might explain it,
  anyways time for me to fly home.

  fb:
   - defer setup when fbdev_probe() fails, not just on -EAGAIN

  bridge:
   - Fix unlocked list_del in drm_bridge_add()
   - Fix unlocked list access in drm_bridge_attach()
   - th1520-dw-hdmi:
       - Fix error check on dw_hdmi_probe() return value
       - Fix remove() callback

  aspeed:
   - Balance the display clock enable on teardown

  i915:
   - Fix a GT park race that could trigger spurious RPM wakelock
     warnings
   - Fix execbuffer relocation cleanup to avoid out-of-bounds free

  xe:
   - i2c removal
   - system Controller Maibox header handling
   - two bo pin/unpin accounting bugs
   - not emitting a w/a twice
   - xe_mmio_wait32() to honor delay/sleep maximums

  amdgpu:
   - Fix direct scanout alpha on some DRM_FORMATs
   - UserQ fixes
   - Fix tearing flips with PSR
   - GPU reset vblank fix
   - Debugfs register interface fix
   - Fix display mode patching
   - Expand Mac reserved memory workaround

  amdkfd:
   - SDMA doorbell fix
   - Fix dma-buf reference leak in error path

  imagination:
   - fix reference and vm_bo handling in remap()
   - size page table preallocation by device address

  gud:
   - don't keep a connector without a CRTC as connector_state

  panthor:
   - validate userspace queue count against initialized firmware
     slot count

  nouveau:
   - fix null ptr regression
   - skip turing CE workaround for non-GR

  vmwgfx:
   - validate pitch value
   - add blend mode property

  vc4:
   - drain hangcheck timer on unbind
   - free BO cache on teardown
   - use kvmalloc_objs for bo cache size list
   - disable V3D interrupt across runtime suspend
   - fix binner slot allocation
   - fix fw refcount leak"

* tag 'drm-fixes-2026-10-11' of https://gitlab.freedesktop.org/drm/kernel: (39 commits)
  drm/nouveau: Skip the Turing CE workaround object for non-GR channels
  drm/vc4: Fix binner slot allocation failing on an idle GPU
  drm/vc4: Disable the V3D interrupt across runtime suspend
  drm/imagination: Size page table preallocation by device address
  drm/imagination: Fix reference and vm_bo handling in remap()
  drm/amdgpu: make Mac FB workaround generic
  drm/amdkfd: fix dma_buf reference leak in get_dmabuf_info
  drm/amd/display: Don't replace a sink mode that shares the native totals
  drm/amdkfd: align SDMA doorbell base for shader doorbell writes
  drm/amdgpu: copy debugfs register data outside the GRBM/SRBM locks
  drm/amdgpu: serialize vblank counter reads against GPU reset
  drm/amd/display: disable self-refresh on tearing flips
  drm/amdgpu/userq: return the memdup_user() error for the user MQD
  drm/amdgpu/userq: only accept doorbell BOs as queue doorbell
  drm/amd/display: Fix direct scanout alpha on some DRM_FORMATs
  drm/xe/i2c: cancel the client work on remove
  drm/xe/sysctrl: Fix mailbox header handling
  drm/i915/gt: Unmask interrupts only when ACTIVE is true
  drm/i915/gem: Prevent overstepping exec array boundary
  drm/gud: don't keep a connector without a CRTC as connector_state
  ...
Commit
bb934c29fda8dcd409145a0deddc1a8095fec930
Parents
b62f58bd · c61e23ed

Merge commit. Changes below are compared with the first parent: b62f58bd.

Changes

41 files changed · +461 −228

FileStatusAddDelContent
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.cmodified+6−2View file
drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.cmodified+46−31View file
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.cmodified+7−10View file
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.cmodified+5−0View file
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.cmodified+12−1View file
drivers/gpu/drm/amd/amdgpu/mes_userqueue.cmodified+3−6View file
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.cmodified+26−6View file
drivers/gpu/drm/amd/amdkfd/kfd_priv.hmodified+7−0View file
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.cmodified+19−0View file
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.cmodified+6−1View file
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.cmodified+1−19View file
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.cmodified+42−0View file
drivers/gpu/drm/aspeed/aspeed_gfx_drv.cmodified+2−3View file
drivers/gpu/drm/bridge/th1520-dw-hdmi.cmodified+4−4View file
drivers/gpu/drm/display/drm_dp_helper.cmodified+3−1View file
drivers/gpu/drm/drm_bridge.cmodified+6−2View file
drivers/gpu/drm/drm_fb_helper.cmodified+3−3View file
drivers/gpu/drm/gud/gud_pipe.cmodified+1−0View file
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.cmodified+1−1View file
drivers/gpu/drm/i915/gt/intel_rps.cmodified+2−1View file
drivers/gpu/drm/imagination/pvr_mmu.cmodified+12−13View file
drivers/gpu/drm/imagination/pvr_vm.cmodified+4−4View file
drivers/gpu/drm/nouveau/nouveau_abi16.cmodified+1−1View file
drivers/gpu/drm/nouveau/nvkm/engine/device/user.cmodified+1−1View file
drivers/gpu/drm/panthor/panthor_sched.cmodified+3−0View file
drivers/gpu/drm/vc4/vc4_bo.cmodified+3−2View file
drivers/gpu/drm/vc4/vc4_drv.cmodified+4−1View file
drivers/gpu/drm/vc4/vc4_drv.hmodified+1−1View file
drivers/gpu/drm/vc4/vc4_gem.cmodified+7−1View file
drivers/gpu/drm/vc4/vc4_irq.cmodified+8−16View file
drivers/gpu/drm/vc4/vc4_v3d.cmodified+35−30View file
drivers/gpu/drm/vc4/vc4_validate.cmodified+1−1View file
drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.cmodified+21−5View file
drivers/gpu/drm/vmwgfx/vmwgfx_kms.cmodified+8−0View file
drivers/gpu/drm/xe/display/xe_fb_pin.cmodified+3−3View file
drivers/gpu/drm/xe/xe_bo.cmodified+105−34View file
drivers/gpu/drm/xe/xe_bo.hmodified+2−0View file
drivers/gpu/drm/xe/xe_i2c.cmodified+4−1View file
drivers/gpu/drm/xe/xe_lrc.cmodified+25−13View file
drivers/gpu/drm/xe/xe_mmio.cmodified+3−2View file
drivers/gpu/drm/xe/xe_sysctrl_mailbox.cmodified+8−8View file

Only the first 600 diff lines are shown. Download the complete patch.

drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c

View file
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
index 054870e..ca5860e 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c
@@ -598,14 +598,18 @@ int amdgpu_amdkfd_get_dmabuf_info(struct amdgpu_device *adev, int dma_buf_fd,
/* first get metadata_size by buffer = NULL */
r = amdgpu_bo_get_metadata(bo, NULL, 0,
metadata_size, NULL);
+ if (r)
+ goto out_put;
/* user buf_size is bigger than bo metadata_size
* allocate a buf at kernel space and copy */
if (*metadata_size <= buffer_size) {
*metadata_buffer = kzalloc(*metadata_size, GFP_KERNEL);
- if (!*metadata_buffer)
- return -ENOMEM;
+ if (!*metadata_buffer) {
+ r = -ENOMEM;
+ goto out_put;
+ }
r = amdgpu_bo_get_metadata(bo, *metadata_buffer, *metadata_size,
NULL, &metadata_flags);

drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c

View file
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
index aca1a80..ab7ccfa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c
@@ -121,6 +121,20 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
*pos &= (1UL << 22) - 1;
+ if (size > PAGE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Access the user buffer only while none of the locks below are held:
+ * a fault takes mmap_lock, and grbm_idx_mutex and srbm_mutex nest
+ * inside it.
+ */
+ u32 *data __free(kfree) = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ if (!read && copy_from_user(data, buf, size))
+ return -EFAULT;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -152,28 +166,16 @@ static int amdgpu_debugfs_process_reg_op(bool read, struct file *f,
mutex_lock(&adev->pm.mutex);
while (size) {
- uint32_t value;
-
- if (read) {
- value = RREG32(*pos >> 2);
- r = put_user(value, (uint32_t *)buf);
- } else {
- r = get_user(value, (uint32_t *)buf);
- if (!r)
- amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, value, 0);
- }
- if (r) {
- result = r;
- goto end;
- }
+ if (read)
+ data[result >> 2] = RREG32(*pos >> 2);
+ else
+ amdgpu_mm_wreg_mmio_rlc(adev, *pos >> 2, data[result >> 2], 0);
result += 4;
- buf += 4;
*pos += 4;
size -= 4;
}
-end:
if (use_bank) {
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, 0);
mutex_unlock(&adev->grbm_idx_mutex);
@@ -188,6 +190,10 @@ end:
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
amdgpu_virt_disable_access_debugfs(adev);
+
+ if (read && copy_to_user(buf, data, result))
+ return -EFAULT;
+
return result;
}
@@ -238,11 +244,24 @@ static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 off
struct amdgpu_device *adev = rd->adev;
ssize_t result = 0;
int r;
- uint32_t value;
if (size & 0x3 || offset & 0x3)
return -EINVAL;
+ if (size > PAGE_SIZE)
+ return -EINVAL;
+
+ /*
+ * Access the user buffer only while none of the locks below are held:
+ * a fault takes mmap_lock, and grbm_idx_mutex and srbm_mutex nest
+ * inside it.
+ */
+ u32 *data __free(kfree) = kmalloc(size, GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+ if (write_en && copy_from_user(data, buf, size))
+ return -EFAULT;
+
r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
if (r < 0) {
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
@@ -281,24 +300,16 @@ static ssize_t amdgpu_debugfs_regs2_op(struct file *f, char __user *buf, u32 off
mutex_lock(&adev->pm.mutex);
while (size) {
- if (!write_en) {
- value = RREG32(offset >> 2);
- r = put_user(value, (uint32_t *)buf);
- } else {
- r = get_user(value, (uint32_t *)buf);
- if (!r)
- amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, value, rd->id.xcc_id);
- }
- if (r) {
- result = r;
- goto end;
- }
+ if (!write_en)
+ data[result >> 2] = RREG32(offset >> 2);
+ else
+ amdgpu_mm_wreg_mmio_rlc(adev, offset >> 2, data[result >> 2],
+ rd->id.xcc_id);
offset += 4;
size -= 4;
result += 4;
- buf += 4;
}
-end:
+
if (rd->id.use_grbm) {
amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff, rd->id.xcc_id);
mutex_unlock(&adev->grbm_idx_mutex);
@@ -317,6 +328,10 @@ end:
pm_runtime_put_autosuspend(adev_to_drm(adev)->dev);
amdgpu_virt_disable_access_debugfs(adev);
+
+ if (!write_en && copy_to_user(buf, data, result))
+ return -EFAULT;
+
return result;
}

drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c

View file
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
index 3dc8faa..61dc2a6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c
@@ -1080,20 +1080,17 @@ void amdgpu_gmc_init_vga_resv_regions(struct amdgpu_device *adev)
case CHIP_RENOIR:
adev->mman.keep_stolen_vga_memory = true;
break;
- case CHIP_POLARIS10:
- case CHIP_POLARIS11:
- case CHIP_POLARIS12:
- /* MacBookPros with switchable graphics put VRAM at 0 when
- * the iGPU is enabled which results in cursor issues if
- * the cursor ends up at 0. Reserve vram at 0 in that case.
- */
- if (adev->gmc.vram_start == 0)
- adev->mman.keep_stolen_vga_memory = true;
- break;
default:
adev->mman.keep_stolen_vga_memory = false;
break;
}
+ /* MacBookPros with switchable graphics put VRAM at 0 when
+ * the iGPU is enabled which results in cursor issues if
+ * the cursor ends up at 0. Reserve vram at 0 in that case.
+ */
+ if ((adev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
+ (adev->gmc.vram_start == 0))
+ adev->mman.keep_stolen_vga_memory = true;
if (amdgpu_sriov_vf(adev) ||
!amdgpu_device_has_display_hardware(adev)) {

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

View file
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 242c48e..7c081b3 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -30,6 +30,7 @@
#include <drm/amdgpu_drm.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
+#include <drm/drm_vblank.h>
#include "amdgpu_uvd.h"
#include "amdgpu_vce.h"
#include "atom.h"
@@ -1660,6 +1661,9 @@ u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc)
DRM_ERROR("Invalid crtc %u\n", pipe);
return -EINVAL;
}
+ if (!down_read_trylock(&adev->reset_domain->sem))
+ return drm_crtc_vblank_count(crtc);
+
/* The hw increments its frame counter at start of vsync, not at start
* of vblank, as is required by DRM core vblank counter handling.
@@ -1705,6 +1709,7 @@ u32 amdgpu_get_vblank_counter_kms(struct drm_crtc *crtc)
DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
}
+ up_read(&adev->reset_domain->sem);
return count;
}

drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c

View file
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index cc8e7af..9316423 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -472,6 +472,7 @@ amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr,
u64 doorbell_index;
struct drm_gem_object *gobj;
struct amdgpu_userq_obj *db_obj = db_info->db_obj;
+ struct amdgpu_bo *abo;
int r, db_size;
gobj = drm_gem_object_lookup(filp, db_info->doorbell_handle);
@@ -480,7 +481,17 @@ amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr,
return -EINVAL;
}
- db_obj->obj = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj));
+ /*
+ * Pinning a regular BO into the doorbell domain would discard its
+ * contents, possibly those of a buffer shared by another client.
+ */
+ abo = gem_to_amdgpu_bo(gobj);
+ if (!(abo->preferred_domains & AMDGPU_GEM_DOMAIN_DOORBELL)) {
+ drm_gem_object_put(gobj);
+ return -EINVAL;
+ }
+
+ db_obj->obj = amdgpu_bo_ref(abo);
drm_gem_object_put(gobj);
r = amdgpu_bo_reserve(db_obj->obj, true);

drivers/gpu/drm/amd/amdgpu/mes_userqueue.c

View file
diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
index 14a5abe..8d5dcaf 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c
@@ -361,8 +361,7 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
compute_mqd = memdup_user(u64_to_user_ptr(mqd_user->mqd), mqd_user->mqd_size);
if (IS_ERR(compute_mqd)) {
- DRM_ERROR("Failed to read user MQD\n");
- r = -ENOMEM;
+ r = PTR_ERR(compute_mqd);
goto free_mqd;
}
@@ -406,8 +405,7 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
mqd_gfx_v11 = memdup_user(u64_to_user_ptr(mqd_user->mqd), mqd_user->mqd_size);
if (IS_ERR(mqd_gfx_v11)) {
- DRM_ERROR("Failed to read user MQD\n");
- r = -ENOMEM;
+ r = PTR_ERR(mqd_gfx_v11);
goto free_mqd;
}
@@ -451,8 +449,7 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue,
mqd_sdma_v11 = memdup_user(u64_to_user_ptr(mqd_user->mqd), mqd_user->mqd_size);
if (IS_ERR(mqd_sdma_v11)) {
- DRM_ERROR("Failed to read sdma user MQD\n");
- r = -ENOMEM;
+ r = PTR_ERR(mqd_sdma_v11);
goto free_mqd;
}

drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c

View file
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
index 2f78395..4594824 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -572,12 +572,32 @@ static int allocate_doorbell(struct qcm_process_device *qpd,
* we need the physical sdma engine id in order to get the
* correct doorbell offset.
*/
- uint32_t valid_id = idx_offset[qpd->dqm->dev->node_id *
- get_num_all_sdma_engines(qpd->dqm) +
- q->properties.sdma_engine_id]
- + (q->properties.sdma_queue_id & 1)
- * KFD_QUEUE_DOORBELL_MIRROR_OFFSET
- + (q->properties.sdma_queue_id >> 1);
+ u32 engine_base = idx_offset[dev->node_id *
+ get_num_all_sdma_engines(qpd->dqm) +
+ q->properties.sdma_engine_id];
+ u32 valid_id;
+
+ /*
+ * With the aqua_vanjaram doorbell layout, a shader doorbell
+ * write whose 32-byte block starts in the previous engine's
+ * range rings that engine instead. Engine ranges are 10
+ * indices apart (sdma_doorbell_range = 20 dwords, halved for
+ * 8-byte doorbells, in aqua_vanjaram_doorbell_index_init()),
+ * which puts odd engines 2 indices into a shared block.
+ * Aligning costs at most 2 indices, and 8 queues per engine use
+ * only 4 of the 10, so the aligned base stays in range. The
+ * 512-index mirror offset keeps the alignment.
+ */
+ if (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 3) ||
+ KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 4) ||
+ KFD_GC_VERSION(dev) == IP_VERSION(9, 5, 0))
+ engine_base = ALIGN(engine_base,
+ KFD_SDMA_SHADER_DOORBELL_GRANULARITY);
+
+ valid_id = engine_base +
+ (q->properties.sdma_queue_id & 1) *
+ KFD_QUEUE_DOORBELL_MIRROR_OFFSET +
+ (q->properties.sdma_queue_id >> 1);
if (restore_id && *restore_id != valid_id)
return -EINVAL;

drivers/gpu/drm/amd/amdkfd/kfd_priv.h

View file
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index d863184..435bf26 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -133,6 +133,13 @@
*/
#define KFD_QUEUE_DOORBELL_MIRROR_OFFSET 512
+/*
+ * On GC 9.4.3, 9.4.4 and 9.5.0, doorbell writes issued from shaders are
+ * routed to an SDMA engine at 32-byte granularity, i.e. 4 indices with the
+ * 8-byte SDMA doorbells used on SOC15.
+ */
+#define KFD_SDMA_SHADER_DOORBELL_GRANULARITY 4
+
/**
* enum kfd_ioctl_flags - KFD ioctl flags
* Various flags that can be set in &amdkfd_ioctl_desc.flags to control how

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

View file
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 1b42c46..47a0ff2 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3708,6 +3708,13 @@ static void amdgpu_dm_enable_self_refresh(struct amdgpu_display_manager *dm,
struct amdgpu_dm_connector *aconn =
(struct amdgpu_dm_connector *)acrtc_state->stream->dm_stream_context;
+ if (!acrtc_state->base.async_flip) {
+ amdgpu_dm_psr_set_event(dm, acrtc_state->stream, false,
+ psr_event_immediate_flip, false);
+ amdgpu_dm_replay_set_event(dm, acrtc_state->stream, false,
+ replay_event_immediate_flip, false);
+ }
+
/* Decrement skip count when SR is enabled and we're doing fast updates. */
if (acrtc_state->update_type == UPDATE_TYPE_FAST &&
(psr->psr_feature_enabled || pr->replay_feature_enabled)) {
@@ -4118,6 +4125,18 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
spin_unlock_irqrestore(&pcrtc->dev->event_lock, flags);
}
mutex_lock(&dm->dc_lock);
+ /*
+ * Tearing (immediate) flips cannot work with panel self-refresh
+ * features. The event is cleared by
+ * amdgpu_dm_enable_self_refresh() once async flips stop.
+ */
+ if (immediate_flip) {
+ dc_exit_ips_for_hw_access(dm->dc);
+ amdgpu_dm_psr_set_event(dm, acrtc_state->stream, true,
+ psr_event_immediate_flip, true);
+ amdgpu_dm_replay_set_event(dm, acrtc_state->stream, true,
+ replay_event_immediate_flip, true);
+ }
update_planes_and_stream_adapter(dm->dc,
acrtc_state->update_type,
planes_count,

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c

View file
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
index d386bb1..45a69bf 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c
@@ -1012,10 +1012,15 @@ decide_crtc_timing_for_drm_display_mode(struct drm_display_mode *drm_mode,
const struct drm_display_mode *native_mode,
bool scale_enabled)
{
+ /* Inserted modes copy the native sync; a sink mode with equal totals may not */
if (scale_enabled || (
native_mode->clock == drm_mode->clock &&
native_mode->htotal == drm_mode->htotal &&
- native_mode->vtotal == drm_mode->vtotal)) {
+ native_mode->vtotal == drm_mode->vtotal &&
+ native_mode->hsync_start == drm_mode->hsync_start &&
+ native_mode->hsync_end == drm_mode->hsync_end &&
+ native_mode->vsync_start == drm_mode->vsync_start &&
+ native_mode->vsync_end == drm_mode->vsync_end)) {
if (native_mode->crtc_clock)
copy_crtc_timing_for_drm_display_mode(native_mode, drm_mode);
} else {

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c

View file
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
index e13b963..a2b8f70 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c
@@ -112,25 +112,7 @@ void amdgpu_dm_plane_fill_blending_from_plane_state(const struct drm_plane_state
if (plane_state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI ||
plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE) {
- static const uint32_t alpha_formats[] = {
- DRM_FORMAT_ARGB8888,
- DRM_FORMAT_RGBA8888,
- DRM_FORMAT_ABGR8888,
- DRM_FORMAT_ARGB2101010,
- DRM_FORMAT_ABGR2101010,
- DRM_FORMAT_ARGB16161616,
- DRM_FORMAT_ABGR16161616,
- DRM_FORMAT_ARGB16161616F,
- };
- uint32_t format = plane_state->fb->format->format;
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(alpha_formats); ++i) {
- if (format == alpha_formats[i]) {
- *per_pixel_alpha = true;
- break;
- }
- }
+ *per_pixel_alpha = plane_state->fb->format->has_alpha;
if (*per_pixel_alpha && plane_state->pixel_blend_mode == DRM_MODE_BLEND_COVERAGE)
*pre_multiplied_alpha = false;

drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c

View file
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
index 59ce682..b617717 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c
@@ -1572,6 +1572,46 @@ static void dm_test_decide_crtc_timing_no_crtc_clock(struct kunit *test)
KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 0);
}
+static void dm_test_decide_crtc_timing_sink_mode_same_totals(struct kunit *test)
+{
+ struct drm_display_mode native_mode = {
+ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016, 4104,
+ 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) };
+ struct drm_display_mode drm_mode = {
+ DRM_MODE("4096x2160", DRM_MODE_TYPE_DRIVER, 594000, 4096, 4184, 4272,
+ 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) };
+
+ drm_mode_set_crtcinfo(&native_mode, 0);
+ drm_mode_set_crtcinfo(&drm_mode, 0);
+
+ decide_crtc_timing_for_drm_display_mode(&drm_mode, &native_mode, false);
+
+ KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 4096);
+ KUNIT_EXPECT_EQ(test, drm_mode.crtc_hsync_start, 4184);
+}
+
+static void dm_test_decide_crtc_timing_inserted_mode(struct kunit *test)
+{
+ struct drm_display_mode native_mode = {
+ DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016, 4104,
+ 4400, 0, 2160, 2168, 2178, 2250, 0,
+ DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) };
+ struct drm_display_mode drm_mode;
+
+ drm_mode_set_crtcinfo(&native_mode, 0);
+ drm_mode = native_mode;
+ drm_mode.hdisplay = 1920;
+ drm_mode.vdisplay = 1080;
+ drm_mode_set_crtcinfo(&drm_mode, 0);
+
+ decide_crtc_timing_for_drm_display_mode(&drm_mode, &native_mode, false);
+
+ KUNIT_EXPECT_EQ(test, drm_mode.crtc_hdisplay, 3840);
+ KUNIT_EXPECT_EQ(test, drm_mode.crtc_vdisplay, 2160);
+}
+
/* Tests for amdgpu_dm_connector_funcs_reset() */
static const struct drm_connector_funcs dm_test_connector_funcs = {
@@ -5635,6 +5675,8 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
KUNIT_CASE(dm_test_decide_crtc_timing_matching_mode),
KUNIT_CASE(dm_test_decide_crtc_timing_no_copy),
KUNIT_CASE(dm_test_decide_crtc_timing_no_crtc_clock),
+ KUNIT_CASE(dm_test_decide_crtc_timing_sink_mode_same_totals),
+ KUNIT_CASE(dm_test_decide_crtc_timing_inserted_mode),
/* amdgpu_dm_connector_funcs_reset */
KUNIT_CASE(dm_test_funcs_reset_sets_defaults),
KUNIT_CASE(dm_test_funcs_reset_edp_abm_level),

drivers/gpu/drm/aspeed/aspeed_gfx_drv.c

View file
diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
index d457766..aa36b79 100644
--- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
+++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c
@@ -189,13 +189,12 @@ static int aspeed_gfx_load(struct drm_device *drm)
}
reset_control_deassert(priv->rst);
- priv->clk = devm_clk_get(drm->dev, NULL);
+ priv->clk = devm_clk_get_enabled(drm->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev,
- "missing or invalid clk device tree entry");
+ "failed to get and enable clock\n");
return PTR_ERR(priv->clk);
}
- clk_prepare_enable(priv->clk);
/* Sanitize control registers */
writel(0, priv->base + CRT_CTRL1);

drivers/gpu/drm/bridge/th1520-dw-hdmi.c

View file
diff --git a/drivers/gpu/drm/bridge/th1520-dw-hdmi.c b/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
index cbea8b1..2fa7f2d 100644
--- a/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/th1520-dw-hdmi.c
@@ -135,8 +135,8 @@ static int th1520_dw_hdmi_probe(struct platform_device *pdev)
plat_data->priv_data = hdmi;
hdmi->dw_hdmi = dw_hdmi_probe(pdev, plat_data);
- if (IS_ERR(hdmi))
- return PTR_ERR(hdmi);
+ if (IS_ERR(hdmi->dw_hdmi))
+ return PTR_ERR(hdmi->dw_hdmi);
platform_set_drvdata(pdev, hdmi);
@@ -145,9 +145,9 @@ static int th1520_dw_hdmi_probe(struct platform_device *pdev)
static void th1520_dw_hdmi_remove(struct platform_device *pdev)
{
- struct dw_hdmi *hdmi = platform_get_drvdata(pdev);
+ struct th1520_hdmi *hdmi = platform_get_drvdata(pdev);
- dw_hdmi_remove(hdmi);
+ dw_hdmi_remove(hdmi->dw_hdmi);
}
static const struct of_device_id th1520_dw_hdmi_of_table[] = {

drivers/gpu/drm/display/drm_dp_helper.c

View file
diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c
index e623ccb..488fd12 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -4634,7 +4634,9 @@ static int dp_aux_backlight_update_status(struct backlight_device *bd)
if (!backlight_is_blank(bd)) {
if (!bl->enabled) {
- drm_edp_backlight_enable(bl->aux, &bl->info, brightness);
+ ret = drm_edp_backlight_enable(bl->aux, &bl->info, brightness);
+ if (ret)
+ return ret;
bl->enabled = true;
return 0;
}

drivers/gpu/drm/drm_bridge.c

View file
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 83f1809..a52d5f5 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -454,8 +454,10 @@ void drm_bridge_add(struct drm_bridge *bridge)
* in bridge_lingering_list. Remove it or bridge_lingering_list will be
* corrupted when adding this bridge to bridge_list below.
*/
+ mutex_lock(&bridge_lock);
if (!list_empty(&bridge->list))
list_del_init(&bridge->list);
+ mutex_unlock(&bridge_lock);
mutex_init(&bridge->hpd_state_mutex);
mutex_init(&bridge->hpd_mutex);
@@ -593,8 +595,10 @@ int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
if (!bridge->container)
DRM_WARN("DRM bridge corrupted or not allocated by devm_drm_bridge_alloc()\n");
- if (list_empty(&bridge->list))
- DRM_WARN("Missing drm_bridge_add() before attach\n");
+ scoped_guard(mutex, &bridge_lock) {
+ if (list_empty(&bridge->list))
+ DRM_WARN("Missing drm_bridge_add() before attach\n");
+ }
drm_bridge_get(bridge);

drivers/gpu/drm/drm_fb_helper.c

View file
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index d4664ed..0817b63 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -1724,10 +1724,10 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper)
ret = drm_fb_helper_single_fb_probe(fb_helper);
if (ret < 0) {
- if (ret == -EAGAIN) {
- fb_helper->deferred_setup = true;
+ /* modesets are probed but fb_helper->fb isn't; defer restore too */

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/gud/gud_pipe.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/i915/gt/intel_rps.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/imagination/pvr_mmu.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/imagination/pvr_vm.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/nouveau/nouveau_abi16.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/nouveau/nvkm/engine/device/user.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/panthor/panthor_sched.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vc4/vc4_bo.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vc4/vc4_drv.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vc4/vc4_drv.h

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vc4/vc4_gem.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vc4/vc4_irq.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vc4/vc4_v3d.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vc4/vc4_validate.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vmwgfx/vmwgfx_cursor_plane.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/xe/display/xe_fb_pin.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/xe/xe_bo.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/xe/xe_bo.h

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/xe/xe_i2c.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/xe/xe_lrc.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/xe/xe_mmio.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpu/drm/xe/xe_sysctrl_mailbox.c

View file

This diff is incomplete. Download the complete patch.