summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/buddy.c13
-rw-r--r--drivers/gpu/drm/adp/Kconfig1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c11
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_device.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_object.c3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c25
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c5
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c6
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c8
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c8
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_chardev.c12
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c13
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c12
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c14
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c8
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_connector.c24
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c20
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c6
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c31
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_connector_test.c39
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c8
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c4
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c18
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c4
-rw-r--r--drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c6
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c7
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_surface.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dccg/dcn60/dcn60_dccg.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c34
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h4
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c1
-rw-r--r--drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/irq/dcn60/irq_service_dcn60.c3
-rw-r--r--drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c2
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c4
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c50
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn42b/dcn42b_resource.c46
-rw-r--r--drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c42
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power.c5
-rw-r--r--drivers/gpu/drm/amd/display/modules/power/power_abm.c3
-rw-r--r--drivers/gpu/drm/amd/pm/amdgpu_dpm.c6
-rw-r--r--drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c2
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c8
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c4
-rw-r--r--drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c4
-rw-r--r--drivers/gpu/drm/amd/ras/core/cmd.c4
-rw-r--r--drivers/gpu/drm/ast/ast_cursor.c3
-rw-r--r--drivers/gpu/drm/bridge/tc358768.c15
-rw-r--r--drivers/gpu/drm/bridge/ti-sn65dsi83.c6
-rw-r--r--drivers/gpu/drm/drm_atomic_state_helper.c7
-rw-r--r--drivers/gpu/drm/drm_atomic_uapi.c5
-rw-r--r--drivers/gpu/drm/drm_exec.c15
-rw-r--r--drivers/gpu/drm/drm_pagemap.c270
-rw-r--r--drivers/gpu/drm/drm_panic_qr.rs4
-rw-r--r--drivers/gpu/drm/drm_prime.c2
-rw-r--r--drivers/gpu/drm/drm_syncobj.c2
-rw-r--r--drivers/gpu/drm/gud/gud_connector.c12
-rw-r--r--drivers/gpu/drm/gud/gud_drv.c2
-rw-r--r--drivers/gpu/drm/i915/display/intel_cdclk.c10
-rw-r--r--drivers/gpu/drm/i915/display/intel_cursor.c15
-rw-r--r--drivers/gpu/drm/i915/display/intel_cx0_phy.c5
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.c11
-rw-r--r--drivers/gpu/drm/i915/display/intel_ddi.h1
-rw-r--r--drivers/gpu/drm/i915/display/intel_display_types.h2
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c44
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp_mst.c4
-rw-r--r--drivers/gpu/drm/i915/display/intel_lt_phy.c6
-rw-r--r--drivers/gpu/drm/i915/display/skl_universal_plane.c15
-rw-r--r--drivers/gpu/drm/i915/i915_pci.c3
-rw-r--r--drivers/gpu/drm/i915/i915_query.c4
-rw-r--r--drivers/gpu/drm/logicvc/Kconfig1
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c9
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dmem.c18
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_sgdma.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_uvmm.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/base.c10
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c191
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h17
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c86
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c125
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c64
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c9
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h5
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c3
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c6
-rw-r--r--drivers/gpu/drm/rockchip/Kconfig3
-rw-r--r--drivers/gpu/drm/rockchip/analogix_dp-rockchip.c7
-rw-r--r--drivers/gpu/drm/scheduler/tests/mock_scheduler.c11
-rw-r--r--drivers/gpu/drm/sysfb/ofdrm.c8
-rw-r--r--drivers/gpu/drm/tegra/dc.c6
-rw-r--r--drivers/gpu/drm/tegra/hub.c2
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c2
-rw-r--r--drivers/gpu/drm/tiny/cirrus-qemu.c3
-rw-r--r--drivers/gpu/drm/vboxvideo/vbox_mode.c4
-rw-r--r--drivers/gpu/drm/verisilicon/vs_plane.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c9
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.h21
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_kms.c1
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_object.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_plane.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_prime.c4
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_vq.c21
-rw-r--r--drivers/gpu/drm/vkms/vkms_configfs.c8
-rw-r--r--drivers/gpu/drm/xe/instructions/xe_gpu_commands.h1
-rw-r--r--drivers/gpu/drm/xe/xe_amc.c2
-rw-r--r--drivers/gpu/drm/xe/xe_oa.c6
-rw-r--r--drivers/gpu/drm/xe/xe_pagefault.c10
-rw-r--r--drivers/gpu/drm/xe/xe_pagefault_types.h3
-rw-r--r--drivers/gpu/drm/xe/xe_ring_ops.c11
-rw-r--r--drivers/gpu/drm/xe/xe_vm.c2
-rw-r--r--drivers/gpu/drm/xe/xe_vram.c3
146 files changed, 1362 insertions, 479 deletions
diff --git a/drivers/gpu/buddy.c b/drivers/gpu/buddy.c
index a5553fcec28c..26e7a48b55f3 100644
--- a/drivers/gpu/buddy.c
+++ b/drivers/gpu/buddy.c
@@ -411,16 +411,13 @@ int gpu_buddy_init(struct gpu_buddy *mm, u64 size, u64 chunk_size)
if (!mm->used_scoreboard)
goto out_free_free_scoreboard;
- mm->free_trees = kmalloc_array(GPU_BUDDY_MAX_FREE_TREES,
- sizeof(*mm->free_trees),
- GFP_KERNEL);
+ mm->free_trees = kmalloc_objs(*mm->free_trees, GPU_BUDDY_MAX_FREE_TREES);
if (!mm->free_trees)
goto out_free_used_scoreboard;
for_each_free_tree(i) {
- mm->free_trees[i] = kmalloc_array(mm->max_order + 1,
- sizeof(struct rb_root),
- GFP_KERNEL);
+ mm->free_trees[i] = kmalloc_objs(struct rb_root,
+ mm->max_order + 1);
if (!mm->free_trees[i])
goto out_free_tree;
@@ -430,9 +427,7 @@ int gpu_buddy_init(struct gpu_buddy *mm, u64 size, u64 chunk_size)
mm->n_roots = hweight64(size);
- mm->roots = kmalloc_array(mm->n_roots,
- sizeof(struct gpu_buddy_block *),
- GFP_KERNEL);
+ mm->roots = kmalloc_objs(struct gpu_buddy_block *, mm->n_roots);
if (!mm->roots)
goto out_free_tree;
diff --git a/drivers/gpu/drm/adp/Kconfig b/drivers/gpu/drm/adp/Kconfig
index 9fcc27eb200d..acfa21ee06d2 100644
--- a/drivers/gpu/drm/adp/Kconfig
+++ b/drivers/gpu/drm/adp/Kconfig
@@ -6,7 +6,6 @@ config DRM_ADP
select DRM_KMS_HELPER
select DRM_BRIDGE_CONNECTOR
select DRM_DISPLAY_HELPER
- select DRM_KMS_DMA_HELPER
select DRM_GEM_DMA_HELPER
select DRM_PANEL_BRIDGE
select VIDEOMODE_HELPERS
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
index 87e15e39eb30..7fd2a8bc7d08 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c
@@ -299,10 +299,10 @@ amdgpu_devcoredump_print_ibs(struct drm_printer *p,
amdgpu_res_first(abo->tbo.resource, offset,
coredump->ibs[i].ib_size_dw * 4, &cursor);
while (cursor.remaining) {
- amdgpu_device_mm_access(adev, cursor.start / 4,
- &ib_content[off], cursor.size / 4,
+ amdgpu_device_mm_access(adev, cursor.start,
+ &ib_content[off], cursor.size,
false);
- off += cursor.size;
+ off += cursor.size / 4;
amdgpu_res_next(&cursor, cursor.size);
}
emit_content = true;
@@ -603,9 +603,8 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check,
ring_count++;
}
if (ring_count)
- coredump->rings = kvcalloc(ring_count,
- sizeof(struct amdgpu_coredump_ring),
- GFP_NOWAIT);
+ coredump->rings = kvzalloc_objs(struct amdgpu_coredump_ring,
+ ring_count, GFP_NOWAIT);
if (coredump->rings) {
for (i = 0, idx = 0; i < adev->num_rings && idx < ring_count; i++) {
struct amdgpu_coredump_ring *cdump_ring;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index 44bed0ba64a3..104d1d2cbad9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -771,6 +771,9 @@ static int amdgpu_device_read_fb_via_bar0(struct amdgpu_device *adev,
if (!buf || !size)
return -EINVAL;
+ if (!amdgpu_sriov_vf(adev))
+ return -EINVAL;
+
flags = pci_resource_flags(adev->pdev, 0);
if ((flags & IORESOURCE_UNSET) || !(flags & IORESOURCE_MEM))
return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
index 164e85b66e2d..62f5c5cbd7f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c
@@ -1608,11 +1608,11 @@ int amdgpu_discovery_sysfs_early_init(struct amdgpu_device *adev, struct pci_dev
discovery_bin = adev->discovery.bin;
- early_entry = kzalloc(sizeof(*early_entry), GFP_KERNEL);
+ early_entry = kzalloc_obj(*early_entry);
if (!early_entry)
return -ENOMEM;
- ip_top = kzalloc(sizeof(*ip_top), GFP_KERNEL);
+ ip_top = kzalloc_obj(*ip_top);
if (!ip_top) {
kfree(early_entry);
return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c
index d5787d848d04..4a7f63fb2fad 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_lockdep.c
@@ -98,7 +98,7 @@ int amdgpu_lockdep_init(void)
struct amdgpu_lockdep_dummy_locks *locks;
unsigned long flags;
- locks = kzalloc(sizeof(*locks), GFP_KERNEL);
+ locks = kzalloc_obj(*locks);
if (!locks)
return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
index b96f94e5169f..1a86a47406b1 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c
@@ -879,7 +879,7 @@ bool amdgpu_mes_queue_reset_by_mes_supported(struct amdgpu_device *adev)
return (ip_maj == 11 && mes_sched >= 0x8c) ||
((ip_maj == 12 && ip_min == 0) && mes_sched >= 0x8d) ||
- ((ip_maj == 12 && ip_min == 1) && mes_sched >= 0x73);
+ ((ip_maj == 12 && ip_min == 1) && mes_sched >= 0x7b);
}
/* Fix me -- node_id is used to identify the correct MES instances in the future */
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
index 5d9d137209b6..1b6c32a177fb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
@@ -1701,9 +1701,8 @@ u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
if (dma_resv_trylock(bo->tbo.base.resv)) {
dma_resv_describe(bo->tbo.base.resv, m);
dma_resv_unlock(bo->tbo.base.resv);
- } else {
- seq_puts(m, "\n");
}
+ seq_puts(m, "\n");
return size;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
index 04f6ebf31cca..42adc8e738d8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c
@@ -396,6 +396,12 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev,
bool ret = false;
int i;
+ /*
+ * Runtime DB is for dGPUs only.
+ */
+ if (adev->flags & AMD_IS_APU)
+ return false;
+
if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) ||
amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
index 95468b9463fb..78adfc839ef8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c
@@ -1293,7 +1293,7 @@ amdgpu_ras_debugfs_table_read_uniras(struct amdgpu_device *adev,
return -ENOMEM;
if (num_recs) {
- records = kvcalloc(num_recs, sizeof(*records), GFP_KERNEL);
+ records = kvzalloc_objs(*records, num_recs);
if (!records) {
res = -ENOMEM;
goto out;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
index d5a419776e93..016957cac1f2 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -191,6 +191,8 @@ amdgpu_ttm_job_submit(struct amdgpu_device *adev, struct amdgpu_ttm_buffer_entit
* @tmz: if we should setup a TMZ enabled mapping
* @size: in number of bytes to map, out number of bytes mapped
* @addr: resulting address inside the MC address space
+ * @vm_needs_flush: out, set true if a GART window was programmed (VMID 0 flush
+ * needed) or false for a direct address
*
* Setup one of the GART windows to access a specific piece of memory or return
* the physical address for local memory.
@@ -200,7 +202,8 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,
struct ttm_resource *mem,
struct amdgpu_res_cursor *mm_cur,
unsigned int window,
- bool tmz, uint64_t *size, uint64_t *addr)
+ bool tmz, uint64_t *size, uint64_t *addr,
+ bool *vm_needs_flush)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
unsigned int offset, num_pages, num_dw, num_bytes;
@@ -221,9 +224,12 @@ static int amdgpu_ttm_map_buffer(struct amdgpu_ttm_buffer_entity *entity,
if (!tmz && mem->start != AMDGPU_BO_INVALID_OFFSET) {
*addr = amdgpu_ttm_domain_start(adev, mem->mem_type) +
mm_cur->start;
+ *vm_needs_flush = false;
return 0;
}
+ /* A GART window is programmed below, so its VMID 0 TLB needs a flush */
+ *vm_needs_flush = true;
/*
* If start begins at an offset inside the page, then adjust the size
@@ -324,6 +330,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
while (src_mm.remaining) {
uint64_t from, to, cur_size, tiling_flags;
uint32_t num_type, data_format, max_com, write_compress_disable;
+ bool src_vm_flush, dst_vm_flush;
struct dma_fence *next;
/* Never copy more than 256MiB at once to avoid a timeout */
@@ -331,12 +338,12 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
/* Map src to window 0 and dst to window 1. */
r = amdgpu_ttm_map_buffer(entity, src->bo, src->mem, &src_mm,
- 0, tmz, &cur_size, &from);
+ 0, tmz, &cur_size, &from, &src_vm_flush);
if (r)
goto error;
r = amdgpu_ttm_map_buffer(entity, dst->bo, dst->mem, &dst_mm,
- 1, tmz, &cur_size, &to);
+ 1, tmz, &cur_size, &to, &dst_vm_flush);
if (r)
goto error;
@@ -364,7 +371,7 @@ static int amdgpu_ttm_copy_mem_to_mem(struct amdgpu_device *adev,
}
r = amdgpu_copy_buffer(adev, entity, from, to, cur_size, resv,
- &next, true, copy_flags);
+ &next, src_vm_flush || dst_vm_flush, copy_flags);
if (r)
goto error;
@@ -2361,9 +2368,8 @@ void amdgpu_ttm_enable_buffer_funcs(struct amdgpu_device *adev)
num_clear_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
num_move_entities = MIN(adev->mman.num_buffer_funcs_scheds, TTM_NUM_MOVE_FENCES);
- adev->mman.clear_entities = kcalloc(num_clear_entities,
- sizeof(struct amdgpu_ttm_buffer_entity),
- GFP_KERNEL);
+ adev->mman.clear_entities = kzalloc_objs(struct amdgpu_ttm_buffer_entity,
+ num_clear_entities);
atomic_set(&adev->mman.next_clear_entity, 0);
if (!adev->mman.clear_entities)
goto error_free_default_entity;
@@ -2625,6 +2631,7 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct dma_fence *fence = NULL;
struct amdgpu_res_cursor dst;
+ bool vm_needs_flush = false;
int r;
if (!entity)
@@ -2646,13 +2653,13 @@ int amdgpu_ttm_clear_buffer(struct amdgpu_ttm_buffer_entity *entity,
cur_size = min(dst.size, 256ULL << 20);
r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst,
- 0, false, &cur_size, &to);
+ 0, false, &cur_size, &to, &vm_needs_flush);
if (r)
goto error;
r = amdgpu_ttm_fill_mem(adev, entity,
0, to, cur_size, resv,
- &next, true, k_job_id);
+ &next, vm_needs_flush, k_job_id);
if (r)
goto error;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
index a98a6cfd4fba..71d34fd09385 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c
@@ -159,8 +159,8 @@ void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev,
adev->umc.ras->ecc_info_query_ras_error_address &&
adev->umc.max_ras_err_cnt_per_query) {
err_data->err_addr =
- kcalloc(adev->umc.max_ras_err_cnt_per_query,
- sizeof(struct eeprom_table_record), GFP_KERNEL);
+ kzalloc_objs(struct eeprom_table_record,
+ adev->umc.max_ras_err_cnt_per_query);
/* still call query_ras_error_address to clear error status
* even NOMEM error is encountered
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
index 0a816b3c5ff9..e43bda0cab3f 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c
@@ -1544,7 +1544,7 @@ int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost)
struct amdgpu_usermode_queue *queue;
const struct amdgpu_userq_funcs *userq_funcs;
unsigned long queue_id;
- int r = 0;
+ int ret = 0, r;
xa_for_each(&adev->userq_doorbell_xa, queue_id, queue) {
if (queue->state == AMDGPU_USERQ_STATE_HUNG && !vram_lost) {
@@ -1555,6 +1555,7 @@ int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost)
r = userq_funcs->map(queue);
if (r) {
dev_err(adev->dev, "Failed to remap queue %ld\n", queue_id);
+ ret = r;
continue;
}
trace_amdgpu_userq_state_changed(queue, AMDGPU_USERQ_STATE_MAPPED);
@@ -1562,5 +1563,5 @@ int amdgpu_userq_post_reset(struct amdgpu_device *adev, bool vram_lost)
}
}
- return r;
+ return ret;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
index 4b023e024d9f..743b41db5b7c 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c
@@ -227,7 +227,7 @@ static int amdgpu_userq_fence_alloc(struct amdgpu_usermode_queue *userq,
struct amdgpu_userq_fence *userq_fence;
void *entry;
- userq_fence = kmalloc(sizeof(*userq_fence), GFP_KERNEL);
+ userq_fence = kmalloc_obj(*userq_fence);
if (!userq_fence)
return -ENOMEM;
@@ -244,9 +244,7 @@ static int amdgpu_userq_fence_alloc(struct amdgpu_usermode_queue *userq,
} while (xas_retry(&xas, entry));
rcu_read_unlock();
- userq_fence->fence_drv_array = kvmalloc_array(xas.xa_index,
- sizeof(fence_drv),
- GFP_KERNEL);
+ userq_fence->fence_drv_array = kvmalloc_objs(fence_drv, xas.xa_index);
if (!userq_fence->fence_drv_array) {
mutex_unlock(&userq->fence_drv_lock);
kfree(userq_fence);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
index b43fc643668d..7a007f4916bc 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
@@ -316,8 +316,8 @@ static int amdgpu_virt_ras_realloc_eh_data_space(struct amdgpu_device *adev,
if (align_space > AMDGPU_VIRT_RAS_BAD_PAGE_TABLE_MAX_CAPACITY)
return -ENOMEM;
- new_bps = kmalloc_array(align_space, sizeof(*data->bps), GFP_KERNEL);
- new_bo = kcalloc(align_space, sizeof(*data->bps_bo), GFP_KERNEL);
+ new_bps = kmalloc_objs(*data->bps, align_space);
+ new_bo = kzalloc_objs(*data->bps_bo, align_space);
if (!new_bps || !new_bo) {
kfree(new_bps);
kfree(new_bo);
@@ -355,7 +355,7 @@ static int amdgpu_virt_init_ras_err_handler_data(struct amdgpu_device *adev)
if (!bps)
goto bps_failure;
- bps_bo = kcalloc(align_space, sizeof(*(*data)->bps_bo), GFP_KERNEL);
+ bps_bo = kzalloc_objs(*(*data)->bps_bo, align_space);
if (!bps_bo)
goto bps_bo_failure;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index aedf72c2333e..bb04101b0fb5 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -2090,7 +2090,7 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
after->start = eaddr + 1;
after->last = tmp->last;
after->offset = tmp->offset;
- after->offset += (after->start - tmp->start) << PAGE_SHIFT;
+ after->offset += (after->start - tmp->start) << AMDGPU_GPU_PAGE_SHIFT;
after->flags = tmp->flags;
after->bo_va = tmp->bo_va;
list_add(&after->list, &tmp->bo_va->invalids);
@@ -3122,7 +3122,7 @@ static void amdgpu_debugfs_vm_bo_status_info(struct seq_file *m,
id = 0;
seq_puts(m, "\tIdle BOs:\n");
- list_for_each_entry(base, &lists->needs_update, vm_status) {
+ list_for_each_entry(base, &lists->idle, vm_status) {
if (!base->bo)
continue;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index 69776dbe188d..0ff5a80aa918 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -1651,10 +1651,10 @@ static int gfx_v11_0_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(11, 0, 2):
case IP_VERSION(11, 0, 3):
if (!adev->gfx.disable_uq &&
- adev->gfx.me_fw_version >= 2420 &&
- adev->gfx.pfp_fw_version >= 2580 &&
- adev->gfx.mec_fw_version >= 2650 &&
- adev->mes.fw_version[0] >= 120) {
+ adev->gfx.me_fw_version >= 3090 &&
+ adev->gfx.pfp_fw_version >= 3190 &&
+ adev->gfx.mec_fw_version >= 3450 &&
+ adev->mes.fw_version[0] >= 147) {
adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs;
adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index 1e5fd1ef8f1d..e2a81a55c63b 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -1436,10 +1436,10 @@ static int gfx_v12_0_sw_init(struct amdgpu_ip_block *ip_block)
case IP_VERSION(12, 0, 0):
case IP_VERSION(12, 0, 1):
if (!adev->gfx.disable_uq &&
- adev->gfx.me_fw_version >= 2780 &&
- adev->gfx.pfp_fw_version >= 2840 &&
- adev->gfx.mec_fw_version >= 3050 &&
- adev->mes.fw_version[0] >= 123) {
+ adev->gfx.me_fw_version >= 3090 &&
+ adev->gfx.pfp_fw_version >= 3190 &&
+ adev->gfx.mec_fw_version >= 3450 &&
+ adev->mes.fw_version[0] >= 147) {
adev->userq_funcs[AMDGPU_HW_IP_GFX] = &userq_mes_funcs;
adev->userq_funcs[AMDGPU_HW_IP_COMPUTE] = &userq_mes_funcs;
}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index 6cf427995078..7f91186ef1d1 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -4546,9 +4546,11 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
/* set static priority for a queue/ring */
gfx_v8_0_mqd_set_priority(ring, mqd);
tmp = RREG32(mmCP_HQD_QUANTUM);
- tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_EN, 1);
- tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_SCALE, 1);
- tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_DURATION, 10);
+ if (ring != &adev->gfx.kiq[0].ring) {
+ tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_EN, 1);
+ tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_SCALE, 1);
+ tmp = REG_SET_FIELD(tmp, CP_HQD_QUANTUM, QUANTUM_DURATION, 10);
+ }
mqd->cp_hqd_quantum = tmp;
/* map_queues packet doesn't need activate the queue,
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
index 7fcfc150a7fc..504a286368eb 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
@@ -1921,13 +1921,13 @@ static int criu_checkpoint_devices(struct kfd_process *p,
struct kfd_criu_device_bucket *device_buckets = NULL;
int ret = 0, i;
- device_buckets = kvcalloc(num_devices, sizeof(*device_buckets), GFP_KERNEL);
+ device_buckets = kvzalloc_objs(*device_buckets, num_devices);
if (!device_buckets) {
ret = -ENOMEM;
goto exit;
}
- device_priv = kvcalloc(num_devices, sizeof(*device_priv), GFP_KERNEL);
+ device_priv = kvzalloc_objs(*device_priv, num_devices);
if (!device_priv) {
ret = -ENOMEM;
goto exit;
@@ -2047,17 +2047,17 @@ static int criu_checkpoint_bos(struct kfd_process *p,
int ret = 0, pdd_index, bo_index = 0, id;
void *mem;
- bo_buckets = kvcalloc(num_bos, sizeof(*bo_buckets), GFP_KERNEL);
+ bo_buckets = kvzalloc_objs(*bo_buckets, num_bos);
if (!bo_buckets)
return -ENOMEM;
- bo_privs = kvcalloc(num_bos, sizeof(*bo_privs), GFP_KERNEL);
+ bo_privs = kvzalloc_objs(*bo_privs, num_bos);
if (!bo_privs) {
ret = -ENOMEM;
goto exit;
}
- files = kvcalloc(num_bos, sizeof(struct file *), GFP_KERNEL);
+ files = kvzalloc_objs(struct file *, num_bos);
if (!files) {
ret = -ENOMEM;
goto exit;
@@ -2588,7 +2588,7 @@ static int criu_restore_bos(struct kfd_process *p,
if (!bo_buckets)
return -ENOMEM;
- files = kvcalloc(args->num_bos, sizeof(struct file *), GFP_KERNEL);
+ files = kvzalloc_objs(struct file *, args->num_bos);
if (!files) {
ret = -ENOMEM;
goto exit;
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 4bc947c3bd0d..9811e4e10291 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
@@ -1455,6 +1455,14 @@ static int evict_process_queues_cpsch(struct device_queue_manager *dqm,
dqm_evict_mqd_bo(dqm, q);
}
+ /*
+ * Heavy-weight TLB flush after MES removes queues to ensure
+ * in-flight memory accesses complete before memory is freed/migrated.
+ * HWS does this automatically, MES does not.
+ */
+ if (dqm->dev->kfd->shared_resources.enable_mes)
+ kfd_flush_tlb(pdd);
+
if (!dqm->dev->kfd->shared_resources.enable_mes) {
pdd->last_evict_timestamp = get_jiffies_64();
retval = execute_queues_cpsch(dqm,
@@ -3746,8 +3754,11 @@ int suspend_queues(struct kfd_process *p,
if (!per_device_suspended) {
dqm_unlock(dqm);
mutex_unlock(&p->event_mutex);
- if (total_suspended)
+ if (total_suspended) {
amdgpu_amdkfd_debug_mem_fence(dqm->dev->adev);
+ /* Heavy-weight TLB flush after MES suspends queues */
+ kfd_flush_tlb(pdd);
+ }
continue;
}
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
index ef1d1cb46152..4fe40e9fcfc8 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -1169,13 +1169,13 @@ int pqm_debugfs_mqds(struct seq_file *m, void *data)
mqd_mgr = q->device->dqm->mqd_mgrs[mqd_type];
size = mqd_mgr->mqd_stride(mqd_mgr,
&q->properties);
- }
- for (xcc = 0; xcc < num_xccs; xcc++) {
- mqd = q->mqd + size * xcc;
- r = mqd_mgr->debugfs_show_mqd(m, mqd);
- if (r != 0)
- break;
+ for (xcc = 0; xcc < num_xccs; xcc++) {
+ mqd = q->mqd + size * xcc;
+ r = mqd_mgr->debugfs_show_mqd(m, mqd);
+ if (r != 0)
+ break;
+ }
}
}
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 ec483276d753..08b8605029ab 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -747,9 +747,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
}
if (adev->dm.dc->caps.max_links > 0) {
adev->dm.hdmi_frl_status_polling_wq =
- create_singlethread_workqueue("hdmi_frl_status_polling_workqueue");
+ create_singlethread_workqueue("hdmi_frl_status_polling_wq");
if (!adev->dm.hdmi_frl_status_polling_wq)
- drm_err(adev_to_drm(adev), "failed to initialize hdmi_frl_status_polling_workqueue\n");
+ drm_err(adev_to_drm(adev), "failed to initialize hdmi_frl_status_polling_wq\n");
}
if (dc_is_dmub_outbox_supported(adev->dm.dc)) {
init_completion(&adev->dm.dmub_aux_transfer_done);
@@ -1972,6 +1972,10 @@ static int dm_resume(struct amdgpu_ip_block *ip_block)
/* On resume we need to rewrite the MSTM control bits to enable MST*/
s3_handle_mst(ddev, false);
+ /* Exit IPS before the detection loop's first AUX/DDC access. */
+ scoped_guard(mutex, &dm->dc_lock)
+ dc_exit_ips_for_hw_access(dm->dc);
+
/* Do detection*/
drm_connector_list_iter_begin(ddev, &iter);
drm_for_each_connector_iter(connector, &iter) {
@@ -3879,7 +3883,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_commit *state,
continue;
bundle->surface_updates[planes_count].surface = dc_plane;
- if (new_pcrtc_state->color_mgmt_changed) {
+ if (new_pcrtc_state->color_mgmt_changed || new_plane_state->color_mgmt_changed) {
bundle->surface_updates[planes_count].gamma = &dc_plane->gamma_correction;
bundle->surface_updates[planes_count].in_transfer_func = &dc_plane->in_transfer_func;
bundle->surface_updates[planes_count].gamut_remap_matrix = &dc_plane->gamut_remap_matrix;
@@ -5698,6 +5702,10 @@ static bool should_reset_plane(struct drm_atomic_commit *state,
if (new_crtc_state->color_mgmt_changed)
return true;
+ /* Plane color pipeline or its colorop changes. */
+ if (new_plane_state->color_mgmt_changed)
+ return true;
+
/*
* On zpos change, planes need to be reordered by removing and re-adding
* them one by one to the dc state, in order of descending zpos.
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
index e61bbc310f33..b9e90ea449ca 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_backlight.c
@@ -534,8 +534,12 @@ void amdgpu_dm_update_connector_ext_caps(struct amdgpu_dm_connector *aconnector)
else if (!IS_ERR_OR_NULL(panel_backlight_quirk) &&
panel_backlight_quirk->force_pwm)
caps->aux_support = false;
- if (caps->aux_support)
- aconnector->dc_link->backlight_control_type = BACKLIGHT_CONTROL_AMD_AUX;
+ if (caps->aux_support) {
+ if (aconnector->dc_link->dpcd_caps.panel_luminance_control)
+ aconnector->dc_link->backlight_control_type = BACKLIGHT_CONTROL_VESA_AUX;
+ else
+ aconnector->dc_link->backlight_control_type = BACKLIGHT_CONTROL_AMD_AUX;
+ }
luminance_range = &conn_base->display_info.luminance_range;
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 c8a1ab8c3b16..154e1f35dcb1 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
@@ -756,10 +756,14 @@ amdgpu_dm_get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing,
break;
case DRM_MODE_COLORIMETRY_BT2020_RGB:
case DRM_MODE_COLORIMETRY_BT2020_YCC:
- if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
- color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
- else
+ if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) {
+ if (connector_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
+ color_space = COLOR_SPACE_2020_RGB_LIMITEDRANGE;
+ else
+ color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
+ } else {
color_space = COLOR_SPACE_2020_YCBCR_LIMITED;
+ }
break;
case DRM_MODE_COLORIMETRY_DEFAULT: /* ITU601 */
default:
@@ -3937,17 +3941,15 @@ void amdgpu_dm_update_freesync_caps(struct drm_connector *connector,
}
/* Handle MCCS */
- if (do_mccs)
+ if (do_mccs) {
dm_helpers_read_mccs_caps(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
- if ((sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A ||
- as_type == FREESYNC_TYPE_PCON_IN_WHITELIST) &&
- (!sink->edid_caps.freesync_vcp_code ||
- (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)))
- freesync_capable = false;
+ if (sink->edid_caps.freesync_vcp_code && !sink->mccs_caps.freesync_supported)
+ freesync_capable = false;
- if (do_mccs && sink->mccs_caps.freesync_supported && freesync_capable)
- dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
+ if (sink->mccs_caps.freesync_supported && freesync_capable)
+ dm_helpers_mccs_vcp_set(adev->dm.dc->ctx, amdgpu_dm_connector->dc_link, sink);
+ }
update:
if (dm_con_state)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
index c4b2fc690fd7..2a6b48e24869 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -196,7 +196,6 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
char *rd_buf_ptr = NULL;
const uint32_t rd_buf_size = 100;
uint32_t result = 0;
- uint8_t str_len = 0;
int r;
if (*pos & 3 || size & 3)
@@ -208,29 +207,26 @@ static ssize_t dp_link_settings_read(struct file *f, char __user *buf,
rd_buf_ptr = rd_buf;
- str_len = strlen("Current: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Current: %d 0x%x %d ",
link->cur_link_settings.lane_count,
link->cur_link_settings.link_rate,
link->cur_link_settings.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Verified: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Verified: %d 0x%x %d ",
link->verified_link_cap.lane_count,
link->verified_link_cap.link_rate,
link->verified_link_cap.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Reported: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Reported: %d 0x%x %d ",
link->reported_link_cap.lane_count,
link->reported_link_cap.link_rate,
link->reported_link_cap.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Preferred: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Preferred: %d 0x%x %d\n",
link->preferred_link_setting.lane_count,
link->preferred_link_setting.link_rate,
link->preferred_link_setting.link_spread);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
index d451082552e8..298de7b75ca8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -200,6 +200,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
if (edid_caps->edid_hdmi) {
+ edid_caps->qs_bit = connector->display_info.rgb_quant_range_selectable;
populate_hdmi_info_from_connector(link->dc->config.enable_frl, &connector->display_info.hdmi, edid_caps);
drm_dbg_driver(connector->dev, "%s: HDMI_FRL [%s] max_frl_rate %d\n", __func__, connector->name, edid_caps->max_frl_rate);
if (edid_caps->frl_dsc_support)
@@ -1202,9 +1203,10 @@ void populate_hdmi_info_from_connector(bool enable_frl, struct drm_hdmi_info *hd
edid_caps->max_frl_rate = get_max_frl_rate(hdmi->max_lanes, hdmi->max_frl_rate_per_lane);
edid_caps->frl_dsc_support = hdmi->dsc_cap.v_1p2;
if (edid_caps->frl_dsc_support) {
- if (hdmi->dsc_cap.bpc_supported == 10)
+ /* HF-VSDB DSC max bpc is cumulative: >=12 implies 10 and 8. */
+ if (hdmi->dsc_cap.bpc_supported >= 10)
edid_caps->frl_dsc_10bpc = true;
- else if (hdmi->dsc_cap.bpc_supported == 12)
+ if (hdmi->dsc_cap.bpc_supported >= 12)
edid_caps->frl_dsc_12bpc = true;
edid_caps->frl_dsc_all_bpp = hdmi->dsc_cap.all_bpp;
edid_caps->frl_dsc_native_420 = hdmi->dsc_cap.native_420;
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 824ef3ce5de0..e13b96358208 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
@@ -2208,16 +2208,41 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
if (res)
return res;
- if (plane->type == DRM_PLANE_TYPE_OVERLAY &&
- plane_cap && plane_cap->per_pixel_alpha) {
+ /* Blend mode support varies on DCE generations according to HW caps
+ * and number of planes per CRTC. However, as current driver
+ * implementation only creates one primary and one cursor plane per
+ * CRTC for DCE (overlay is only created if
+ * DC_PLANE_TYPE_DCN_UNIVERSAL), the primary plane blend mode is
+ * ignored across DCE versions. Keep PREMULTI to avoid uAPI
+ * regressions: it was the default/mandatory mode for many years and,
+ * with no overlay plane, primary composes on top of a black
+ * background, where PREMULTI and PIXEL_NONE are equivalent.
+ */
+ if (plane_cap && plane_cap->type != DC_PLANE_TYPE_DCN_UNIVERSAL) {
+ unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+ BIT(DRM_MODE_BLEND_PREMULTI);
+
+ drm_plane_create_blend_mode_property(plane, blend_caps);
+ } else if ((plane->type == DRM_PLANE_TYPE_OVERLAY ||
+ plane->type == DRM_PLANE_TYPE_PRIMARY) &&
+ plane_cap && plane_cap->per_pixel_alpha) {
unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
BIT(DRM_MODE_BLEND_PREMULTI) |
BIT(DRM_MODE_BLEND_COVERAGE);
- drm_plane_create_alpha_property(plane);
drm_plane_create_blend_mode_property(plane, blend_caps);
+
+ if (plane->type == DRM_PLANE_TYPE_OVERLAY)
+ drm_plane_create_alpha_property(plane);
}
+ /* Cursor color format is set to CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA
+ * by default, so only advertise DRM_MODE_BLEND_PREMULTI blend mode for
+ * this type of plane.
+ */
+ if (plane->type == DRM_PLANE_TYPE_CURSOR)
+ drm_plane_create_blend_mode_property(plane, BIT(DRM_MODE_BLEND_PREMULTI));
+
if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
/*
* Allow OVERLAY planes to be used as underlays by assigning an
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 a54fd9529dc9..212a7536e65b 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
@@ -568,6 +568,23 @@ static void dm_test_output_color_space_bt2020_rgb(struct kunit *test)
}
/**
+ * dm_test_output_color_space_bt2020_rgb_limited - Test limited BT.2020 RGB
+ * @test: The KUnit test context
+ */
+static void dm_test_output_color_space_bt2020_rgb_limited(struct kunit *test)
+{
+ struct dc_crtc_timing timing = {};
+ struct drm_connector_state state = {};
+
+ timing.pixel_encoding = PIXEL_ENCODING_RGB;
+ state.colorspace = DRM_MODE_COLORIMETRY_BT2020_RGB;
+ state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+ KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
+ (int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
+}
+
+/**
* dm_test_output_color_space_bt2020_ycc - Test Output color space bt2020 ycc
* @test: The KUnit test context
*/
@@ -639,6 +656,24 @@ static void dm_test_output_color_space_bt2020_ycc_rgb_encoding(struct kunit *tes
}
/**
+ * dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited - Test limited
+ * BT.2020 RGB output selected through the BT.2020 YCC connector colorspace
+ * @test: The KUnit test context
+ */
+static void dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited(struct kunit *test)
+{
+ struct dc_crtc_timing timing = {};
+ struct drm_connector_state state = {};
+
+ timing.pixel_encoding = PIXEL_ENCODING_RGB;
+ state.colorspace = DRM_MODE_COLORIMETRY_BT2020_YCC;
+ state.hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
+
+ KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_get_output_color_space(&timing, &state),
+ (int)COLOR_SPACE_2020_RGB_LIMITEDRANGE);
+}
+
+/**
* dm_test_output_color_space_bt2020_rgb_ycc_encoding - Test Output color space
* bt2020 rgb with non-rgb pixel encoding falls back to limited ycbcr
* @test: The KUnit test context
@@ -4180,7 +4215,7 @@ dm_test_destroy_connector(struct kunit *test, struct drm_device *drm)
{
struct amdgpu_dm_connector *aconnector;
- aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL);
+ aconnector = kzalloc_obj(*aconnector);
KUNIT_ASSERT_NOT_NULL(test, aconnector);
KUNIT_ASSERT_EQ(test,
@@ -5422,10 +5457,12 @@ static struct kunit_case amdgpu_dm_connector_tests[] = {
KUNIT_CASE(dm_test_output_color_space_bt709_y_only),
KUNIT_CASE(dm_test_output_color_space_oprgb),
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb),
+ KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_limited),
KUNIT_CASE(dm_test_output_color_space_bt2020_ycc),
KUNIT_CASE(dm_test_output_color_space_default_ycbcr709_y_only),
KUNIT_CASE(dm_test_output_color_space_default_ycbcr601),
KUNIT_CASE(dm_test_output_color_space_bt2020_ycc_rgb_encoding),
+ KUNIT_CASE(dm_test_output_color_space_bt2020_ycc_rgb_encoding_limited),
KUNIT_CASE(dm_test_output_color_space_bt2020_rgb_ycc_encoding),
/* Tests for amdgpu_dm_convert_dc_color_depth_into_bpc */
KUNIT_CASE(dm_test_convert_color_depth_bpc_mappings),
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
index 4dacddd23878..0d998f204250 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c
@@ -1445,7 +1445,7 @@ static void dm_test_crtc_destroy_state_no_stream(struct kunit *test)
struct dm_crtc_state *dm_state;
/* destroy_state kfree()s the state, so use a plain (unmanaged) alloc. */
- dm_state = kzalloc_obj(*dm_state, GFP_KERNEL);
+ dm_state = kzalloc_obj(*dm_state);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dm_state);
amdgpu_dm_crtc_destroy_state(NULL, &dm_state->base);
@@ -1475,7 +1475,7 @@ static void dm_test_crtc_destroy_state_releases_stream(struct kunit *test)
kref_get(&stream->refcount);
/* destroy_state kfree()s the state, so use a plain (unmanaged) alloc. */
- dm_state = kzalloc_obj(*dm_state, GFP_KERNEL);
+ dm_state = kzalloc_obj(*dm_state);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dm_state);
dm_state->stream = stream;
@@ -1569,7 +1569,7 @@ static void dm_test_crtc_handle_vblank_completes_cursor_only(struct kunit *test)
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, acrtc);
/* drm_crtc_send_vblank_event() consumes (kfree()s) the event. */
- event = kzalloc_obj(*event, GFP_KERNEL);
+ event = kzalloc_obj(*event);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, event);
acrtc->base.dev = &adev->ddev;
@@ -1628,7 +1628,7 @@ dm_test_vblank_control_worker_setup(struct kunit *test, bool enable,
kref_get(&stream->refcount);
/* Worker kfree()s the work item, so it must be a plain allocation. */
- work = kzalloc_obj(*work, GFP_KERNEL);
+ work = kzalloc_obj(*work);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, work);
work->dm = &adev->dm;
work->acrtc = acrtc;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
index 058e1ad15dfe..82e0c984693c 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_helpers_test.c
@@ -358,12 +358,14 @@ static void dm_test_parse_edid_caps_hdmi_frl(struct kunit *test)
/* Drive the HDMI/FRL branch */
connector->display_info.is_hdmi = true;
+ connector->display_info.rgb_quant_range_selectable = true;
connector->display_info.hdmi.scdc.supported = true;
connector->display_info.hdmi.max_lanes = 4;
connector->display_info.hdmi.max_frl_rate_per_lane = 12;
KUNIT_EXPECT_EQ(test, dm_helpers_parse_edid_caps(link, dc_edid, edid_caps), EDID_OK);
KUNIT_EXPECT_TRUE(test, edid_caps->edid_hdmi);
+ KUNIT_EXPECT_EQ(test, edid_caps->qs_bit, 1);
KUNIT_EXPECT_TRUE(test, edid_caps->scdc_present);
/* max_lanes 4 + max_frl_rate_per_lane 12 -> rate index 6 */
KUNIT_EXPECT_EQ(test, edid_caps->max_frl_rate, 6);
@@ -909,7 +911,7 @@ static void dm_test_populate_hdmi_frl_dsc_12bpc(struct kunit *test)
KUNIT_EXPECT_EQ(test, caps->max_frl_rate, 2);
KUNIT_EXPECT_TRUE(test, caps->frl_dsc_support);
- KUNIT_EXPECT_FALSE(test, caps->frl_dsc_10bpc);
+ KUNIT_EXPECT_TRUE(test, caps->frl_dsc_10bpc);
KUNIT_EXPECT_TRUE(test, caps->frl_dsc_12bpc);
KUNIT_EXPECT_EQ(test, caps->frl_dsc_max_slices, 7);
KUNIT_EXPECT_EQ(test, caps->frl_dsc_max_frl_rate, 1);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
index 28c36217f6a2..861ee9eaa032 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
@@ -103,7 +103,7 @@ static enum dc_status dm_test_dp_read_hpd_rx_irq_data_ok(struct dc_link *link,
*/
static struct dc_sink *dm_test_sink_create(struct dc_link *link)
{
- struct dc_sink *sink = kzalloc(sizeof(*sink), GFP_KERNEL);
+ struct dc_sink *sink = kzalloc_obj(*sink);
if (!sink)
return NULL;
@@ -2131,7 +2131,7 @@ static void dm_test_hpd_rx_offload_work_no_connector(struct kunit *test)
offload_wq = kunit_kzalloc(test, sizeof(*offload_wq), GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, offload_wq);
- offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL);
+ offload_work = kzalloc_obj(*offload_work);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, offload_work);
offload_work->offload_wq = offload_wq;
offload_work->adev = adev;
@@ -2177,7 +2177,7 @@ static void dm_test_hpd_rx_offload_work_no_connection(struct kunit *test)
link->dc = dc;
aconn->dc_link = link;
- offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL);
+ offload_work = kzalloc_obj(*offload_work);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, offload_work);
offload_work->offload_wq = offload_wq;
offload_work->adev = adev;
@@ -2244,7 +2244,7 @@ static void dm_test_hpd_rx_offload_work_automated_test(struct kunit *test)
link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
aconn->dc_link = link;
- offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL);
+ offload_work = kzalloc_obj(*offload_work);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, offload_work);
offload_work->offload_wq = offload_wq;
offload_work->adev = adev;
@@ -2315,7 +2315,7 @@ static void dm_test_hpd_rx_offload_work_link_loss(struct kunit *test)
link->connector_signal = SIGNAL_TYPE_DISPLAY_PORT;
aconn->dc_link = link;
- offload_work = kzalloc(sizeof(*offload_work), GFP_KERNEL);
+ offload_work = kzalloc_obj(*offload_work);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, offload_work);
offload_work->offload_wq = offload_wq;
offload_work->adev = adev;
@@ -3452,9 +3452,9 @@ static void dm_test_handle_hpd_work_out_of_range(struct kunit *test)
struct amdgpu_device *adev;
adev = dm_kunit_alloc_adev(test);
- hpd_work = kzalloc(sizeof(*hpd_work), GFP_KERNEL);
+ hpd_work = kzalloc_obj(*hpd_work);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hpd_work);
- hpd_work->dmub_notify = kzalloc(sizeof(*hpd_work->dmub_notify), GFP_KERNEL);
+ hpd_work->dmub_notify = kzalloc_obj(*hpd_work->dmub_notify);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hpd_work->dmub_notify);
hpd_work->dmub_notify->type =
(enum dmub_notification_type)ARRAY_SIZE(adev->dm.dmub_callback);
@@ -3899,9 +3899,9 @@ static void dm_test_handle_vmin_vmax_update(struct kunit *test)
kref_get(&stream->refcount);
/* The worker kfree()s both, so they must come from the slab. */
- work = kzalloc(sizeof(*work), GFP_KERNEL);
+ work = kzalloc_obj(*work);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, work);
- adjust = kzalloc(sizeof(*adjust), GFP_KERNEL);
+ adjust = kzalloc_obj(*adjust);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adjust);
work->adev = adev;
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
index ba97092c7bb8..23ac8ae41c68 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c
@@ -2945,7 +2945,7 @@ static void dm_test_plane_reset_initializes_state(struct kunit *test)
* destroy-existing-state path. The destroy hook frees this state, so it
* must be a plain (non-KUnit-managed) allocation.
*/
- old_state = kzalloc(sizeof(*old_state), GFP_KERNEL);
+ old_state = kzalloc_obj(*old_state);
KUNIT_ASSERT_NOT_NULL(test, old_state);
plane->funcs = &dm_test_plane_reset_funcs;
plane->state = &old_state->base;
@@ -3018,7 +3018,7 @@ static void dm_test_plane_destroy_state_minimal(struct kunit *test)
KUNIT_ASSERT_NOT_NULL(test, plane);
/* destroy_state frees the state itself, so use a plain allocation. */
- dm_plane_state = kzalloc(sizeof(*dm_plane_state), GFP_KERNEL);
+ dm_plane_state = kzalloc_obj(*dm_plane_state);
KUNIT_ASSERT_NOT_NULL(test, dm_plane_state);
amdgpu_dm_plane_drm_plane_destroy_state(plane, &dm_plane_state->base);
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
index 3c10eec9b1e0..5645866610fc 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_test.c
@@ -239,7 +239,7 @@ static void dm_test_atomic_destroy_state_no_context(struct kunit *test)
* Use kzalloc(), not kunit_kzalloc(): dm_atomic_destroy_state() frees
* the state itself, so KUnit-managed memory would be double-freed.
*/
- dm_state = kzalloc(sizeof(*dm_state), GFP_KERNEL);
+ dm_state = kzalloc_obj(*dm_state);
KUNIT_ASSERT_NOT_NULL(test, dm_state);
/* context == NULL: dc_state_release() is skipped and the state is freed. */
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
index e2148cb3b8ab..bf80eaf23e9a 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c
@@ -377,7 +377,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p
}
break;
case AMDGPU_FAMILY_GC_11_5_4: {
- struct clk_mgr_dcn42 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL);
+ struct clk_mgr_dcn42 *clk_mgr = kzalloc_obj(*clk_mgr);
if (clk_mgr == NULL) {
BREAK_TO_DEBUGGER();
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
index d71b0aed90c9..7dd88d90eba2 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn60/dcn60_clk_mgr.c
@@ -1595,7 +1595,7 @@ struct clk_mgr_internal *dcn60_clk_mgr_construct(
struct dccg *dccg)
{
struct clk_log_info log_info = {0};
- struct dcn60_clk_mgr *clk_mgr60 = kzalloc(sizeof(struct dcn60_clk_mgr), GFP_KERNEL);
+ struct dcn60_clk_mgr *clk_mgr60 = kzalloc_obj(struct dcn60_clk_mgr);
struct clk_mgr_internal *clk_mgr;
if (!clk_mgr60)
@@ -1644,7 +1644,7 @@ struct clk_mgr_internal *dcn60_clk_mgr_construct(
clk_mgr->smu_present = false;
- clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL);
+ clk_mgr->base.bw_params = kzalloc_obj(*clk_mgr->base.bw_params);
if (!clk_mgr->base.bw_params)
goto fail;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 68f228014305..519ac878ada1 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -914,8 +914,7 @@ static bool dc_construct_update_scratch_pool(struct dc *dc)
unsigned int i;
for (i = 0; i < ARRAY_SIZE(dc->update_scratch_pool); i++) {
- dc->update_scratch_pool[i] = kzalloc(
- sizeof(struct dc_update_scratch_space), GFP_KERNEL);
+ dc->update_scratch_pool[i] = kzalloc_obj(struct dc_update_scratch_space);
if (!dc->update_scratch_pool[i])
return false;
dc->update_scratch_in_use[i] = false;
@@ -3199,6 +3198,7 @@ static struct dc_update_descriptor check_update_surfaces_for_stream(
}
if ((stream_update->hdr_static_metadata && !stream_update->stream->use_dynamic_meta) ||
+ stream_update->output_color_space ||
stream_update->vrr_infopacket ||
stream_update->vsc_infopacket ||
stream_update->vsp_infopacket ||
@@ -4189,6 +4189,7 @@ static void commit_planes_do_stream_update_sequence(struct dc *dc,
hwss_add_setup_periodic_interrupt(&seq_state, dc, pipe_ctx);
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
+ stream_update->output_color_space ||
stream_update->vrr_infopacket ||
stream_update->vsc_infopacket ||
stream_update->vsp_infopacket ||
@@ -4371,6 +4372,7 @@ static void commit_planes_do_stream_update(struct dc *dc,
dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
+ stream_update->output_color_space ||
stream_update->vrr_infopacket ||
stream_update->vsc_infopacket ||
stream_update->vsp_infopacket ||
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 7eaaf38cd9ab..fc9080f0c093 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -1797,7 +1797,11 @@ bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
* pipe-split, merge together per same height.
*/
for (split_pipe = pipe_ctx->top_pipe; split_pipe;
- split_pipe = split_pipe->top_pipe)
+ split_pipe = split_pipe->top_pipe) {
+
+ if (split_pipe == test_pipe)
+ continue;
+
if (split_pipe->plane_state->layer_index == test_pipe->plane_state->layer_index) {
struct rect r2_half;
@@ -1809,6 +1813,7 @@ bool resource_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
r2_bottom = min(r2_bottom, r2_half.y + r2_half.height);
break;
}
+ }
if (r1.x >= r2.x && r1.y >= r2.y && r1_right <= r2_right && r1_bottom <= r2_bottom)
return true;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
index 88e825a6582c..0b135a9e6c4f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c
@@ -290,7 +290,7 @@ static void dc_plane_cm_free(struct kref *kref)
struct dc_plane_cm *dc_plane_cm_create(void)
{
- struct dc_plane_cm *cm = kvzalloc(sizeof(*cm), GFP_KERNEL);
+ struct dc_plane_cm *cm = kvzalloc_obj(*cm);
if (cm == NULL)
goto alloc_fail;
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c
index 3b03b152da22..c2fa7fd56acf 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn42/dcn42_dccg.c
@@ -358,7 +358,7 @@ struct dccg *dccg42_create(
const struct dccg_shift *dccg_shift,
const struct dccg_mask *dccg_mask)
{
- struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
+ struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn);
struct dccg *base;
if (dccg_dcn == NULL) {
diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn60/dcn60_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn60/dcn60_dccg.c
index 8e2f88913e4c..1d6d193b23c7 100644
--- a/drivers/gpu/drm/amd/display/dc/dccg/dcn60/dcn60_dccg.c
+++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn60/dcn60_dccg.c
@@ -167,7 +167,7 @@ struct dccg *dccg60_create(
const struct dccg_shift *dccg_shift,
const struct dccg_mask *dccg_mask)
{
- struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL);
+ struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn);
struct dccg *base;
if (dccg_dcn == NULL) {
diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
index 66fe7f313ea3..62ca235cd649 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
@@ -320,6 +320,8 @@ static struct fixed31_32 interp_tf_pts(const struct fixed31_32 *output_tf_channe
return value;
}
+#define NUM_DEGAMMA_REGIONS 9
+
bool cm3_helper_translate_curve_to_degamma_hw_format(
const struct dc_transfer_func *output_tf,
struct pwl_params *lut_params)
@@ -343,31 +345,15 @@ bool cm3_helper_translate_curve_to_degamma_hw_format(
memset(lut_params, 0, sizeof(struct pwl_params));
memset(seg_distr, 0, sizeof(seg_distr));
- if (output_tf->tf == TRANSFER_FUNCTION_PQ ||
- output_tf->tf == TRANSFER_FUNCTION_SRGB) {
- /* 9 segments
- * segments are from 2^-9 to 0
- */
- const uint8_t SEG_COUNT = 9;
- seg_distr[0] = 0; // Since we only have one point in darkest region
- for (k = 1; k < SEG_COUNT; k++)
- seg_distr[k] = k - 1; // 2^(k-1) points per region; halves as k decreases
-
- region_start = -SEG_COUNT;
- region_end = 0;
- } else {
- /* 12 segments
- * segments are from 2^-12 to 2^0
- * There are less than 256 points, for optimization
- */
- const uint8_t SEG_COUNT = 12;
-
- for (i = 0; i < SEG_COUNT; i++)
- seg_distr[i] = 4;
+ /* 9 segments
+ * segments are from 2^-9 to 2^0
+ */
+ seg_distr[0] = 0; // Since we only have one point in darkest region
+ for (k = 1; k < NUM_DEGAMMA_REGIONS; k++)
+ seg_distr[k] = k - 1; // 2^(k-1) points per region; halves as k decreases
- region_start = -SEG_COUNT;
- region_end = 0;
- }
+ region_start = -NUM_DEGAMMA_REGIONS;
+ region_end = 0;
for (i = region_end - region_start; i < MAX_REGIONS_NUMBER ; i++)
seg_distr[i] = -1;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c
index 8497eaea012e..297e21e7c68d 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn5_funcs_mode_programming.c
@@ -1128,8 +1128,8 @@ static bool dcn5_mode_programming(struct dml2_core_calcs_mode_programming_ex *in
CalculateWatermarks_params->USRRetrainingSupport = &mode_lib->mp.USRRetrainingSupport;
CalculateWatermarks_params->temp_read_or_ppt_support = mode_lib->mp.temp_read_or_ppt_support;
CalculateWatermarks_params->global_temp_read_or_ppt_supported = &mode_lib->mp.global_temp_read_or_ppt_supported;
- CalculateWatermarks_params->VActiveLatencyHidingMargin = 0;
- CalculateWatermarks_params->VActiveLatencyHidingUs = 0;
+ CalculateWatermarks_params->VActiveLatencyHidingMargin = NULL;
+ CalculateWatermarks_params->VActiveLatencyHidingUs = NULL;
dcn5_calculate_watermarks_and_dram_speed_change_support(&mode_lib->scratch, CalculateWatermarks_params);
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
index 8a371bd1a7a5..28f4a53d0617 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_shared_types.h
@@ -1819,8 +1819,8 @@ struct dml2_core_calcs_CalculateWatermarksMALLUseAndDRAMSpeedChangeSupport_param
bool UnboundedRequestEnabled;
unsigned int CompressedBufferSizeInkByte;
bool max_outstanding_when_urgent_expected;
- const unsigned int max_outstanding_requests;
- const unsigned int max_request_size_bytes;
+ unsigned int max_outstanding_requests;
+ unsigned int max_request_size_bytes;
const unsigned int *meta_row_height_l;
const unsigned int *meta_row_height_c;
const enum dml2_pstate_method *uclk_pstate_switch_modes;
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c
index 0b884a8661c8..6d6611a6b5a6 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_pmo/dml2_pmo_dcn6_stage_optimizers.c
@@ -1414,7 +1414,7 @@ static bool find_shift_for_valid_cache_id_assignment(const int *mcache_boundarie
success = true;
for (pipe_index = 0; pipe_index < pipe_count; pipe_index++) {
if (!calculate_first_second_splitting(mcache_boundaries, num_boundaries, *shift,
- pipe_vp_startx[pipe_index], pipe_vp_endx[pipe_index], 0, 0)) {
+ pipe_vp_startx[pipe_index], pipe_vp_endx[pipe_index], NULL, NULL)) {
success = false;
break;
}
diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c
index 166f10b8862f..c82886323a51 100644
--- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c
+++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml2_translation_helper.c
@@ -301,6 +301,7 @@ void dml2_init_socbb_params(struct dml2_context *dml2, const struct dc *in_dc, s
out->smn_latency_us = 2;
out->dispclk_dppclk_vco_speed_mhz = 3600;
out->pct_ideal_dram_bw_after_urgent_pixel_only = 65.0;
+ out->gpuvm_min_page_size_kbytes = 4;
break;
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
index b75bfea635fd..cf9c7a2089a1 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c
@@ -542,7 +542,7 @@ void dal_hw_ddc_init_i3cpad(
*hw_ddc = NULL;
}
- *hw_ddc = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL);
+ *hw_ddc = kzalloc_obj(struct hw_ddc);
if (!*hw_ddc) {
ASSERT_CRITICAL(false);
return;
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.c b/drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.c
index f4d1ce9079de..3a87c1a26488 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn42/irq_service_dcn42.c
@@ -405,7 +405,7 @@ static void dcn42_irq_construct(struct irq_service *irq_service,
struct irq_service *dal_irq_service_dcn42_create(struct irq_service_init_data *init_data)
{
- struct irq_service *irq_service = kzalloc(sizeof(*irq_service), GFP_KERNEL);
+ struct irq_service *irq_service = kzalloc_obj(*irq_service);
if (!irq_service)
return NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn60/irq_service_dcn60.c b/drivers/gpu/drm/amd/display/dc/irq/dcn60/irq_service_dcn60.c
index 99163346e7d9..651bae6b5ede 100644
--- a/drivers/gpu/drm/amd/display/dc/irq/dcn60/irq_service_dcn60.c
+++ b/drivers/gpu/drm/amd/display/dc/irq/dcn60/irq_service_dcn60.c
@@ -406,8 +406,7 @@ static void dcn60_irq_construct(
struct irq_service *dal_irq_service_dcn60_create(
struct irq_service_init_data *init_data)
{
- struct irq_service *irq_service = kzalloc(sizeof(*irq_service),
- GFP_KERNEL);
+ struct irq_service *irq_service = kzalloc_obj(*irq_service);
if (!irq_service)
return NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
index dd854d992692..f43fc4b78a8d 100644
--- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
+++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c
@@ -103,6 +103,11 @@ static int get_estimated_bw(struct dc_link *link)
{
uint8_t bw_estimated_bw = 0;
+ if (link->dpia_bw_alloc_config.bw_granularity == 0) {
+ DC_LOG_ERROR("%s: BW granularity is zero!\n", __func__);
+ return 0;
+ }
+
core_link_read_dpcd(
link,
ESTIMATED_BW,
diff --git a/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c b/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c
index 78b33b2dbae8..2c87e33e909e 100644
--- a/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c
+++ b/drivers/gpu/drm/amd/display/dc/pg/dcn42/dcn42_pg_cntl.c
@@ -615,7 +615,7 @@ struct pg_cntl *pg_cntl42_create(
const struct pg_cntl_shift *pg_cntl_shift,
const struct pg_cntl_mask *pg_cntl_mask)
{
- struct dcn_pg_cntl *pg_cntl_dcn = kzalloc(sizeof(*pg_cntl_dcn), GFP_KERNEL);
+ struct dcn_pg_cntl *pg_cntl_dcn = kzalloc_obj(*pg_cntl_dcn);
struct pg_cntl *base;
if (pg_cntl_dcn == NULL) {
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
index dbb8bb7fc20d..aecbcd28c2d9 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c
@@ -1135,7 +1135,7 @@ static struct hpo_frl_stream_encoder *dcn30_hpo_frl_stream_encoder_create(enum e
}
/* allocate HPO stream encoder and create VPG sub-block */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn30_vpg_create(ctx, vpg_inst);
afmt = dcn30_afmt_create(ctx, afmt_inst);
@@ -1166,7 +1166,7 @@ static struct hpo_frl_link_encoder *dcn30_hpo_frl_link_encoder_create(enum engin
ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
index 88dcf8166378..f67b3e00bd86 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c
@@ -492,7 +492,7 @@ static struct hpo_frl_stream_encoder *dcn302_hpo_frl_stream_encoder_create(enum
return NULL;
/* allocate HPO stream encoder and create VPG sub-block */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn302_vpg_create(ctx, vpg_inst);
afmt = dcn302_afmt_create(ctx, afmt_inst);
@@ -531,7 +531,7 @@ static struct hpo_frl_link_encoder *dcn302_hpo_frl_link_encoder_create(enum engi
ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
index 50b7c7b85fac..9e1bf34cca2a 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c
@@ -479,7 +479,7 @@ static struct hpo_frl_stream_encoder *dcn303_hpo_frl_stream_encoder_create(enum
return NULL;
/* allocate HPO stream encoder and create VPG sub-block */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn303_vpg_create(ctx, vpg_inst);
afmt = dcn303_afmt_create(ctx, afmt_inst);
@@ -518,7 +518,7 @@ static struct hpo_frl_link_encoder *dcn303_hpo_frl_link_encoder_create(enum engi
ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
index db56e30cf259..6359fbb574df 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c
@@ -1346,7 +1346,7 @@ static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum e
}
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn31_vpg_create(ctx, vpg_inst);
afmt = dcn31_afmt_create(ctx, afmt_inst);
@@ -1377,7 +1377,7 @@ static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engin
ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
index 63f92e9da6d8..0ddfceca69dd 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c
@@ -1404,7 +1404,7 @@ static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum e
}
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn31_vpg_create(ctx, vpg_inst);
afmt = dcn31_afmt_create(ctx, afmt_inst);
@@ -1436,7 +1436,7 @@ static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engin
ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
index 15c1615c5f45..a1894be8cbb2 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c
@@ -1347,7 +1347,7 @@ static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum e
}
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn31_vpg_create(ctx, vpg_inst);
afmt = dcn31_afmt_create(ctx, afmt_inst);
@@ -1379,7 +1379,7 @@ static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engin
ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
index a5ea35e45791..4a2d56a196b4 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c
@@ -1340,7 +1340,7 @@ static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(enum e
}
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn31_vpg_create(ctx, vpg_inst);
afmt = dcn31_afmt_create(ctx, afmt_inst);
@@ -1372,7 +1372,7 @@ static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(enum engin
ASSERT((eng_id == ENGINE_ID_HPO_0) || (eng_id == ENGINE_ID_HPO_1));
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
index 7c2a79015f4e..a2e66761b8ec 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c
@@ -1339,7 +1339,7 @@ static struct hpo_frl_stream_encoder *dcn32_hpo_frl_stream_encoder_create(enum e
}
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn32_vpg_create(ctx, vpg_inst);
afmt = dcn32_afmt_create(ctx, afmt_inst);
@@ -1375,7 +1375,7 @@ static struct hpo_frl_link_encoder *dcn32_hpo_frl_link_encoder_create(enum engin
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
index 5ee9a5a8ec3c..4097093d9012 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c
@@ -1314,7 +1314,7 @@ static struct hpo_frl_stream_encoder *dcn321_hpo_frl_stream_encoder_create(enum
}
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn321_vpg_create(ctx, vpg_inst);
afmt = dcn321_afmt_create(ctx, afmt_inst);
@@ -1350,7 +1350,7 @@ static struct hpo_frl_link_encoder *dcn321_hpo_frl_link_encoder_create(enum engi
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
index 52826e96c184..fd7a22fcca59 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c
@@ -1398,7 +1398,7 @@ static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(
return NULL;
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn31_vpg_create(ctx, vpg_inst);
afmt = dcn31_afmt_create(ctx, afmt_inst);
@@ -1430,7 +1430,7 @@ static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
index e3fc71307c91..83248ee01d11 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c
@@ -1378,7 +1378,7 @@ static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(
return NULL;
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn31_vpg_create(ctx, vpg_inst);
afmt = dcn31_afmt_create(ctx, afmt_inst);
@@ -1410,7 +1410,7 @@ static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c
index c019a657005d..8d1baa76c347 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c
@@ -1385,7 +1385,7 @@ static struct hpo_frl_stream_encoder *dcn31_hpo_frl_stream_encoder_create(
return NULL;
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_stream_encoder);
vpg = dcn31_vpg_create(ctx, vpg_inst);
afmt = dcn31_afmt_create(ctx, afmt_inst);
@@ -1417,7 +1417,7 @@ static struct hpo_frl_link_encoder *dcn31_hpo_frl_link_encoder_create(
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_enc3 = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_enc3 = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_enc3)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
index aced8ff657bf..0cfdca82bef0 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c
@@ -1322,7 +1322,7 @@ static struct hpo_frl_stream_encoder *dcn401_hpo_frl_stream_encoder_create(
return NULL;
/* allocate HPO stream encoder and create VPG, AFMT sub-blocks */
- hpo_enc401 = kzalloc(sizeof(struct dcn401_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc401 = kzalloc_obj(struct dcn401_hpo_frl_stream_encoder);
vpg = dcn401_vpg_create(ctx, vpg_inst);
afmt = dcn401_afmt_create(ctx, afmt_inst);
@@ -1353,7 +1353,7 @@ static struct hpo_frl_link_encoder *dcn401_hpo_frl_link_encoder_create(
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_link_enc = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_link_enc = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_link_enc)
return NULL; /* out of memory */
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
index 6370d3903eb5..28192d6dda7a 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn42/dcn42_resource.c
@@ -818,7 +818,7 @@ static struct dce_aux *dcn42_aux_engine_create(
uint32_t inst)
{
struct aux_engine_dce110 *aux_engine =
- kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
+ kzalloc_obj(struct aux_engine_dce110);
if (!aux_engine)
return NULL;
@@ -884,7 +884,7 @@ static struct dce_i2c_hw *dcn42_i2c_hw_create(
uint32_t inst)
{
struct dce_i2c_hw *dce_i2c_hw =
- kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
+ kzalloc_obj(struct dce_i2c_hw);
if (!dce_i2c_hw)
return NULL;
@@ -910,7 +910,7 @@ static struct clock_source *dcn42_clock_source_create(
bool dp_clk_src)
{
struct dce110_clk_src *clk_src =
- kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
+ kzalloc_obj(struct dce110_clk_src);
if (!clk_src)
return NULL;
@@ -929,8 +929,7 @@ static struct hubbub *dcn42_hubbub_create(struct dc_context *ctx)
{
int i;
- struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub),
- GFP_KERNEL);
+ struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub);
if (!hubbub3)
return NULL;
@@ -983,7 +982,7 @@ static struct hubp *dcn42_hubp_create(
uint32_t inst)
{
struct dcn20_hubp *hubp2 =
- kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_hubp);
if (!hubp2)
return NULL;
@@ -1025,7 +1024,7 @@ static struct dpp *dcn42_dpp_create(
uint32_t inst)
{
struct dcn42_dpp *dpp42 =
- kzalloc(sizeof(struct dcn42_dpp), GFP_KERNEL);
+ kzalloc_obj(struct dcn42_dpp);
if (!dpp42)
return NULL;
@@ -1051,8 +1050,7 @@ static struct mpc *dcn42_mpc_create(
int num_mpcc,
int num_rmu)
{
- struct dcn42_mpc *mpc401 = kzalloc(sizeof(struct dcn42_mpc),
- GFP_KERNEL);
+ struct dcn42_mpc *mpc401 = kzalloc_obj(struct dcn42_mpc);
if (!mpc401)
return NULL;
@@ -1075,7 +1073,7 @@ static struct output_pixel_processor *dcn42_opp_create(
struct dc_context *ctx, uint32_t inst)
{
struct dcn20_opp *opp4 =
- kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_opp);
if (!opp4) {
BREAK_TO_DEBUGGER();
@@ -1098,7 +1096,7 @@ static struct timing_generator *dcn42_timing_generator_create(
uint32_t instance)
{
struct optc *tgn10 =
- kzalloc(sizeof(struct optc), GFP_KERNEL);
+ kzalloc_obj(struct optc);
if (!tgn10)
return NULL;
@@ -1136,7 +1134,7 @@ static struct link_encoder *dcn42_link_encoder_create(
const struct encoder_init_data *enc_init_data)
{
struct dcn20_link_encoder *enc20 =
- kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_link_encoder);
if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
return NULL;
@@ -1202,7 +1200,7 @@ static struct vpg *dcn42_vpg_create(
struct dc_context *ctx,
uint32_t inst)
{
- struct dcn31_vpg *vpg4 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
+ struct dcn31_vpg *vpg4 = kzalloc_obj(struct dcn31_vpg);
if (!vpg4)
return NULL;
@@ -1231,7 +1229,7 @@ static struct apg *dcn42_apg_create(
struct dc_context *ctx,
uint32_t inst)
{
- struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
+ struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg);
if (!apg31)
return NULL;
@@ -1275,7 +1273,7 @@ static struct stream_encoder *dcn42_stream_encoder_create(
} else
return NULL;
- enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ enc1 = kzalloc_obj(struct dcn10_stream_encoder);
vpg = dcn42_vpg_create(ctx, vpg_inst);
apg = dcn42_apg_create(ctx, apg_inst);
@@ -1325,7 +1323,7 @@ static struct hpo_frl_stream_encoder *dcn42_hpo_frl_stream_encoder_create(
return NULL;
/* allocate HPO stream encoder and create VPG sub-block */
- hpo_enc42 = kzalloc(sizeof(struct dcn42_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc42 = kzalloc_obj(struct dcn42_hpo_frl_stream_encoder);
vpg = dcn42_vpg_create(ctx, vpg_inst);
apg = dcn42_apg_create(ctx, apg_inst);
@@ -1357,7 +1355,7 @@ static struct hpo_frl_link_encoder *dcn42_hpo_frl_link_encoder_create(
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_link_enc = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_link_enc = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_link_enc)
return NULL; /* out of memory */
@@ -1399,7 +1397,7 @@ static struct hpo_dp_stream_encoder *dcn42_hpo_dp_stream_encoder_create(
apg_inst = hpo_dp_inst + 5;
/* allocate HPO stream encoder and create VPG sub-block */
- hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
+ hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder);
vpg = dcn42_vpg_create(ctx, vpg_inst);
apg = dcn42_apg_create(ctx, apg_inst);
@@ -1432,7 +1430,7 @@ static struct hpo_dp_link_encoder *dcn42_hpo_dp_link_encoder_create(
struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
/* allocate HPO link encoder */
- hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+ hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder);
if (!hpo_dp_enc31)
return NULL; /* out of memory */
@@ -1453,7 +1451,7 @@ static struct hpo_dp_link_encoder *dcn42_hpo_dp_link_encoder_create(
static struct dce_hwseq *dcn42_hwseq_create(
struct dc_context *ctx)
{
- struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
+ struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq);
#undef REG_STRUCT
#define REG_STRUCT hwseq_reg
@@ -1727,8 +1725,7 @@ static bool dcn42_dwbc_create(struct dc_context *ctx, struct resource_pool *pool
uint32_t dwb_count = pool->res_cap->num_dwb;
for (i = 0; i < dwb_count; i++) {
- struct dcn30_dwbc *dwbc42 = kzalloc(sizeof(struct dcn30_dwbc),
- GFP_KERNEL);
+ struct dcn30_dwbc *dwbc42 = kzalloc_obj(struct dcn30_dwbc);
if (!dwbc42) {
dm_error("DC: failed to create dwbc42!\n");
@@ -1764,8 +1761,7 @@ static bool dcn42_mmhubbub_create(struct dc_context *ctx, struct resource_pool *
uint32_t pipe_count = pool->res_cap->num_dwb;
for (i = 0; i < pipe_count; i++) {
- struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
- GFP_KERNEL);
+ struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub);
if (!mcif_wb30) {
dm_error("DC: failed to create mcif_wb30!\n");
@@ -1793,7 +1789,7 @@ static struct display_stream_compressor *dcn42_dsc_create(
struct dc_context *ctx, uint32_t inst)
{
struct dcn401_dsc *dsc =
- kzalloc(sizeof(struct dcn401_dsc), GFP_KERNEL);
+ kzalloc_obj(struct dcn401_dsc);
if (!dsc) {
BREAK_TO_DEBUGGER();
@@ -1890,7 +1886,7 @@ static struct link_encoder *dcn42_link_enc_create_minimal(
if ((unsigned int)(eng_id - ENGINE_ID_DIGA) >= ctx->dc->res_pool->res_cap->num_dig_link_enc)
return NULL;
- enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+ enc20 = kzalloc_obj(struct dcn20_link_encoder);
if (!enc20)
return NULL;
@@ -2441,7 +2437,7 @@ struct resource_pool *dcn42_create_resource_pool(
struct dc *dc)
{
struct dcn42_resource_pool *pool =
- kzalloc(sizeof(struct dcn401_resource_pool), GFP_KERNEL);
+ kzalloc_obj(struct dcn42_resource_pool);
if (!pool)
return NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn42b/dcn42b_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn42b/dcn42b_resource.c
index 41f0c67f57ff..f36d0f828166 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn42b/dcn42b_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn42b/dcn42b_resource.c
@@ -870,7 +870,7 @@ static struct dce_aux *dcn42b_aux_engine_create(
uint32_t inst)
{
struct aux_engine_dce110 *aux_engine =
- kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
+ kzalloc_obj(struct aux_engine_dce110);
if (!aux_engine)
return NULL;
@@ -940,7 +940,7 @@ static struct dce_i2c_hw *dcn42b_i2c_hw_create(
uint32_t inst)
{
struct dce_i2c_hw *dce_i2c_hw =
- kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
+ kzalloc_obj(struct dce_i2c_hw);
if (!dce_i2c_hw)
return NULL;
@@ -968,7 +968,7 @@ static struct clock_source *dcn42b_clock_source_create(
bool dp_clk_src)
{
struct dce110_clk_src *clk_src =
- kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
+ kzalloc_obj(struct dce110_clk_src);
if (!clk_src)
return NULL;
@@ -988,8 +988,7 @@ static struct hubbub *dcn42b_hubbub_create(struct dc_context *ctx)
{
int i;
- struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub),
- GFP_KERNEL);
+ struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub);
if (!hubbub3)
return NULL;
@@ -1042,7 +1041,7 @@ static struct hubp *dcn42b_hubp_create(
uint32_t inst)
{
struct dcn20_hubp *hubp2 =
- kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_hubp);
if (!hubp2)
return NULL;
@@ -1084,7 +1083,7 @@ static struct dpp *dcn42b_dpp_create(
uint32_t inst)
{
struct dcn42_dpp *dpp42b =
- kzalloc(sizeof(struct dcn42_dpp), GFP_KERNEL);
+ kzalloc_obj(struct dcn42_dpp);
if (!dpp42b)
return NULL;
@@ -1110,8 +1109,7 @@ static struct mpc *dcn42b_mpc_create(
int num_mpcc,
int num_rmu)
{
- struct dcn42_mpc *mpc42b = kzalloc(sizeof(struct dcn42_mpc),
- GFP_KERNEL);
+ struct dcn42_mpc *mpc42b = kzalloc_obj(struct dcn42_mpc);
if (!mpc42b)
return NULL;
@@ -1134,7 +1132,7 @@ static struct output_pixel_processor *dcn42b_opp_create(
struct dc_context *ctx, uint32_t inst)
{
struct dcn20_opp *opp4 =
- kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_opp);
if (!opp4) {
BREAK_TO_DEBUGGER();
@@ -1158,7 +1156,7 @@ static struct timing_generator *dcn42b_timing_generator_create(
uint32_t instance)
{
struct optc *tgn10 =
- kzalloc(sizeof(struct optc), GFP_KERNEL);
+ kzalloc_obj(struct optc);
if (!tgn10)
return NULL;
@@ -1196,7 +1194,7 @@ static struct link_encoder *dcn42b_link_encoder_create(
const struct encoder_init_data *enc_init_data)
{
struct dcn20_link_encoder *enc20 =
- kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_link_encoder);
if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs))
return NULL;
@@ -1271,7 +1269,7 @@ static struct vpg *dcn42b_vpg_create(
struct dc_context *ctx,
uint32_t inst)
{
- struct dcn31_vpg *vpg4 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
+ struct dcn31_vpg *vpg4 = kzalloc_obj(struct dcn31_vpg);
if (!vpg4)
return NULL;
@@ -1300,7 +1298,7 @@ static struct apg *dcn42b_apg_create(
struct dc_context *ctx,
uint32_t inst)
{
- struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
+ struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg);
if (!apg31)
return NULL;
@@ -1344,7 +1342,7 @@ static struct stream_encoder *dcn42b_stream_encoder_create(
} else
return NULL;
- enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ enc1 = kzalloc_obj(struct dcn10_stream_encoder);
vpg = dcn42b_vpg_create(ctx, vpg_inst);
apg = dcn42b_apg_create(ctx, apg_inst);
@@ -1404,7 +1402,7 @@ static struct hpo_dp_stream_encoder *dcn42b_hpo_dp_stream_encoder_create(
apg_inst = hpo_dp_inst + 6;
/* allocate HPO stream encoder and create VPG sub-block */
- hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
+ hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder);
vpg = dcn42b_vpg_create(ctx, vpg_inst);
apg = dcn42b_apg_create(ctx, apg_inst);
@@ -1437,7 +1435,7 @@ static struct hpo_dp_link_encoder *dcn42b_hpo_dp_link_encoder_create(
struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31;
/* allocate HPO link encoder */
- hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+ hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder);
if (!hpo_dp_enc31)
return NULL; /* out of memory */
@@ -1457,7 +1455,7 @@ static struct hpo_dp_link_encoder *dcn42b_hpo_dp_link_encoder_create(
static struct dce_hwseq *dcn42b_hwseq_create(
struct dc_context *ctx)
{
- struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
+ struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq);
#undef REG_STRUCT
#define REG_STRUCT hwseq_reg
@@ -1716,8 +1714,7 @@ static bool dcn42b_dwbc_create(struct dc_context *ctx, struct resource_pool *poo
uint32_t dwb_count = pool->res_cap->num_dwb;
for (i = 0; i < dwb_count; i++) {
- struct dcn30_dwbc *dwbc42 = kzalloc(sizeof(struct dcn30_dwbc),
- GFP_KERNEL);
+ struct dcn30_dwbc *dwbc42 = kzalloc_obj(struct dcn30_dwbc);
if (!dwbc42) {
dm_error("DC: failed to create dwbc42!\n");
@@ -1753,8 +1750,7 @@ static bool dcn42b_mmhubbub_create(struct dc_context *ctx, struct resource_pool
uint32_t pipe_count = pool->res_cap->num_dwb;
for (i = 0; i < pipe_count; i++) {
- struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub),
- GFP_KERNEL);
+ struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub);
if (!mcif_wb30) {
dm_error("DC: failed to create mcif_wb30!\n");
@@ -1782,7 +1778,7 @@ static struct display_stream_compressor *dcn42b_dsc_create(
struct dc_context *ctx, uint32_t inst)
{
struct dcn401_dsc *dsc =
- kzalloc(sizeof(struct dcn401_dsc), GFP_KERNEL);
+ kzalloc_obj(struct dcn401_dsc);
if (!dsc) {
BREAK_TO_DEBUGGER();
@@ -1875,7 +1871,7 @@ static struct link_encoder *dcn42b_link_enc_create_minimal(
if ((unsigned int)(eng_id - ENGINE_ID_DIGA) >= ctx->dc->res_pool->res_cap->num_dig_link_enc)
return NULL;
- enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+ enc20 = kzalloc_obj(struct dcn20_link_encoder);
if (!enc20)
return NULL;
@@ -2439,7 +2435,7 @@ struct resource_pool *dcn42b_create_resource_pool(
struct dc *dc)
{
struct dcn42b_resource_pool *pool =
- kzalloc(sizeof(struct dcn42b_resource_pool), GFP_KERNEL);
+ kzalloc_obj(struct dcn42b_resource_pool);
if (!pool)
return NULL;
diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
index 4b7668abf4dc..d091ea55cb5d 100644
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/resource/dcn60/dcn60_resource.c
@@ -998,7 +998,7 @@ static struct dce_aux *dcn60_aux_engine_create(
uint32_t inst)
{
struct aux_engine_dce110 *aux_engine =
- kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL);
+ kzalloc_obj(struct aux_engine_dce110);
if (!aux_engine)
return NULL;
@@ -1037,7 +1037,7 @@ static struct dce_i2c_hw *dcn60_i2c_hw_create(
uint32_t inst)
{
struct dce_i2c_hw *dce_i2c_hw =
- kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL);
+ kzalloc_obj(struct dce_i2c_hw);
if (!dce_i2c_hw)
return NULL;
@@ -1061,7 +1061,7 @@ static struct clock_source *dcn60_clock_source_create(
bool dp_clk_src)
{
struct dce110_clk_src *clk_src =
- kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL);
+ kzalloc_obj(struct dce110_clk_src);
if (!clk_src)
return NULL;
@@ -1081,8 +1081,7 @@ static struct hubbub *dcn60_hubbub_create(struct dc_context *ctx)
{
int i;
- struct dcn20_hubbub *hubbub2 = kzalloc(sizeof(struct dcn20_hubbub),
- GFP_KERNEL);
+ struct dcn20_hubbub *hubbub2 = kzalloc_obj(struct dcn20_hubbub);
if (!hubbub2)
return NULL;
@@ -1136,7 +1135,7 @@ static struct hubp *dcn60_hubp_create(
uint32_t inst)
{
struct dcn20_hubp *hubp2 =
- kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_hubp);
if (!hubp2)
return NULL;
@@ -1168,7 +1167,7 @@ static struct dpp *dcn60_dpp_create(
uint32_t inst)
{
struct dcn60_dpp *dpp60 =
- kzalloc(sizeof(struct dcn60_dpp), GFP_KERNEL);
+ kzalloc_obj(struct dcn60_dpp);
if (!dpp60)
return NULL;
@@ -1194,8 +1193,7 @@ static struct mpc *dcn60_mpc_create(
int num_mpcc,
int num_rmu)
{
- struct dcn60_mpc *mpc60 = kzalloc(sizeof(struct dcn60_mpc),
- GFP_KERNEL);
+ struct dcn60_mpc *mpc60 = kzalloc_obj(struct dcn60_mpc);
if (!mpc60)
return NULL;
@@ -1218,7 +1216,7 @@ static struct output_pixel_processor *dcn60_opp_create(
struct dc_context *ctx, uint32_t inst)
{
struct dcn20_opp *opp2 =
- kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_opp);
if (!opp2) {
BREAK_TO_DEBUGGER();
@@ -1242,7 +1240,7 @@ static struct timing_generator *dcn60_timing_generator_create(
uint32_t instance)
{
struct optc *tgn10 =
- kzalloc(sizeof(struct optc), GFP_KERNEL);
+ kzalloc_obj(struct optc);
if (!tgn10)
return NULL;
@@ -1282,7 +1280,7 @@ static struct link_encoder *dcn60_link_encoder_create(
const struct encoder_init_data *enc_init_data)
{
struct dcn20_link_encoder *enc20 =
- kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL);
+ kzalloc_obj(struct dcn20_link_encoder);
if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) {
kfree(enc20);
@@ -1349,7 +1347,7 @@ static struct vpg *dcn60_vpg_create(
struct dc_context *ctx,
uint32_t inst)
{
- struct dcn31_vpg *vpg6 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL);
+ struct dcn31_vpg *vpg6 = kzalloc_obj(struct dcn31_vpg);
if (!vpg6)
return NULL;
@@ -1378,7 +1376,7 @@ static struct apg *dcn60_apg_create(
struct dc_context *ctx,
uint32_t inst)
{
- struct dcn31_apg *apg60 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL);
+ struct dcn31_apg *apg60 = kzalloc_obj(struct dcn31_apg);
if (!apg60)
return NULL;
@@ -1415,7 +1413,7 @@ static struct stream_encoder *dcn60_stream_encoder_create(
} else
return NULL;
- enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL);
+ enc1 = kzalloc_obj(struct dcn10_stream_encoder);
vpg = dcn60_vpg_create(ctx, vpg_inst);
apg = dcn60_apg_create(ctx, apg_inst);
@@ -1462,7 +1460,7 @@ static struct hpo_frl_stream_encoder *dcn60_hpo_frl_stream_encoder_create(
return NULL;
/* allocate HPO stream encoder and create VPG, APG sub-blocks */
- hpo_enc60 = kzalloc(sizeof(struct dcn401_hpo_frl_stream_encoder), GFP_KERNEL);
+ hpo_enc60 = kzalloc_obj(struct dcn401_hpo_frl_stream_encoder);
vpg = dcn60_vpg_create(ctx, vpg_inst);
apg = dcn60_apg_create(ctx, apg_inst);
@@ -1493,7 +1491,7 @@ static struct hpo_frl_link_encoder *dcn60_hpo_frl_link_encoder_create(
hpo_frl_link_encoder_reg_list(0);
/* allocate HPO link encoder */
- hpo_link_enc = kzalloc(sizeof(struct dcn30_hpo_frl_link_encoder), GFP_KERNEL);
+ hpo_link_enc = kzalloc_obj(struct dcn30_hpo_frl_link_encoder);
if (!hpo_link_enc)
return NULL; /* out of memory */
@@ -1535,7 +1533,7 @@ static struct hpo_dp_stream_encoder *dcn60_hpo_dp_stream_encoder_create(
apg_inst = hpo_dp_inst;
/* allocate HPO stream encoder and create VPG sub-block */
- hpo_dp_enc60 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL);
+ hpo_dp_enc60 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder);
vpg = dcn60_vpg_create(ctx, vpg_inst);
apg = dcn60_apg_create(ctx, apg_inst);
@@ -1568,7 +1566,7 @@ static struct hpo_dp_link_encoder *dcn60_hpo_dp_link_encoder_create(
struct dcn31_hpo_dp_link_encoder *hpo_dp_enc60;
/* allocate HPO link encoder */
- hpo_dp_enc60 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL);
+ hpo_dp_enc60 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder);
if (!hpo_dp_enc60)
return NULL; /* out of memory */
@@ -1589,7 +1587,7 @@ static struct hpo_dp_link_encoder *dcn60_hpo_dp_link_encoder_create(
static struct dce_hwseq *dcn60_hwseq_create(
struct dc_context *ctx)
{
- struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL);
+ struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq);
#undef REG_STRUCT
#define REG_STRUCT hwseq_reg
@@ -1784,7 +1782,7 @@ static struct display_stream_compressor *dcn60_dsc_create(
struct dc_context *ctx, uint32_t inst)
{
struct dcn60_dsc *dsc =
- kzalloc(sizeof(struct dcn60_dsc), GFP_KERNEL);
+ kzalloc_obj(struct dcn60_dsc);
if (!dsc) {
BREAK_TO_DEBUGGER();
@@ -2363,7 +2361,7 @@ struct resource_pool *dcn60_create_resource_pool(
struct dc *dc)
{
struct dcn60_resource_pool *pool =
- kzalloc(sizeof(struct dcn60_resource_pool), GFP_KERNEL);
+ kzalloc_obj(struct dcn60_resource_pool);
if (!pool)
return NULL;
diff --git a/drivers/gpu/drm/amd/display/modules/power/power.c b/drivers/gpu/drm/amd/display/modules/power/power.c
index ee15c14a899e..2f9690e65ca9 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power.c
@@ -111,7 +111,7 @@ struct mod_power *mod_power_create(struct dc *dc,
if (dc == NULL)
goto fail_dc_null;
- core_power = kzalloc(sizeof(struct core_power), GFP_KERNEL);
+ core_power = kzalloc_obj(struct core_power);
if (core_power == NULL)
goto fail_alloc_context;
@@ -129,8 +129,7 @@ struct mod_power *mod_power_create(struct dc *dc,
for (i = 0; i < MOD_POWER_MAX_CONCURRENT_STREAMS; i++) {
core_power->map[i].psr_context =
- kzalloc(sizeof(struct mod_power_psr_context),
- GFP_KERNEL);
+ kzalloc_obj(struct mod_power_psr_context);
if (core_power->map[i].psr_context == NULL)
goto fail_construct;
}
diff --git a/drivers/gpu/drm/amd/display/modules/power/power_abm.c b/drivers/gpu/drm/amd/display/modules/power/power_abm.c
index 5e86889eaa84..5f27dea4aa0a 100644
--- a/drivers/gpu/drm/amd/display/modules/power/power_abm.c
+++ b/drivers/gpu/drm/amd/display/modules/power/power_abm.c
@@ -705,8 +705,7 @@ void initialize_backlight_caps(struct core_power *core_power, unsigned int inst)
* (do not want to use 256 bytes on the stack)
*/
ext_backlight_caps = (struct dm_acpi_atif_backlight_caps *)
- (kzalloc(sizeof(struct dm_acpi_atif_backlight_caps),
- GFP_KERNEL));
+ (kzalloc_obj(struct dm_acpi_atif_backlight_caps));
if (ext_backlight_caps == NULL)
return;
diff --git a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
index ce526db4d24a..808be6c425bf 100644
--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
@@ -348,7 +348,8 @@ int amdgpu_dpm_switch_power_profile(struct amdgpu_device *adev,
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret = 0;
- if (amdgpu_sriov_vf(adev))
+ if (amdgpu_sriov_vf(adev) ||
+ amdgpu_in_reset(adev))
return 0;
if (pp_funcs && pp_funcs->switch_power_profile) {
@@ -367,7 +368,8 @@ int amdgpu_dpm_pause_power_profile(struct amdgpu_device *adev,
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret = 0;
- if (amdgpu_sriov_vf(adev))
+ if (amdgpu_sriov_vf(adev) ||
+ amdgpu_in_reset(adev))
return 0;
if (pp_funcs && pp_funcs->pause_power_profile) {
diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
index 2393fa8d4e4b..bdf1e489369e 100644
--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
+++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c
@@ -2988,7 +2988,7 @@ static int smu7_init_voltage_dependency_on_display_clock_table(struct pp_hwmgr *
if (!amdgpu_device_ip_get_ip_block(hwmgr->adev, AMD_IP_BLOCK_TYPE_DCE))
return 0;
- table = kzalloc(struct_size(table, entries, 4), GFP_KERNEL);
+ table = kzalloc_flex(*table, entries, 4);
if (!table)
return -ENOMEM;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index 6e741ec4a71e..a29e76b03476 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2092,11 +2092,11 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu,
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
- if ((mp1_ver == IP_VERSION(13, 0, 0) && smu->smc_fw_version <= 0x004e1e00) ||
- (mp1_ver == IP_VERSION(13, 0, 10) && smu->smc_fw_version <= 0x00500800))
+ if ((mp1_ver == IP_VERSION(13, 0, 0) &&
+ (smu->smc_fw_version <= 0x004e1e00 || smu->smc_fw_version >= 0x004e8600)) ||
+ (mp1_ver == IP_VERSION(13, 0, 10) &&
+ smu->smc_fw_version <= 0x00500800))
gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
- else
- gpu_metrics->energy_accumulator = UINT_MAX;
if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD)
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
index b94ae43586df..5fe409a23772 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -2097,8 +2097,8 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu,
metrics->Vcn1ActivityPercentage);
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
- gpu_metrics->energy_accumulator = smu->smc_fw_version <= 0x00521400 ?
- metrics->EnergyAccumulator : UINT_MAX;
+ if (smu->smc_fw_version <= 0x00521400)
+ gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
if (metrics->AverageGfxActivity <= SMU_13_0_7_BUSY_THRESHOLD)
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
index aa4daf8f7d6f..4f820db5f8dd 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c
@@ -222,7 +222,7 @@ static int smu_v15_0_8_tables_init(struct smu_context *smu)
smu_table->metrics_time = 0;
- driver_pptable = kzalloc(sizeof(PPTable_t), GFP_KERNEL);
+ driver_pptable = kzalloc_obj(PPTable_t);
if (!driver_pptable)
return -ENOMEM;
@@ -1026,7 +1026,7 @@ static int smu_v15_0_8_fru_get_product_info(struct smu_context *smu,
struct amdgpu_device *adev = smu->adev;
if (!adev->fru_info) {
- adev->fru_info = kzalloc(sizeof(*adev->fru_info), GFP_KERNEL);
+ adev->fru_info = kzalloc_obj(*adev->fru_info);
if (!adev->fru_info)
return -ENOMEM;
}
diff --git a/drivers/gpu/drm/amd/ras/core/cmd.c b/drivers/gpu/drm/amd/ras/core/cmd.c
index 6c37dc519eed..446b935c1fc9 100644
--- a/drivers/gpu/drm/amd/ras/core/cmd.c
+++ b/drivers/gpu/drm/amd/ras/core/cmd.c
@@ -222,7 +222,7 @@ static int ras_cmd_get_cper_records(struct ras_core_context *ras_core,
if (!buffer)
return RAS_CMD__ERROR_GENERIC;
- trace = kcalloc(trace_count, sizeof(*trace), GFP_KERNEL);
+ trace = kzalloc_objs(*trace, trace_count);
if (!trace) {
ret = RAS_CMD__ERROR_GENERIC;
goto out;
@@ -316,7 +316,7 @@ static int ras_cmd_get_batch_trace_records(struct ras_core_context *ras_core,
(input_data->start_batch_id >= overview.last_batch_id))
return RAS_CMD__ERROR_INVALID_INPUT_SIZE;
- trace_arry = kcalloc(trace_count, sizeof(*trace_arry), GFP_KERNEL);
+ trace_arry = kzalloc_objs(*trace_arry, trace_count);
if (!trace_arry)
return RAS_CMD__ERROR_GENERIC;
diff --git a/drivers/gpu/drm/ast/ast_cursor.c b/drivers/gpu/drm/ast/ast_cursor.c
index fd19c45f2abe..690d4cd1db5e 100644
--- a/drivers/gpu/drm/ast/ast_cursor.c
+++ b/drivers/gpu/drm/ast/ast_cursor.c
@@ -25,6 +25,7 @@
#include <linux/sizes.h>
#include <drm/drm_atomic.h>
+#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_format_helper.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -355,6 +356,8 @@ int ast_cursor_plane_init(struct ast_device *ast)
}
drm_plane_helper_add(cursor_plane, &ast_cursor_plane_helper_funcs);
drm_plane_enable_fb_damage_clips(cursor_plane);
+ drm_plane_create_blend_mode_property(cursor_plane,
+ BIT(DRM_MODE_BLEND_COVERAGE));
return 0;
}
diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c
index d1fc6af37cc5..19b43efcf93f 100644
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -1263,10 +1263,13 @@ tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
return input_fmts;
}
-static bool tc358768_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static int tc358768_bridge_atomic_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
+ struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+
/* Default to positive sync */
if (!(adjusted_mode->flags &
@@ -1277,13 +1280,15 @@ static bool tc358768_mode_fixup(struct drm_bridge *bridge,
(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
- return true;
+ bridge_state->input_bus_cfg.flags = bridge->timings->input_bus_flags;
+
+ return 0;
}
static const struct drm_bridge_funcs tc358768_bridge_funcs = {
.attach = tc358768_bridge_attach,
.mode_valid = tc358768_bridge_mode_valid,
- .mode_fixup = tc358768_mode_fixup,
+ .atomic_check = tc358768_bridge_atomic_check,
.atomic_pre_enable = tc358768_bridge_atomic_pre_enable,
.atomic_enable = tc358768_bridge_atomic_enable,
.atomic_disable = tc358768_bridge_atomic_disable,
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
index f9fdbf48c6b3..526826ba4524 100644
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -403,7 +403,7 @@ retry:
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
- return 0;
+ return err;
}
static void sn65dsi83_reset_work(struct work_struct *ws)
@@ -419,11 +419,13 @@ static void sn65dsi83_reset_work(struct work_struct *ws)
ret = sn65dsi83_reset_pipe(ctx);
if (ret) {
dev_err(ctx->dev, "reset pipe failed %pe\n", ERR_PTR(ret));
- return;
+ goto bridge_exit;
}
+
if (ctx->irq)
enable_irq(ctx->irq);
+bridge_exit:
drm_bridge_exit(idx);
}
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c
index d90d1d7c9cf9..a2ef272e9f27 100644
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
@@ -278,7 +278,14 @@ void __drm_atomic_helper_plane_state_init(struct drm_plane_state *plane_state,
plane_state->rotation = DRM_MODE_ROTATE_0;
plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
+
plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
+ if (plane->blend_mode_property) {
+ if (!drm_object_property_get_default_value(&plane->base,
+ plane->blend_mode_property,
+ &val))
+ plane_state->pixel_blend_mode = val;
+ }
if (plane->color_encoding_property) {
if (!drm_object_property_get_default_value(&plane->base,
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 1050dddadb17..5ea593b3a98e 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1449,9 +1449,6 @@ static int prepare_signaling(struct drm_device *dev,
if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
struct drm_pending_vblank_event *e = crtc_state->event;
- if (!file_priv)
- continue;
-
ret = drm_event_reserve_init(dev, file_priv, &e->base,
&e->event.base);
if (ret) {
@@ -1567,6 +1564,8 @@ static void complete_signaling(struct drm_device *dev,
* to prevent a double free in drm_atomic_commit_clear.
*/
if (event && (event->base.fence || event->base.file_priv)) {
+ if (crtc_state->commit && crtc_state->commit->abort_completion)
+ drm_crtc_commit_put(crtc_state->commit);
drm_event_cancel_free(dev, &event->base);
crtc_state->event = NULL;
}
diff --git a/drivers/gpu/drm/drm_exec.c b/drivers/gpu/drm/drm_exec.c
index fa923852fae4..2453ec41360f 100644
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -79,7 +79,7 @@ void drm_exec_init(struct drm_exec *exec, u32 flags, unsigned nr)
nr = PAGE_SIZE / sizeof(void *);
exec->flags = flags;
- exec->objects = kvmalloc_objs(*exec->objects, nr, GFP_KERNEL);
+ exec->objects = kvmalloc_objs(*exec->objects, nr);
/* If allocation here fails, just delay that till the first use */
exec->max_objects = exec->objects ? nr : 0;
@@ -322,6 +322,19 @@ int drm_exec_prepare_array(struct drm_exec *exec,
{
int ret;
+ /*
+ * Make sure to lock a contended object even when no objects are
+ * given, otherwise drm_exec_retry_on_contention() would loop
+ * forever on patterns like:
+ *
+ * ret = drm_exec_prepare_array(exec, objs, num_objects, ...);
+ * drm_exec_retry_on_contention(exec);
+ *
+ * with num_objects == 0.
+ */
+ if (!num_objects)
+ return drm_exec_lock_contended(exec);
+
for (unsigned int i = 0; i < num_objects; ++i) {
ret = drm_exec_prepare_obj(exec, objects[i], num_fences);
if (unlikely(ret))
diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index 892b325fa99b..a0546955d0b9 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -384,6 +384,58 @@ next:
}
/**
+ * drm_pagemap_migrate_populate_src_pages() - Populate the source page array
+ * @pages: Array of source pages to populate
+ * @src_mpfn: Source array of migrate PFNs
+ * @dst_mpfn: Destination array of migrate PFNs
+ * @npages: Number of pages in the arrays
+ *
+ * Populate @pages with the device pages the copy callback is to read from.
+ *
+ * Entries are normally only populated at the head of each source folio, with
+ * the copy callback deriving the rest of the folio from the order recorded in
+ * the corresponding drm_pagemap_addr. That does not work where
+ * drm_pagemap_migrate_populate_ram_pfn() had to demote a higher-order source
+ * folio to order-0 destination folios: the drm_pagemap_addr entries are then
+ * per-page, and the copy callback needs a source page for each of them.
+ * Populate every entry for those ranges.
+ *
+ * Note that the source folio itself is only split later, by
+ * migrate_vma_pages() / migrate_device_pages(), so its order cannot be used to
+ * detect the demotion - the destination has to be inspected instead.
+ */
+static void drm_pagemap_migrate_populate_src_pages(struct page **pages,
+ unsigned long *src_mpfn,
+ unsigned long *dst_mpfn,
+ unsigned long npages)
+{
+ unsigned long i;
+
+ for (i = 0; i < npages;) {
+ struct page *page = migrate_pfn_to_page(src_mpfn[i]);
+ unsigned int order = 0;
+ unsigned long j, nr;
+
+ if (!page) {
+ i++;
+ continue;
+ }
+
+ order = folio_order(page_folio(page));
+ nr = NR_PAGES(order);
+
+ if (order && !(dst_mpfn[i] & MIGRATE_PFN_COMPOUND)) {
+ for (j = 0; j < nr && i + j < npages; j++)
+ pages[i + j] = folio_page(page_folio(page), j);
+ } else {
+ pages[i] = page;
+ }
+
+ i += nr;
+ }
+}
+
+/**
* drm_pagemap_migrate_unmap_pages() - Unmap pages previously mapped for GPU SVM migration
* @dev: The device for which the pages were mapped
* @migrate_pfn: Array of migrate pfns set up for the mapped pages. Used to
@@ -875,6 +927,7 @@ static int drm_pagemap_migrate_populate_ram_pfn(struct vm_area_struct *vas,
struct page *page = NULL, *src_page;
struct folio *folio;
unsigned int order = 0;
+ gfp_t gfp = GFP_HIGHUSER;
if (!(src_mpfn[i] & MIGRATE_PFN_MIGRATE))
goto next;
@@ -891,11 +944,51 @@ static int drm_pagemap_migrate_populate_ram_pfn(struct vm_area_struct *vas,
order = folio_order(page_folio(src_page));
- /* TODO: Support fallback to single pages if THP allocation fails */
+ /*
+ * A large source folio is always collected whole, at its head
+ * page, PMD aligned and flagged MIGRATE_PFN_COMPOUND: anything
+ * else is split before it reaches us, either by
+ * migrate_vma_collect_pmd() or, for the eviction path, by
+ * migrate_device_pfns(). Both the order-0 fallback below and
+ * drm_pagemap_migrate_populate_src_pages() rely on that, as
+ * they index the folio from @i.
+ */
+ WARN_ON_ONCE(order &&
+ (src_page != folio_page(page_folio(src_page), 0) ||
+ !(src_mpfn[i] & MIGRATE_PFN_COMPOUND)));
+
+ if (order)
+ gfp |= __GFP_NOWARN;
+
if (vas)
- folio = vma_alloc_folio(GFP_HIGHUSER, order, vas, addr);
+ folio = vma_alloc_folio(gfp, order, vas, addr);
else
- folio = folio_alloc(GFP_HIGHUSER, order);
+ folio = folio_alloc(gfp, order);
+
+ if (!folio && order) {
+ /*
+ * Higher-order allocation failed, fall back to
+ * order-0 allocations for the entire range covered
+ * by the original higher-order allocation, without
+ * setting MIGRATE_PFN_COMPOUND, until we move past
+ * that range.
+ */
+ unsigned long nr = NR_PAGES(order);
+ unsigned long j;
+
+ gfp &= ~__GFP_NOWARN;
+ for (j = 0; j < nr && i < npages; j++, i++, addr += PAGE_SIZE) {
+ folio = vas ?
+ vma_alloc_folio(gfp, 0, vas, addr) :
+ folio_alloc(gfp, 0);
+ if (!folio)
+ goto free_pages;
+
+ page = folio_page(folio, 0);
+ mpfn[i] = migrate_pfn(page_to_pfn(page));
+ }
+ continue;
+ }
if (!folio)
goto free_pages;
@@ -940,11 +1033,11 @@ free_pages:
if (!page)
goto next_put;
+ order = folio_order(page_folio(page));
+
put_page(page);
mpfn[i] = 0;
- order = folio_order(page_folio(page));
-
next_put:
i += NR_PAGES(order);
}
@@ -1103,11 +1196,116 @@ void drm_pagemap_put(struct drm_pagemap *dpagemap)
EXPORT_SYMBOL(drm_pagemap_put);
/**
+ * drm_pagemap_page_get_flags() - Read flags from a device-private folio
+ * @page: Pointer to a page of the device-private folio
+ *
+ * Return: The DRM_PAGEMAP_ZDD_FLAG_* bits encoded in zone_device_data.
+ */
+static unsigned long drm_pagemap_page_get_flags(struct page *page)
+{
+ struct folio *folio = page_folio(page);
+
+ return (unsigned long)folio_zone_device_data(folio) &
+ DRM_PAGEMAP_ZDD_FLAG_MASK;
+}
+
+/**
+ * drm_pagemap_page_set_flags() - Set flags on a device-private folio
+ * @page: Pointer to a page of the device-private folio
+ * @flags: DRM_PAGEMAP_ZDD_FLAG_* bits to set
+ *
+ * Preserve any flags already encoded alongside the ZDD pointer.
+ */
+static void drm_pagemap_page_set_flags(struct page *page,
+ unsigned long flags)
+{
+ struct folio *folio = page_folio(page);
+ unsigned long old;
+
+ if (WARN_ON_ONCE(flags & ~DRM_PAGEMAP_ZDD_FLAG_MASK))
+ return;
+
+ old = (unsigned long)folio_zone_device_data(folio);
+ folio_set_zone_device_data(folio, (void *)(old | flags));
+}
+
+/**
+ * drm_pagemap_retire_migrated_pages() - Record migrated device-private folios
+ * @src_pfns: source array after migrate_vma_pages() or migrate_device_pages()
+ * @npages: number of entries in @src_pfns
+ *
+ * Flag device-private folios successfully migrated to RAM before finalize
+ * unlocks the sources. The migrated state is stored in the physical folio, so
+ * it survives later folio splits and subsequent migrations can skip it.
+ */
+static void drm_pagemap_retire_migrated_pages(unsigned long *src_pfns,
+ unsigned long npages)
+{
+ unsigned long i = 0;
+
+ while (i < npages) {
+ struct page *page = migrate_pfn_to_page(src_pfns[i]);
+ unsigned long nr = 1;
+
+ if (!page) {
+ i++;
+ continue;
+ }
+
+ if (src_pfns[i] & MIGRATE_PFN_COMPOUND)
+ nr = folio_nr_pages(page_folio(page));
+
+ if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
+ is_device_private_page(page))
+ drm_pagemap_page_set_flags(page,
+ DRM_PAGEMAP_ZDD_FLAG_MIGRATED);
+
+ i += nr;
+ }
+}
+
+/**
+ * drm_pagemap_skip_retired_pages() - Skip retired device-private folios
+ * @src_pfns: MIGRATE_PFN-encoded source array
+ * @npages: number of entries in @src_pfns
+ *
+ * Skip source folios already migrated to RAM, identified by the migrated flag
+ * stored in the physical folio's zone_device_data.
+ */
+static void drm_pagemap_skip_retired_pages(unsigned long *src_pfns,
+ unsigned long npages)
+{
+ unsigned long i = 0;
+
+ while (i < npages) {
+ struct page *page = migrate_pfn_to_page(src_pfns[i]);
+ unsigned long nr = 1;
+
+ if (!page) {
+ i++;
+ continue;
+ }
+
+ if (src_pfns[i] & MIGRATE_PFN_COMPOUND)
+ nr = folio_nr_pages(page_folio(page));
+
+ if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
+ is_device_private_page(page) &&
+ (drm_pagemap_page_get_flags(page) &
+ DRM_PAGEMAP_ZDD_FLAG_MIGRATED))
+ src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
+
+ i += nr;
+ }
+}
+
+/**
* drm_pagemap_evict_to_ram() - Evict GPU SVM range to RAM
* @devmem_allocation: Pointer to the device memory allocation
*
- * Similar to __drm_pagemap_migrate_to_ram but does not require mmap lock and
- * migration done via migrate_device_* functions.
+ * Similar to __drm_pagemap_migrate_to_ram(), but uses the
+ * migrate_device_* helpers and does not require the mmap lock.
+ * Device-private PFNs already migrated to RAM by either path are skipped.
*
* Return: 0 on success, negative error code on failure.
*/
@@ -1115,17 +1313,18 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
{
const struct drm_pagemap_devmem_ops *ops = devmem_allocation->ops;
struct drm_pagemap_iova_state state = {};
- unsigned long npages, mpages = 0;
+ unsigned long npages, mpages;
struct page **pages;
unsigned long *src, *dst;
struct drm_pagemap_addr *pagemap_addr;
void *buf;
- int i, err = 0;
+ int err = 0;
unsigned int retry_count = 2;
npages = devmem_allocation->size >> PAGE_SHIFT;
retry:
+ mpages = 0;
if (!mmget_not_zero(devmem_allocation->mm))
return -EFAULT;
@@ -1148,6 +1347,8 @@ retry:
if (err)
goto err_free;
+ drm_pagemap_skip_retired_pages(src, npages);
+
err = drm_pagemap_migrate_populate_ram_pfn(NULL, NULL, npages, &mpages,
src, dst, 0);
if (err || !mpages)
@@ -1160,27 +1361,20 @@ retry:
if (err)
goto err_finalize;
- for (i = 0; i < npages;) {
- unsigned int order = 0;
-
- pages[i] = migrate_pfn_to_page(src[i]);
- if (pages[i])
- order = folio_order(page_folio(pages[i]));
-
- i += NR_PAGES(order);
- }
+ drm_pagemap_migrate_populate_src_pages(pages, src, dst, npages);
err = ops->copy_to_ram(pages, pagemap_addr, npages, NULL);
if (err)
goto err_finalize;
err_finalize:
+ drm_pagemap_migrate_unmap_pages(devmem_allocation->dev, pagemap_addr, dst, npages,
+ DMA_FROM_DEVICE, &state);
if (err)
drm_pagemap_migration_unlock_put_pages(npages, dst);
migrate_device_pages(src, dst, npages);
+ drm_pagemap_retire_migrated_pages(src, npages);
migrate_device_finalize(src, dst, npages);
- drm_pagemap_migrate_unmap_pages(devmem_allocation->dev, pagemap_addr, dst, npages,
- DMA_FROM_DEVICE, &state);
err_free:
kvfree(buf);
@@ -1235,7 +1429,7 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
struct drm_pagemap_addr *pagemap_addr;
unsigned long start, end;
void *buf;
- int i, err = 0;
+ int err = 0;
zdd = drm_pagemap_page_zone_device_data(page);
if (time_before64(get_jiffies_64(), zdd->devmem_allocation->timeslice_expiration))
@@ -1275,13 +1469,15 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
if (!migrate.cpages)
goto err_free;
+ drm_pagemap_skip_retired_pages(migrate.src, npages);
+
ops = zdd->devmem_allocation->ops;
dev = zdd->devmem_allocation->dev;
err = drm_pagemap_migrate_populate_ram_pfn(vas, page, npages, &mpages,
migrate.src, migrate.dst,
start);
- if (err)
+ if (err || !mpages)
goto err_finalize;
err = drm_pagemap_migrate_map_system_pages(dev, pagemap_addr,
@@ -1290,29 +1486,23 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
if (err)
goto err_finalize;
- for (i = 0; i < npages;) {
- unsigned int order = 0;
-
- pages[i] = migrate_pfn_to_page(migrate.src[i]);
- if (pages[i])
- order = folio_order(page_folio(pages[i]));
-
- i += NR_PAGES(order);
- }
+ drm_pagemap_migrate_populate_src_pages(pages, migrate.src, migrate.dst,
+ npages);
err = ops->copy_to_ram(pages, pagemap_addr, npages, NULL);
if (err)
goto err_finalize;
err_finalize:
- if (err)
- drm_pagemap_migration_unlock_put_pages(npages, migrate.dst);
- migrate_vma_pages(&migrate);
- migrate_vma_finalize(&migrate);
if (dev)
drm_pagemap_migrate_unmap_pages(dev, pagemap_addr, migrate.dst,
npages, DMA_FROM_DEVICE,
&state);
+ if (err)
+ drm_pagemap_migration_unlock_put_pages(npages, migrate.dst);
+ migrate_vma_pages(&migrate);
+ drm_pagemap_retire_migrated_pages(migrate.src, npages);
+ migrate_vma_finalize(&migrate);
err_free:
kvfree(buf);
err_out:
@@ -1360,13 +1550,19 @@ static vm_fault_t drm_pagemap_migrate_to_ram(struct vm_fault *vmf)
static void drm_pagemap_folio_split(struct folio *orig_folio, struct folio *new_folio)
{
struct drm_pagemap_zdd *zdd;
+ unsigned long orig_data, new_data;
if (!new_folio)
return;
new_folio->pgmap = orig_folio->pgmap;
- zdd = folio_zone_device_data(orig_folio);
- folio_set_zone_device_data(new_folio, drm_pagemap_zdd_get(zdd));
+
+ orig_data = (unsigned long)folio_zone_device_data(orig_folio);
+ zdd = (struct drm_pagemap_zdd *)(orig_data & ~DRM_PAGEMAP_ZDD_FLAG_MASK);
+
+ new_data = (unsigned long)drm_pagemap_zdd_get(zdd);
+ new_data |= orig_data & DRM_PAGEMAP_ZDD_FLAG_MASK;
+ folio_set_zone_device_data(new_folio, (void *)new_data);
}
static const struct dev_pagemap_ops drm_pagemap_pagemap_ops = {
diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_qr.rs
index ac27e86c601c..4d7eb75a3afc 100644
--- a/drivers/gpu/drm/drm_panic_qr.rs
+++ b/drivers/gpu/drm/drm_panic_qr.rs
@@ -407,8 +407,8 @@ impl DecFifo {
for i in (0..self.len).rev() {
self.decimals[i + len] = self.decimals[i];
}
- for i in 0..len {
- self.decimals[i] = (chunk % 10) as u8;
+ for decimal in &mut self.decimals[..len] {
+ *decimal = (chunk % 10) as u8;
chunk = div10(chunk);
}
self.len += len;
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 9b44c78cd77f..fe3436d1235d 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -524,7 +524,7 @@ int drm_gem_prime_handle_to_fd(struct drm_device *dev,
return PTR_ERR(dmabuf);
}
- fd_install(fd, dmabuf->file);
+ dma_buf_fd_install(dmabuf, fd);
*prime_fd = fd;
return 0;
}
diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c
index 2fa170a29a62..c23a5de27eff 100644
--- a/drivers/gpu/drm/drm_syncobj.c
+++ b/drivers/gpu/drm/drm_syncobj.c
@@ -1619,7 +1619,7 @@ drm_syncobj_timeline_signal_ioctl(struct drm_device *dev, void *data,
goto err_points;
}
- chains = kmalloc_objs(*chains, args->count_handles, GFP_KERNEL);
+ chains = kmalloc_objs(*chains, args->count_handles);
if (!chains) {
ret = -ENOMEM;
goto err_points;
diff --git a/drivers/gpu/drm/gud/gud_connector.c b/drivers/gpu/drm/gud/gud_connector.c
index ea0cca58b7c8..8141c3a1e30a 100644
--- a/drivers/gpu/drm/gud/gud_connector.c
+++ b/drivers/gpu/drm/gud/gud_connector.c
@@ -396,8 +396,16 @@ static int gud_connector_add_tv_mode(struct gud_device *gdrm, struct drm_connect
}
num_modes = ret / GUD_CONNECTOR_TV_MODE_NAME_LEN;
- for (i = 0; i < num_modes; i++)
- modes[i] = &buf[i * GUD_CONNECTOR_TV_MODE_NAME_LEN];
+ for (i = 0; i < num_modes; i++) {
+ char *mode = &buf[i * GUD_CONNECTOR_TV_MODE_NAME_LEN];
+
+ if (!memchr(mode, '\0', GUD_CONNECTOR_TV_MODE_NAME_LEN)) {
+ ret = -EIO;
+ goto free;
+ }
+
+ modes[i] = mode;
+ }
ret = drm_mode_create_tv_properties_legacy(connector->dev, num_modes, modes);
free:
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
index 89bd6ca36003..3a1b9e2a2eaa 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -289,6 +289,8 @@ static int gud_plane_add_properties(struct gud_device *gdrm)
* but mask out any additions on future devices.
*/
val &= GUD_ROTATION_MASK;
+ if (!(val & GUD_ROTATION_0))
+ continue;
ret = drm_plane_create_rotation_property(&gdrm->plane,
DRM_MODE_ROTATE_0, val);
break;
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index a53d88727177..a1a5720996b7 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2381,8 +2381,10 @@ static void bxt_sanitize_cdclk(struct intel_display *display)
* dividers both syncing to an active pipe, or asynchronously
* (PIPE_NONE).
*/
- cdctl &= ~bxt_cdclk_cd2x_pipe_mask(display);
- cdctl |= bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
+ if (DISPLAY_VER(display) < 30) {
+ cdctl &= ~bxt_cdclk_cd2x_pipe_mask(display);
+ cdctl |= bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
+ }
if (cdctl != expected) {
if (DISPLAY_VER(display) < 20) {
@@ -2713,8 +2715,8 @@ static void intel_set_cdclk(struct intel_display *display,
}
}
-static bool dg2_power_well_count(struct intel_display *display,
- const struct intel_cdclk_state *cdclk_state)
+static int dg2_power_well_count(struct intel_display *display,
+ const struct intel_cdclk_state *cdclk_state)
{
return display->platform.dg2 ? hweight8(cdclk_state->active_pipes) : 0;
}
diff --git a/drivers/gpu/drm/i915/display/intel_cursor.c b/drivers/gpu/drm/i915/display/intel_cursor.c
index 0673f16f6fd0..86bb96ac449b 100644
--- a/drivers/gpu/drm/i915/display/intel_cursor.c
+++ b/drivers/gpu/drm/i915/display/intel_cursor.c
@@ -530,13 +530,18 @@ static int i9xx_check_cursor(struct intel_crtc_state *crtc_state,
}
static void i9xx_cursor_disable_sel_fetch_arm(struct intel_dsb *dsb,
- struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state)
+ struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
enum pipe pipe = plane->pipe;
- if (!crtc_state->enable_psr2_sel_fetch)
+ /*
+ * Clear this whenever the hardware has selective fetch, not just when
+ * the current state uses it. The cursor may have been enabled with
+ * selective fetch earlier and had its enable bit orphaned when the
+ * feature was switched off.
+ */
+ if (!HAS_PSR2_SEL_FETCH(display))
return;
intel_de_write_dsb(display, dsb, SEL_FETCH_CUR_CTL(pipe), 0);
@@ -586,7 +591,7 @@ static void i9xx_cursor_update_sel_fetch_arm(struct intel_dsb *dsb,
if (crtc_state->enable_psr2_su_region_et)
wa_16021440873(dsb, plane, crtc_state, plane_state);
else
- i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
+ i9xx_cursor_disable_sel_fetch_arm(dsb, plane);
}
}
@@ -695,7 +700,7 @@ static void i9xx_cursor_update_arm(struct intel_dsb *dsb,
if (plane_state)
i9xx_cursor_update_sel_fetch_arm(dsb, plane, crtc_state, plane_state);
else
- i9xx_cursor_disable_sel_fetch_arm(dsb, plane, crtc_state);
+ i9xx_cursor_disable_sel_fetch_arm(dsb, plane);
if (plane->cursor.base != base ||
plane->cursor.size != fbc_ctl ||
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index 452062417ce9..dbebd7210848 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -3233,7 +3233,8 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
* 8. Program DDI_CLK_VALFREQ to match intended DDI
* clock frequency.
*/
- intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
+ intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
+ intel_ddi_link_symbol_clock(encoder, port_clock));
/*
* 9. Set PORT_CLOCK_CTL register PCLK PLL Request
@@ -3406,7 +3407,7 @@ void intel_mtl_tbt_pll_enable_clock(struct intel_encoder *encoder, int port_cloc
* clock frequency.
*/
intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
- port_clock);
+ intel_ddi_link_symbol_clock(encoder, port_clock));
}
void intel_mtl_pll_enable(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index b8985e1e0a81..02a53c9848e1 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -1529,6 +1529,17 @@ int intel_ddi_level(struct intel_encoder *encoder,
return level;
}
+int intel_ddi_link_symbol_clock(struct intel_encoder *encoder, int clock)
+{
+ if (intel_encoder_is_dp(encoder))
+ return intel_dp_link_symbol_clock(clock);
+
+ if (intel_hdmi_is_frl(clock))
+ return DIV_ROUND_CLOSEST(clock * 10, 18);
+
+ return clock;
+}
+
static void
hsw_set_signal_levels(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.h b/drivers/gpu/drm/i915/display/intel_ddi.h
index 580ecb09b8b6..239d5a403f91 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.h
+++ b/drivers/gpu/drm/i915/display/intel_ddi.h
@@ -81,6 +81,7 @@ void intel_ddi_sanitize_encoder_pll_mapping(struct intel_encoder *encoder);
int intel_ddi_level(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
int lane);
+int intel_ddi_link_symbol_clock(struct intel_encoder *encoder, int clock);
void intel_ddi_update_active_dpll(struct intel_atomic_state *state,
struct intel_encoder *encoder,
struct intel_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index b7cc361fd955..43d53a98dae7 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1946,6 +1946,8 @@ struct intel_dp {
bool colorimetry_support;
+ bool sst_split_sdp_support;
+
struct {
enum transcoder transcoder;
struct mutex lock;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 113d767e62e9..3152122e6aef 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3409,12 +3409,22 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state)
{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
pipe_config->has_audio =
intel_dp_has_audio(encoder, conn_state) &&
intel_audio_compute_config(encoder, pipe_config, conn_state);
pipe_config->sdp_split_enable = pipe_config->has_audio &&
intel_dp_is_uhbr(pipe_config);
+
+ /*
+ * SDP splitting for UHBR audio requires explicit sink capability in
+ * SST mode, whereas in MST mode it is inherently supported.
+ */
+ if (pipe_config->sdp_split_enable &&
+ !intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST))
+ pipe_config->sdp_split_enable = intel_dp->sst_split_sdp_support;
}
void
@@ -4462,16 +4472,25 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
str_enable_disable(tmp));
}
-static bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
+static u8 intel_dp_read_dprx_feature_enum(struct intel_dp *intel_dp)
{
u8 dprx = 0;
- if (drm_dp_dpcd_readb(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
- &dprx) != 1)
- return false;
+ drm_dp_dpcd_read_data(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
+ &dprx, sizeof(dprx));
+ return dprx;
+}
+
+static bool intel_dp_get_colorimetry_status(u8 dprx)
+{
return dprx & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED;
}
+static bool intel_dp_get_sst_split_sdp_status(u8 dprx)
+{
+ return dprx & DP_SST_SPLIT_SDP_CAP;
+}
+
static int intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
{
@@ -4771,6 +4790,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
{
struct intel_display *display = to_intel_display(intel_dp);
int ret;
+ u8 dprx;
/* this function is meant to be called only once */
drm_WARN_ON(display->drm, intel_dp->dpcd[DP_DPCD_REV] != 0);
@@ -4782,8 +4802,13 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
drm_dp_is_branch(intel_dp->dpcd));
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
+ dprx = intel_dp_read_dprx_feature_enum(intel_dp);
+
intel_dp->colorimetry_support =
- intel_dp_get_colorimetry_status(intel_dp);
+ intel_dp_get_colorimetry_status(dprx);
+
+ intel_dp->sst_split_sdp_support =
+ intel_dp_get_sst_split_sdp_status(dprx);
/*
* Read the eDP display control registers.
@@ -4874,13 +4899,20 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
* the OUI/ID since we know it won't change.
*/
if (!intel_dp_is_edp(intel_dp)) {
+ u8 dprx;
+
drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
drm_dp_is_branch(intel_dp->dpcd));
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
+ dprx = intel_dp_read_dprx_feature_enum(intel_dp);
+
intel_dp->colorimetry_support =
- intel_dp_get_colorimetry_status(intel_dp);
+ intel_dp_get_colorimetry_status(dprx);
+
+ intel_dp->sst_split_sdp_support =
+ intel_dp_get_sst_split_sdp_status(dprx);
intel_dp_update_sink_caps(intel_dp);
}
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 3be1643f8d03..57daed0b0b36 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -765,10 +765,6 @@ static int mst_stream_compute_config(struct intel_atomic_state *state,
if (ret)
return ret;
- ret = intel_pfit_compute_config(pipe_config, conn_state);
- if (ret)
- return ret;
-
for_each_joiner_candidate(connector, adjusted_mode, num_joined_pipes) {
if (num_joined_pipes > 1)
pipe_config->joiner_pipes = GENMASK(crtc->pipe + num_joined_pipes - 1,
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c
index 8fc6d230493f..86492651b01d 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c
@@ -1976,7 +1976,8 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
* Change. We handle this step in bxt_set_cdclk().
*/
/* 10. Program DDI_CLK_VALFREQ to match intended DDI clock frequency. */
- intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
+ intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
+ intel_ddi_link_symbol_clock(encoder, port_clock));
/* 11. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 1. */
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, port),
@@ -2023,7 +2024,8 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
lane_phy_pulse_status,
lane_phy_pulse_status);
} else {
- intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
+ intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
+ intel_ddi_link_symbol_clock(encoder, port_clock));
}
/*
diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c
index 07a683293352..5cda1ab90e40 100644
--- a/drivers/gpu/drm/i915/display/skl_universal_plane.c
+++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c
@@ -879,13 +879,18 @@ skl_plane_disable_arm(struct intel_dsb *dsb,
}
static void icl_plane_disable_sel_fetch_arm(struct intel_dsb *dsb,
- struct intel_plane *plane,
- const struct intel_crtc_state *crtc_state)
+ struct intel_plane *plane)
{
struct intel_display *display = to_intel_display(plane);
enum pipe pipe = plane->pipe;
- if (!crtc_state->enable_psr2_sel_fetch)
+ /*
+ * Clear this whenever the hardware has selective fetch, not just when
+ * the current state uses it. The plane may have been enabled with
+ * selective fetch earlier and had its enable bit orphaned when the
+ * feature was switched off.
+ */
+ if (!HAS_PSR2_SEL_FETCH(display))
return;
intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id), 0);
@@ -921,7 +926,7 @@ icl_plane_disable_arm(struct intel_dsb *dsb,
skl_write_plane_wm(dsb, plane, crtc_state);
- icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
+ icl_plane_disable_sel_fetch_arm(dsb, plane);
if (plane_has_normalizer(plane))
intel_de_write_dsb(display, dsb,
@@ -1641,7 +1646,7 @@ static void icl_plane_update_sel_fetch_arm(struct intel_dsb *dsb,
intel_de_write_dsb(display, dsb, SEL_FETCH_PLANE_CTL(pipe, plane->id),
SEL_FETCH_PLANE_CTL_ENABLE);
else
- icl_plane_disable_sel_fetch_arm(dsb, plane, crtc_state);
+ icl_plane_disable_sel_fetch_arm(dsb, plane);
}
static void
diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c
index 82415af47d54..2f03f95945f1 100644
--- a/drivers/gpu/drm/i915/i915_pci.c
+++ b/drivers/gpu/drm/i915/i915_pci.c
@@ -958,6 +958,9 @@ static int i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
(struct intel_device_info *) ent->driver_data;
int err;
+ if (!intel_info)
+ return -ENODEV;
+
if (intel_info->require_force_probe && !id_forced(pdev->device)) {
dev_info(&pdev->dev,
"Your graphics device %04x is not properly supported by i915 in this\n"
diff --git a/drivers/gpu/drm/i915/i915_query.c b/drivers/gpu/drm/i915/i915_query.c
index 0c55fb6e9727..11157fb14db3 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -403,8 +403,10 @@ static int query_perf_config_list(struct drm_i915_private *i915,
ids = krealloc(oa_config_ids,
n_configs * sizeof(*oa_config_ids),
GFP_KERNEL);
- if (!ids)
+ if (!ids) {
+ kfree(oa_config_ids);
return -ENOMEM;
+ }
alloc = fetch_and_zero(&n_configs);
diff --git a/drivers/gpu/drm/logicvc/Kconfig b/drivers/gpu/drm/logicvc/Kconfig
index 579a358ed5cf..11aae1626199 100644
--- a/drivers/gpu/drm/logicvc/Kconfig
+++ b/drivers/gpu/drm/logicvc/Kconfig
@@ -4,7 +4,6 @@ config DRM_LOGICVC
depends on OF || COMPILE_TEST
select DRM_CLIENT_SELECTION
select DRM_KMS_HELPER
- select DRM_KMS_DMA_HELPER
select DRM_GEM_DMA_HELPER
select REGMAP
select REGMAP_MMIO
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
index 7903d7470d19..01145db32c53 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/disp.h
@@ -87,4 +87,5 @@ int gp102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int gv100_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int tu102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
int ga102_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
+int gb202_disp_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_disp **);
#endif
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index 598513f60449..f142f6310596 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -90,6 +90,14 @@ nouveau_channel_del(struct nouveau_channel **pchan)
{
struct nouveau_channel *chan = *pchan;
if (chan) {
+ /*
+ * Drop the kill-event subscription first. Its handler
+ * dereferences chan->fence, which the fence context teardown
+ * below frees, so leaving it armed across the teardown leaves
+ * a window for a use-after-free.
+ */
+ nvif_event_dtor(&chan->kill);
+
if (chan->fence)
nouveau_fence(chan->cli->drm)->context_del(chan);
@@ -100,7 +108,6 @@ nouveau_channel_del(struct nouveau_channel **pchan)
nvif_object_dtor(&chan->nvsw);
nvif_object_dtor(&chan->gart);
nvif_object_dtor(&chan->vram);
- nvif_event_dtor(&chan->kill);
nvif_object_dtor(&chan->user);
nvif_mem_dtor(&chan->mem_userd);
nouveau_vma_del(&chan->sema.vma);
diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c
index 9442ec6e1f6c..ad4570c50be7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dmem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c
@@ -267,7 +267,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf)
nouveau_fence_new(&fence, dmem->migrate.chan);
migrate_vma_pages(&args);
nouveau_dmem_fence_done(&fence);
- dma_unmap_page(drm->dev->dev, dma_info.dma_addr, PAGE_SIZE,
+ dma_unmap_page(drm->dev->dev, dma_info.dma_addr, dma_info.size,
DMA_BIDIRECTIONAL);
done:
migrate_vma_finalize(&args);
@@ -279,11 +279,25 @@ err:
static void nouveau_dmem_folio_split(struct folio *head, struct folio *tail)
{
+ struct nouveau_dmem_chunk *chunk;
+ struct nouveau_dmem *dmem;
+
if (tail == NULL)
return;
tail->pgmap = head->pgmap;
tail->mapping = head->mapping;
folio_set_zone_device_data(tail, folio_zone_device_data(head));
+
+ /*
+ * The split hands out a new independently-freeable folio that will
+ * later be released via nouveau_dmem_folio_free(); account for it so
+ * chunk->callocated stays balanced.
+ */
+ chunk = nouveau_page_to_chunk(&head->page);
+ dmem = chunk->drm->dmem;
+ spin_lock(&dmem->lock);
+ chunk->callocated++;
+ spin_unlock(&dmem->lock);
}
static const struct dev_pagemap_ops nouveau_dmem_pagemap_ops = {
@@ -772,7 +786,7 @@ static unsigned long nouveau_dmem_migrate_copy_one(struct nouveau_drm *drm,
return mpfn;
out_dma_unmap:
- dma_unmap_page(dev, dma_info->dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+ dma_unmap_page(dev, dma_info->dma_addr, dma_info->size, DMA_BIDIRECTIONAL);
out_free_page:
nouveau_dmem_page_free_locked(drm, dpage);
out:
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
index fa3b4ebf38a8..2bd0376193ae 100644
--- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c
@@ -72,9 +72,7 @@ nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo, uint32_t page_flags)
struct nouveau_sgdma_be *nvbe;
enum ttm_caching caching;
- if (nvbo->force_coherent)
- caching = ttm_uncached;
- else if (drm->agp.bridge)
+ if (nvbo->force_coherent || drm->agp.bridge)
caching = ttm_write_combined;
else
caching = ttm_cached;
diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
index f5e4756b4de4..fc125fd44a9b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c
@@ -1319,6 +1319,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job,
op->va.range);
if (!op->reg || op->reg->dirty) {
ret = -ENOENT;
+ op->reg = NULL;
goto unwind_continue;
}
@@ -1327,6 +1328,7 @@ nouveau_uvmm_bind_job_submit(struct nouveau_job *job,
op->va.range);
if (IS_ERR(op->ops)) {
ret = PTR_ERR(op->ops);
+ op->reg = NULL;
goto unwind_continue;
}
@@ -1473,6 +1475,7 @@ unwind:
op->va.range);
break;
case OP_UNMAP_SPARSE:
+ op->reg->dirty = false;
__nouveau_uvma_region_insert(uvmm, op->reg);
nouveau_uvmm_sm_unmap_prepare_unwind(uvmm, &op->new,
op->ops);
@@ -1489,7 +1492,8 @@ unwind:
break;
}
- drm_gpuva_ops_free(&uvmm->base, op->ops);
+ if (!IS_ERR_OR_NULL(op->ops))
+ drm_gpuva_ops_free(&uvmm->base, op->ops);
op->ops = NULL;
op->reg = NULL;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index ea62dc97f118..96c8a5b29999 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -2846,7 +2846,7 @@ nv1b2_chipset = {
.pci = { 0x00000001, gh100_pci_new },
.timer = { 0x00000001, gk20a_timer_new },
.vfn = { 0x00000001, ga100_vfn_new },
- .disp = { 0x00000001, ga102_disp_new },
+ .disp = { 0x00000001, gb202_disp_new },
.fifo = { 0x00000001, ga102_fifo_new },
};
@@ -2862,7 +2862,7 @@ nv1b3_chipset = {
.pci = { 0x00000001, gh100_pci_new },
.timer = { 0x00000001, gk20a_timer_new },
.vfn = { 0x00000001, ga100_vfn_new },
- .disp = { 0x00000001, ga102_disp_new },
+ .disp = { 0x00000001, gb202_disp_new },
.fifo = { 0x00000001, ga102_fifo_new },
};
@@ -2878,7 +2878,7 @@ nv1b5_chipset = {
.pci = { 0x00000001, gh100_pci_new },
.timer = { 0x00000001, gk20a_timer_new },
.vfn = { 0x00000001, ga100_vfn_new },
- .disp = { 0x00000001, ga102_disp_new },
+ .disp = { 0x00000001, gb202_disp_new },
.fifo = { 0x00000001, ga102_fifo_new },
};
@@ -2894,7 +2894,7 @@ nv1b6_chipset = {
.pci = { 0x00000001, gh100_pci_new },
.timer = { 0x00000001, gk20a_timer_new },
.vfn = { 0x00000001, ga100_vfn_new },
- .disp = { 0x00000001, ga102_disp_new },
+ .disp = { 0x00000001, gb202_disp_new },
.fifo = { 0x00000001, ga102_fifo_new },
};
@@ -2910,7 +2910,7 @@ nv1b7_chipset = {
.pci = { 0x00000001, gh100_pci_new },
.timer = { 0x00000001, gk20a_timer_new },
.vfn = { 0x00000001, ga100_vfn_new },
- .disp = { 0x00000001, ga102_disp_new },
+ .disp = { 0x00000001, gb202_disp_new },
.fifo = { 0x00000001, ga102_fifo_new },
};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
index e1aecd3fe96c..98d6ca5ac311 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
@@ -27,6 +27,7 @@ nvkm-y += nvkm/engine/disp/gp102.o
nvkm-y += nvkm/engine/disp/gv100.o
nvkm-y += nvkm/engine/disp/tu102.o
nvkm-y += nvkm/engine/disp/ga102.o
+nvkm-y += nvkm/engine/disp/gb202.o
nvkm-y += nvkm/engine/disp/udisp.o
nvkm-y += nvkm/engine/disp/uconn.o
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c
index ab0a85c92430..820834b5ee9b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ga102.c
@@ -144,12 +144,23 @@ ga102_disp = {
},
};
+static const struct nvkm_disp_func
+ga102_gsp_disp = {
+ .uevent = &gv100_disp_chan_uevent,
+ .ramht_size = 0x2000,
+ .gsp.intr = tu102_disp_intr,
+ .gsp.head = &tu102_gsp_head,
+ .gsp.hdmi_gcp = tu102_sor_hdmi_gcp,
+ .gsp.hdmi_infoframe_avi = gv100_sor_hdmi_infoframe_avi,
+ .gsp.hdmi_infoframe_vsi = gv100_sor_hdmi_infoframe_vsi,
+};
+
int
ga102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_disp **pdisp)
{
if (nvkm_gsp_rm(device->gsp))
- return r535_disp_new(&ga102_disp, device, type, inst, pdisp);
+ return r535_disp_new(&ga102_gsp_disp, device, type, inst, pdisp);
return nvkm_disp_new_(&ga102_disp, device, type, inst, pdisp);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c
new file mode 100644
index 000000000000..d0360610f9fa
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gb202.c
@@ -0,0 +1,191 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2026 Valve Corp.
+ */
+#include "priv.h"
+#include "head.h"
+#include "ior.h"
+
+#include <subdev/timer.h>
+
+/* GB20x (NVD5.0) reorganised the SF HDMI packet units. The AVI unit is
+ * unchanged from GV100, but the legacy VSI unit is gone. Vendor infoframes
+ * are sent through the shared generic infoframe units instead. Register
+ * layout per NVIDIA's clc971.h/clca71.h, programming sequence per
+ * nvhdmipkt_C971.c:programAdvancedInfoframeC971().
+ */
+static void
+gb202_sor_hdmi_infoframe_vsi(struct nvkm_ior *ior, int head, void *data, u32 size)
+{
+ struct nvkm_device *device = ior->disp->engine.subdev.device;
+ const u32 hoff = head * 0x400;
+ /* Generic infoframe unit 1, the slot NVIDIA's driver uses for the VSI. */
+ const u32 ctrl = 0x6f0138 + hoff;
+ u8 buf[36] = {};
+ int i;
+
+ /* Disable the unit and wait for it to go idle. */
+ nvkm_mask(device, ctrl, 0x00000001, 0x00000000);
+ if (nvkm_msec(device, 2000,
+ if (!(nvkm_rd32(device, ctrl) & 0x00400000))
+ break;
+ ) < 0)
+ return;
+
+ if (!size)
+ return;
+
+ /* Clear SENT status, and point the data port at unit 1's slot. */
+ nvkm_mask(device, ctrl, 0x00800000, 0x00800000);
+ nvkm_wr32(device, 0x6f03f0 + hoff, 0x00000001);
+
+ /* The data port takes the raw packet, except that a zero is inserted
+ * in HB3 after the three header bytes. A slot is 9 dwords (HB0-3 plus
+ * up to 32 payload bytes). An HDMI infoframe carries at most PB0-27,
+ * so the tail stays zero, and we always write the whole slot.
+ */
+ size = min_t(u32, size, 31);
+ memcpy(buf, data, min_t(u32, size, 3));
+ if (size > 3)
+ memcpy(&buf[4], (u8 *)data + 3, size - 3);
+
+ for (i = 0; i < 36; i += 4) {
+ nvkm_wr32(device, 0x6f03f4 + hoff, buf[i + 0] | buf[i + 1] << 8 |
+ buf[i + 2] << 16 |
+ (u32)buf[i + 3] << 24);
+ }
+
+ /* No flip ID or scanline matching. */
+ nvkm_wr32(device, 0x6f013c + hoff, 0x00000000);
+
+ /* ENABLE | RUN_MODE=ALWAYS | LOC=VBLANK | OFFSET=1 | SIZE=0. */
+ nvkm_wr32(device, ctrl, 0x00000041);
+
+ /* Audio priority low (the init value). */
+ nvkm_wr32(device, 0x6f03f8 + hoff, 0x00000002);
+}
+
+/* General Control Packet AVMute bracket. The GCP unit moved to slot 1 on
+ * NVD5.0. Only SB0 (the AVMute bit) is ours to write so we must not do a
+ * full write here: SB1 carries the deep-color CD/PP fields, and SB1_CTRL
+ * (bit 24, new with clc871.h) controls where their generation happens (HW
+ * or driver) on these chips, with the default being HW.
+ */
+static void
+gb202_sor_hdmi_gcp(struct nvkm_ior *sor, int head, bool enable)
+{
+ struct nvkm_device *device = sor->disp->engine.subdev.device;
+ const u32 hdmi = head * 0x400;
+
+ nvkm_mask(device, 0x6f0040 + hdmi, 0x00000001, 0x00000000);
+ nvkm_mask(device, 0x6f004c + hdmi, 0x000000ff, !enable ? 0x00000001 :
+ 0x00000010);
+ nvkm_mask(device, 0x6f0040 + hdmi, 0x00000001, 0x00000001);
+}
+
+/* Same core-channel state mirror as gv100_head_state() (assembly at 0x680000,
+ * armed at +0x8000, per-head method offsets unchanged), but NVD5.0 spaces
+ * heads 0x800 apart (see NVCA7D_HEAD_SET_*(a) in clca7d.h).
+ */
+static void
+gb202_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
+{
+ struct nvkm_device *device = head->disp->engine.subdev.device;
+ const u32 hoff = (state == &head->arm) * 0x8000 + head->id * 0x800;
+ u32 data;
+
+ data = nvkm_rd32(device, 0x682064 + hoff);
+ state->vtotal = (data & 0xffff0000) >> 16;
+ state->htotal = (data & 0x0000ffff);
+ data = nvkm_rd32(device, 0x682068 + hoff);
+ state->vsynce = (data & 0xffff0000) >> 16;
+ state->hsynce = (data & 0x0000ffff);
+ data = nvkm_rd32(device, 0x68206c + hoff);
+ state->vblanke = (data & 0xffff0000) >> 16;
+ state->hblanke = (data & 0x0000ffff);
+ data = nvkm_rd32(device, 0x682070 + hoff);
+ state->vblanks = (data & 0xffff0000) >> 16;
+ state->hblanks = (data & 0x0000ffff);
+ /* Bit 31 is ADJ1000DIV1001, not a HERTZ bit. We don't have enough bits
+ * to add the full clock in hz on Blackwell (35 bits), but state->hz
+ * is unused and obsolete under GSP so this is fine.
+ */
+ state->hz = nvkm_rd32(device, 0x68200c + hoff) & 0x7fffffff;
+
+ data = nvkm_rd32(device, 0x682004 + hoff);
+ switch ((data & 0x000000f0) >> 4) {
+ case 5: state->or.depth = 30; break;
+ case 4: state->or.depth = 24; break;
+ case 1: state->or.depth = 18; break;
+ default:
+ state->or.depth = 18;
+ WARN_ON(1);
+ break;
+ }
+}
+
+/* NVD5.0 (GB20x and later) moved the RM head-timing interrupt enable to
+ * the low-latency vector's EN1 block. The event latch is unchanged.
+ */
+static void
+gb202_head_vblank_put(struct nvkm_head *head)
+{
+ struct nvkm_device *device = head->disp->engine.subdev.device;
+
+ nvkm_mask(device, 0x611ef0 + (head->id * 4), 0x00000002, 0x00000000);
+}
+
+static void
+gb202_head_vblank_get(struct nvkm_head *head)
+{
+ struct nvkm_device *device = head->disp->engine.subdev.device;
+
+ nvkm_wr32(device, 0x611800 + (head->id * 4), 0x00000002);
+ nvkm_mask(device, 0x611ef0 + (head->id * 4), 0x00000002, 0x00000002);
+}
+
+static irqreturn_t
+gb202_disp_intr(struct nvkm_inth *inth)
+{
+ struct nvkm_disp *disp = container_of(inth, typeof(*disp), engine.subdev.inth);
+ irqreturn_t ret = tu102_disp_intr(inth);
+
+ /* The FE interrupt vectors are message-based on NVD5.0. Re-arm the
+ * low-latency vector so it fires again for any event that latched
+ * while we were servicing.
+ */
+ nvkm_wr32(disp->engine.subdev.device, 0x611f34, 0x00000001);
+ return ret;
+}
+
+static const struct nvkm_head_func
+gb202_gsp_head = {
+ .state = gb202_head_state,
+ .rgpos = gv100_head_rgpos,
+ .vblank_get = gb202_head_vblank_get,
+ .vblank_put = gb202_head_vblank_put,
+};
+
+/* GB20x is GSP-only. This table supplies the register programming the
+ * GSP-RM display path needs from the chip.
+ */
+static const struct nvkm_disp_func
+gb202_gsp_disp = {
+ .uevent = &gv100_disp_chan_uevent,
+ .ramht_size = 0x2000,
+ /* Head timing arrives on the dedicated low-latency vector. */
+ .gsp.intr = gb202_disp_intr,
+ .gsp.intr_low_latency = true,
+ .gsp.head = &gb202_gsp_head,
+ .gsp.hdmi_gcp = gb202_sor_hdmi_gcp,
+ /* The legacy AVI unit is unchanged on GB20x. */
+ .gsp.hdmi_infoframe_avi = gv100_sor_hdmi_infoframe_avi,
+ .gsp.hdmi_infoframe_vsi = gb202_sor_hdmi_infoframe_vsi,
+};
+
+int
+gb202_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
+ struct nvkm_disp **pdisp)
+{
+ return r535_disp_new(&gb202_gsp_disp, device, type, inst, pdisp);
+}
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
index b642729c254f..5976498da909 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
@@ -56,6 +56,8 @@ int gv100_head_new(struct nvkm_disp *, int id);
void gv100_head_state(struct nvkm_head *head, struct nvkm_head_state *state);
void gv100_head_rgpos(struct nvkm_head *head, u16 *hline, u16 *vline);
+extern const struct nvkm_head_func tu102_gsp_head;
+
#define HEAD_MSG(h,l,f,a...) do { \
struct nvkm_head *_h = (h); \
nvkm_##l(&_h->disp->engine.subdev, "head-%d: "f"\n", _h->id, ##a); \
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
index 3ba04bead2f9..5d682a774f2d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -194,6 +194,7 @@ void gv100_sor_dp_audio_sym(struct nvkm_ior *, int, u16, u32);
void gv100_sor_dp_watermark(struct nvkm_ior *, int, u8);
extern const struct nvkm_ior_func_hda gv100_sor_hda;
+void tu102_sor_hdmi_gcp(struct nvkm_ior *, int, bool);
void tu102_sor_dp_vcpi(struct nvkm_ior *, int, u8, u8, u16, u16);
int nv50_pior_cnt(struct nvkm_disp *, unsigned long *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
index a3fd7cb7c488..fde321dbd7c8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
@@ -5,6 +5,8 @@
#include <engine/disp.h>
#include <core/enum.h>
struct nvkm_head;
+struct nvkm_head_func;
+struct nvkm_ior;
struct nvkm_outp;
struct dcb_output;
@@ -34,6 +36,20 @@ struct nvkm_disp_func {
int (*new)(struct nvkm_disp *, int id);
} wndw, head, dac, sor, pior;
+ /* Register programming that the GSP-RM display path (rm/r535) needs from
+ * the chip, everything else on that path goes through RM. The hooks are
+ * called unconditionally and the head table is handed to nvkm_head_new_().
+ */
+ struct {
+ irqreturn_t (*intr)(struct nvkm_inth *);
+ /* Head-timing interrupts arrive on a second DISP vector. */
+ bool intr_low_latency;
+ const struct nvkm_head_func *head;
+ void (*hdmi_gcp)(struct nvkm_ior *, int head, bool enable);
+ void (*hdmi_infoframe_avi)(struct nvkm_ior *, int head, void *data, u32 size);
+ void (*hdmi_infoframe_vsi)(struct nvkm_ior *, int head, void *data, u32 size);
+ } gsp;
+
u16 ramht_size;
struct nvkm_sclass root;
@@ -72,6 +88,7 @@ int gv100_disp_wndw_cnt(struct nvkm_disp *, unsigned long *);
int gv100_disp_caps_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
int tu102_disp_init(struct nvkm_disp *);
+irqreturn_t tu102_disp_intr(struct nvkm_inth *);
void nv50_disp_dptmds_war_2(struct nvkm_disp *, struct dcb_output *);
void nv50_disp_dptmds_war_3(struct nvkm_disp *, struct dcb_output *);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c
index dcb9f8ba374c..f6c163072ff6 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/tu102.c
@@ -30,6 +30,21 @@
#include <nvif/class.h>
+/* General Control Packet: bracket an audio enable/disable with AVMute
+ * through the legacy GCP SF unit. Used by the GSP-RM path, which sends the
+ * equivalent packet via RM as well but keeps the direct write in sync.
+ */
+void
+tu102_sor_hdmi_gcp(struct nvkm_ior *sor, int head, bool enable)
+{
+ struct nvkm_device *device = sor->disp->engine.subdev.device;
+ const u32 hdmi = head * 0x400;
+
+ nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000);
+ nvkm_wr32(device, 0x6f00cc + hdmi, !enable ? 0x00000001 : 0x00000010);
+ nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001);
+}
+
void
tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
{
@@ -104,6 +119,64 @@ tu102_sor_new(struct nvkm_disp *disp, int id)
return nvkm_ior_new_(&tu102_sor, disp, SOR, id, hda & BIT(id));
}
+/* The GSP-RM display path leaves head-timing (vblank) interrupts and their
+ * enables to us. These program the RM head-timing line (bit 1 of the
+ * per-head enable, not the bit nvkm's own gv100 path uses).
+ */
+static void
+tu102_head_vblank_put(struct nvkm_head *head)
+{
+ struct nvkm_device *device = head->disp->engine.subdev.device;
+
+ nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000000);
+}
+
+static void
+tu102_head_vblank_get(struct nvkm_head *head)
+{
+ struct nvkm_device *device = head->disp->engine.subdev.device;
+
+ nvkm_wr32(device, 0x611800 + (head->id * 4), 0x00000002);
+ nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002);
+}
+
+const struct nvkm_head_func
+tu102_gsp_head = {
+ .state = gv100_head_state,
+ .rgpos = gv100_head_rgpos,
+ .vblank_get = tu102_head_vblank_get,
+ .vblank_put = tu102_head_vblank_put,
+};
+
+static void
+tu102_disp_intr_head_timing(struct nvkm_disp *disp, int head)
+{
+ struct nvkm_subdev *subdev = &disp->engine.subdev;
+ struct nvkm_device *device = subdev->device;
+ u32 stat = nvkm_rd32(device, 0x611c00 + (head * 0x04));
+
+ if (stat & 0x00000002) {
+ nvkm_disp_vblank(disp, head);
+
+ nvkm_wr32(device, 0x611800 + (head * 0x04), 0x00000002);
+ }
+}
+
+irqreturn_t
+tu102_disp_intr(struct nvkm_inth *inth)
+{
+ struct nvkm_disp *disp = container_of(inth, typeof(*disp), engine.subdev.inth);
+ struct nvkm_subdev *subdev = &disp->engine.subdev;
+ struct nvkm_device *device = subdev->device;
+ unsigned long mask = nvkm_rd32(device, 0x611ec0) & 0x000000ff;
+ int head;
+
+ for_each_set_bit(head, &mask, 8)
+ tu102_disp_intr_head_timing(disp, head);
+
+ return IRQ_HANDLED;
+}
+
int
tu102_disp_init(struct nvkm_disp *disp)
{
@@ -230,12 +303,23 @@ tu102_disp = {
},
};
+static const struct nvkm_disp_func
+tu102_gsp_disp = {
+ .uevent = &gv100_disp_chan_uevent,
+ .ramht_size = 0x2000,
+ .gsp.intr = tu102_disp_intr,
+ .gsp.head = &tu102_gsp_head,
+ .gsp.hdmi_gcp = tu102_sor_hdmi_gcp,
+ .gsp.hdmi_infoframe_avi = gv100_sor_hdmi_infoframe_avi,
+ .gsp.hdmi_infoframe_vsi = gv100_sor_hdmi_infoframe_vsi,
+};
+
int
tu102_disp_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
struct nvkm_disp **pdisp)
{
if (nvkm_gsp_rm(device->gsp))
- return r535_disp_new(&tu102_disp, device, type, inst, pdisp);
+ return r535_disp_new(&tu102_gsp_disp, device, type, inst, pdisp);
return nvkm_disp_new_(&tu102_disp, device, type, inst, pdisp);
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
index e77733a5d9c3..f5f22173fc2c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/disp.c
@@ -400,16 +400,16 @@ r535_sor_dp_audio(struct nvkm_ior *sor, int head, bool enable)
r535_sor_dp_audio_mute(sor, false);
}
-static void
-r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
+static int
+r535_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
{
struct nvkm_disp *disp = sor->disp;
struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;
ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl));
- if (WARN_ON(IS_ERR(ctrl)))
- return;
+ if (IS_ERR(ctrl))
+ return PTR_ERR(ctrl);
ctrl->subDeviceInstance = 0;
ctrl->head = head;
@@ -429,12 +429,20 @@ r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u
ctrl->MST.sendACT = 0;
ctrl->MST.singleHeadMSTPipeline = 0;
ctrl->MST.bEnableAudioOverRightPanel = 0;
- WARN_ON(nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl));
+ return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
+}
+
+static void
+r535_sor_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
+{
+ const struct nvkm_rm_api *rmapi = sor->disp->engine.subdev.device->gsp->rm->api;
+
+ WARN_ON(rmapi->disp->dp.vcpi(sor, head, slot, slot_nr, pbn, aligned_pbn));
}
static int
-r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef,
- u32 watermark, u32 hblanksym, u32 vblanksym)
+r535_dp_sst(struct nvkm_ior *sor, int head, bool ef,
+ u32 watermark, u32 hblanksym, u32 vblanksym)
{
struct nvkm_disp *disp = sor->disp;
struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;
@@ -461,6 +469,15 @@ r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef,
return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
}
+static int
+r535_sor_dp_sst(struct nvkm_ior *sor, int head, bool ef,
+ u32 watermark, u32 hblanksym, u32 vblanksym)
+{
+ const struct nvkm_rm_api *rmapi = sor->disp->engine.subdev.device->gsp->rm->api;
+
+ return rmapi->disp->dp.sst(sor, head, ef, watermark, hblanksym, vblanksym);
+}
+
static const struct nvkm_ior_func_dp
r535_sor_dp = {
.sst = r535_sor_dp_sst,
@@ -545,16 +562,21 @@ r535_sor_hdmi_ctrl_audio(struct nvkm_outp *outp, bool enable)
static void
r535_sor_hdmi_audio(struct nvkm_ior *sor, int head, bool enable)
{
- struct nvkm_device *device = sor->disp->engine.subdev.device;
- const u32 hdmi = head * 0x400;
-
r535_sor_hdmi_ctrl_audio(sor->asy.outp, enable);
r535_sor_hdmi_ctrl_audio_mute(sor->asy.outp, !enable);
+ sor->disp->func->gsp.hdmi_gcp(sor, head, enable);
+}
+
+static void
+r535_sor_hdmi_infoframe_avi(struct nvkm_ior *sor, int head, void *data, u32 size)
+{
+ sor->disp->func->gsp.hdmi_infoframe_avi(sor, head, data, size);
+}
- /* General Control (GCP). */
- nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000000);
- nvkm_wr32(device, 0x6f00cc + hdmi, !enable ? 0x00000001 : 0x00000010);
- nvkm_mask(device, 0x6f00c0 + hdmi, 0x00000001, 0x00000001);
+static void
+r535_sor_hdmi_infoframe_vsi(struct nvkm_ior *sor, int head, void *data, u32 size)
+{
+ sor->disp->func->gsp.hdmi_infoframe_vsi(sor, head, data, size);
}
static void
@@ -582,8 +604,8 @@ r535_sor_hdmi = {
.ctrl = r535_sor_hdmi_ctrl,
.scdc = r535_sor_hdmi_scdc,
/*TODO: SF_USER -> KMS. */
- .infoframe_avi = gv100_sor_hdmi_infoframe_avi,
- .infoframe_vsi = gv100_sor_hdmi_infoframe_vsi,
+ .infoframe_avi = r535_sor_hdmi_infoframe_avi,
+ .infoframe_vsi = r535_sor_hdmi_infoframe_vsi,
.audio = r535_sor_hdmi_audio,
};
@@ -608,31 +630,6 @@ r535_sor_cnt(struct nvkm_disp *disp, unsigned long *pmask)
return 4;
}
-static void
-r535_head_vblank_put(struct nvkm_head *head)
-{
- struct nvkm_device *device = head->disp->engine.subdev.device;
-
- nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000000);
-}
-
-static void
-r535_head_vblank_get(struct nvkm_head *head)
-{
- struct nvkm_device *device = head->disp->engine.subdev.device;
-
- nvkm_wr32(device, 0x611800 + (head->id * 4), 0x00000002);
- nvkm_mask(device, 0x611d80 + (head->id * 4), 0x00000002, 0x00000002);
-}
-
-static const struct nvkm_head_func
-r535_head = {
- .state = gv100_head_state,
- .rgpos = gv100_head_rgpos,
- .vblank_get = r535_head_vblank_get,
- .vblank_put = r535_head_vblank_put,
-};
-
static struct nvkm_conn *
r535_conn_new(struct nvkm_disp *disp, u32 id)
{
@@ -1405,35 +1402,6 @@ r535_disp_event = {
};
static void
-r535_disp_intr_head_timing(struct nvkm_disp *disp, int head)
-{
- struct nvkm_subdev *subdev = &disp->engine.subdev;
- struct nvkm_device *device = subdev->device;
- u32 stat = nvkm_rd32(device, 0x611c00 + (head * 0x04));
-
- if (stat & 0x00000002) {
- nvkm_disp_vblank(disp, head);
-
- nvkm_wr32(device, 0x611800 + (head * 0x04), 0x00000002);
- }
-}
-
-static irqreturn_t
-r535_disp_intr(struct nvkm_inth *inth)
-{
- struct nvkm_disp *disp = container_of(inth, typeof(*disp), engine.subdev.inth);
- struct nvkm_subdev *subdev = &disp->engine.subdev;
- struct nvkm_device *device = subdev->device;
- unsigned long mask = nvkm_rd32(device, 0x611ec0) & 0x000000ff;
- int head;
-
- for_each_set_bit(head, &mask, 8)
- r535_disp_intr_head_timing(disp, head);
-
- return IRQ_HANDLED;
-}
-
-static void
r535_disp_fini(struct nvkm_disp *disp, bool suspend)
{
if (!disp->engine.subdev.use.enabled)
@@ -1659,7 +1627,7 @@ r535_disp_oneinit(struct nvkm_disp *disp)
nvkm_gsp_rm_ctrl_done(&disp->rm.objcom, ctrl);
for_each_set_bit(i, &disp->head.mask, disp->head.nr) {
- ret = nvkm_head_new_(&r535_head, disp, i);
+ ret = nvkm_head_new_(disp->func->gsp.head, disp, i);
if (ret)
return ret;
}
@@ -1703,12 +1671,20 @@ r535_disp_oneinit(struct nvkm_disp *disp)
if (ret)
return ret;
- ret = nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type, disp->engine.subdev.inst);
+ /* Chips that raise head-timing interrupts on a separate low-latency
+ * vector report it as a second DISP interrupt table entry, exposed
+ * as instance 1 by the RM engine-index translation (see
+ * r570_gsp_xlat_mc_engine_idx()). Their high-latency vector
+ * (instance 0) is left unhandled as no event nouveau enables is
+ * routed to it, and without a handler it stays masked.
+ */
+ ret = nvkm_gsp_intr_stall(gsp, disp->engine.subdev.type,
+ disp->func->gsp.intr_low_latency ? 1 : disp->engine.subdev.inst);
if (ret < 0)
return ret;
ret = nvkm_inth_add(&device->vfn->intr, ret, NVKM_INTR_PRIO_NORMAL, &disp->engine.subdev,
- r535_disp_intr, &disp->engine.subdev.inth);
+ disp->func->gsp.intr, &disp->engine.subdev.inth);
if (ret)
return ret;
@@ -1741,6 +1717,7 @@ r535_disp_new(const struct nvkm_disp_func *hw, struct nvkm_device *device,
rm->uevent = hw->uevent;
rm->sor.cnt = r535_sor_cnt;
rm->sor.new = r535_sor_new;
+ rm->gsp = hw->gsp;
rm->ramht_size = hw->ramht_size;
rm->root.oclass = gpu->disp.class.root;
@@ -1782,6 +1759,8 @@ r535_disp = {
.dp = {
.get_caps = r535_dp_get_caps,
.set_indexed_link_rates = r535_dp_set_indexed_link_rates,
+ .sst = r535_dp_sst,
+ .vcpi = r535_dp_vcpi,
},
.chan = {
.set_pushbuf = r535_disp_chan_set_pushbuf,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c
index a96e31c2d80b..8a23837f356e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/disp.c
@@ -5,6 +5,7 @@
#include <rm/rm.h>
#include <engine/disp.h>
+#include <engine/disp/ior.h>
#include <engine/disp/outp.h>
#include "nvhw/drf.h"
@@ -75,6 +76,67 @@ r570_disp_chan_set_pushbuf(struct nvkm_disp *disp, s32 oclass, int inst, struct
}
static int
+r570_dp_vcpi(struct nvkm_ior *sor, int head, u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn)
+{
+ struct nvkm_disp *disp = sor->disp;
+ NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;
+
+ ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
+ NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl));
+ if (IS_ERR(ctrl))
+ return PTR_ERR(ctrl);
+
+ ctrl->subDeviceInstance = 0;
+ ctrl->head = head;
+ ctrl->sorIndex = sor->id;
+ ctrl->dpLink = sor->asy.link == 2;
+ ctrl->bEnableOverride = 1;
+ ctrl->bMST = 1;
+ ctrl->hBlankSym = 0;
+ ctrl->vBlankSym = 0;
+ ctrl->colorFormat = 0;
+ ctrl->bEnableTwoHeadOneOr = 0;
+ ctrl->singleHeadMultistreamMode = 0;
+ ctrl->MST.slotStart = slot;
+ ctrl->MST.slotEnd = slot + slot_nr - 1;
+ ctrl->MST.PBN = pbn;
+ ctrl->MST.Timeslice = aligned_pbn;
+ ctrl->MST.sendACT = 0;
+ ctrl->MST.singleHeadMSTPipeline = 0;
+ ctrl->MST.bEnableAudioOverRightPanel = 0;
+ return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
+}
+
+static int
+r570_dp_sst(struct nvkm_ior *sor, int head, bool ef,
+ u32 watermark, u32 hblanksym, u32 vblanksym)
+{
+ struct nvkm_disp *disp = sor->disp;
+ NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS *ctrl;
+
+ ctrl = nvkm_gsp_rm_ctrl_get(&disp->rm.objcom,
+ NV0073_CTRL_CMD_DP_CONFIG_STREAM, sizeof(*ctrl));
+ if (IS_ERR(ctrl))
+ return PTR_ERR(ctrl);
+
+ ctrl->subDeviceInstance = 0;
+ ctrl->head = head;
+ ctrl->sorIndex = sor->id;
+ ctrl->dpLink = sor->asy.link == 2;
+ ctrl->bEnableOverride = 1;
+ ctrl->bMST = 0;
+ ctrl->hBlankSym = hblanksym;
+ ctrl->vBlankSym = vblanksym;
+ ctrl->colorFormat = 0;
+ ctrl->bEnableTwoHeadOneOr = 0;
+ ctrl->SST.bEnhancedFraming = ef;
+ ctrl->SST.tuSize = 64;
+ ctrl->SST.waterMark = watermark;
+ ctrl->SST.bEnableAudioOverRightPanel = 0;
+ return nvkm_gsp_rm_ctrl_wr(&disp->rm.objcom, ctrl);
+}
+
+static int
r570_dp_set_indexed_link_rates(struct nvkm_outp *outp)
{
NV0073_CTRL_CMD_DP_CONFIG_INDEXED_LINK_RATES_PARAMS *ctrl;
@@ -255,6 +317,8 @@ r570_disp = {
.dp = {
.get_caps = r570_dp_get_caps,
.set_indexed_link_rates = r570_dp_set_indexed_link_rates,
+ .sst = r570_dp_sst,
+ .vcpi = r570_dp_vcpi,
},
.chan = {
.set_pushbuf = r570_disp_chan_set_pushbuf,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
index 996941c668ba..1488771c63fc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
@@ -44,6 +44,15 @@ r570_gsp_xlat_mc_engine_idx(u32 mc_engine_idx, enum nvkm_subdev_type *ptype, int
*ptype = NVKM_ENGINE_DISP;
*pinst = 0;
return true;
+ case MC_ENGINE_IDX_DISP_LOW:
+ /* GB20x+ report a separate low-latency display vector, used
+ * for head-timing interrupts. Expose it as a second DISP
+ * interrupt instance. r535_disp_oneinit() attaches the
+ * handler to it when the chip's gsp.intr_low_latency is set.
+ */
+ *ptype = NVKM_ENGINE_DISP;
+ *pinst = 1;
+ return true;
case MC_ENGINE_IDX_CE0 ... MC_ENGINE_IDX_CE19:
*ptype = NVKM_ENGINE_CE;
*pinst = mc_engine_idx - MC_ENGINE_IDX_CE0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h
index 06e972835d77..742b25a2a12d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/disp.h
@@ -256,6 +256,8 @@ typedef struct NV0073_CTRL_DP_CTRL_PARAMS {
NvU32 eightLaneDpcdBaseAddr;
} NV0073_CTRL_DP_CTRL_PARAMS;
+#define NV0073_CTRL_CMD_DP_CONFIG_STREAM (0x731362U) /* finn: Evaluated from "(FINN_NV04_DISPLAY_COMMON_DP_INTERFACE_ID << 8) | NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS_MESSAGE_ID" */
+
typedef struct NV0073_CTRL_CMD_DP_CONFIG_STREAM_PARAMS {
NvU32 subDeviceInstance;
NvU32 head;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
index a9af94adf9ef..fcd0221dcea1 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
@@ -6,6 +6,7 @@
#ifndef __NVKM_RM_H__
#define __NVKM_RM_H__
#include "handles.h"
+struct nvkm_ior;
struct nvkm_outp;
struct r535_gr;
@@ -93,6 +94,10 @@ struct nvkm_rm_api {
struct {
int (*get_caps)(struct nvkm_disp *, int *link_bw, bool *mst, bool *wm);
int (*set_indexed_link_rates)(struct nvkm_outp *);
+ int (*sst)(struct nvkm_ior *, int head, bool ef,
+ u32 watermark, u32 hblanksym, u32 vblanksym);
+ int (*vcpi)(struct nvkm_ior *, int head,
+ u8 slot, u8 slot_nr, u16 pbn, u16 aligned_pbn);
} dp;
struct {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
index f4489efc94a7..22b0fde6ba34 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c
@@ -195,6 +195,9 @@ check_io_mapping(struct nv50_instmem *imem)
{
struct nvkm_device *device = imem->base.subdev.device;
+ if (imem->iomap.size)
+ return true;
+
return io_mapping_init_wc(&imem->iomap,
device->func->resource_addr(device, NVKM_BAR2_INST),
device->func->resource_size(device, NVKM_BAR2_INST)) != NULL;
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 7f4178800afd..0719fc6a52d5 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -30,6 +30,7 @@
#include <drm/drm_drv.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder.h>
#include <drm/drm_framebuffer.h>
@@ -981,7 +982,7 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev,
return ERR_PTR(-EINVAL);
}
- plane = kzalloc(sizeof(*plane), GFP_KERNEL);
+ plane = kzalloc_obj(*plane);
if (!plane)
return ERR_PTR(-ENOMEM);
@@ -993,6 +994,9 @@ static struct drm_plane *qxl_create_plane(struct qxl_device *qdev,
drm_plane_helper_add(plane, helper_funcs);
+ drm_plane_create_blend_mode_property(plane,
+ BIT(DRM_MODE_BLEND_PREMULTI));
+
return plane;
free_plane:
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index e7f49fe845ea..4e58685f58ff 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -68,6 +68,7 @@ config ROCKCHIP_CDN_DP
config ROCKCHIP_DW_DP
bool "Rockchip specific extensions for Synopsys DW DP"
+ select DRM_BRIDGE_CONNECTOR
help
This selects support for Rockchip SoC specific extensions
to enable Synopsys DesignWare Cores based DisplayPort transmit
@@ -145,6 +146,8 @@ config ROCKCHIP_RGB
config ROCKCHIP_RK3066_HDMI
bool "Rockchip specific extensions for RK3066 HDMI"
depends on DRM_ROCKCHIP
+ select DRM_DISPLAY_HELPER
+ select DRM_BRIDGE_CONNECTOR
help
This selects support for Rockchip SoC specific extensions
for the RK3066 HDMI driver. If you want to enable
diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
index 587e60232ec7..efd5a98e80bd 100644
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -241,10 +241,11 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder,
of_graph_get_remote_port(endpoint.local_node);
of_property_read_u32(remote_port, "reg", &port_id);
- sprintf(name, "%s vp%d", remote_port_parent->full_name, port_id);
+ snprintf(name, sizeof(name), "%s vp%d",
+ remote_port_parent->full_name, port_id);
} else {
- sprintf(name, "%s %s",
- remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
+ snprintf(name, sizeof(name), "%s %s",
+ remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
}
DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
diff --git a/drivers/gpu/drm/scheduler/tests/mock_scheduler.c b/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
index 8e9ae7d980eb..2dfa3efef210 100644
--- a/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
+++ b/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2025 Valve Corporation */
+#include <kunit/device.h>
+
#include "sched_tests.h"
/*
@@ -288,6 +290,7 @@ static const struct drm_sched_backend_ops drm_mock_scheduler_ops = {
*/
struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test, long timeout)
{
+ static unsigned int instance;
struct drm_sched_init_args args = {
.ops = &drm_mock_scheduler_ops,
.num_rqs = DRM_SCHED_PRIORITY_COUNT,
@@ -297,11 +300,19 @@ struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test, long timeout)
.name = "drm-mock-scheduler",
};
struct drm_mock_scheduler *sched;
+ struct device *dev;
+ char name[64];
int ret;
sched = kunit_kzalloc(test, sizeof(*sched), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, sched);
+ snprintf(name, sizeof(name), "%s-%u", args.name, instance++);
+ dev = kunit_device_register(test, name);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+ args.dev = dev;
+
ret = drm_sched_init(&sched->base, &args);
KUNIT_ASSERT_EQ(test, ret, 0);
diff --git a/drivers/gpu/drm/sysfb/ofdrm.c b/drivers/gpu/drm/sysfb/ofdrm.c
index 819aed466727..9d60db45139c 100644
--- a/drivers/gpu/drm/sysfb/ofdrm.c
+++ b/drivers/gpu/drm/sysfb/ofdrm.c
@@ -2,6 +2,7 @@
#include <linux/aperture.h>
#include <linux/of_address.h>
+#include <linux/overflow.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
@@ -238,7 +239,7 @@ static bool is_avivo(u32 vendor, u32 device)
/* This will match most R5xx */
return (vendor == PCI_VENDOR_ID_ATI) &&
((device >= PCI_VENDOR_ID_ATI_R520 && device < 0x7800) ||
- (PCI_VENDOR_ID_ATI_R600 >= 0x9400));
+ (device >= PCI_VENDOR_ID_ATI_R600));
}
static enum ofdrm_model display_get_model_of(struct drm_device *dev, struct device_node *of_node)
@@ -913,7 +914,10 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv,
return ERR_PTR(-EINVAL);
}
- fb_size = linebytes * height;
+ if (check_mul_overflow(linebytes, height, &fb_size)) {
+ drm_err(dev, "framebuffer size exceeds maximum\n");
+ return ERR_PTR(-EINVAL);
+ }
/*
* Try to figure out the address of the framebuffer. Unfortunately, Open
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 0b3fcc7011b3..fefc3761a4bc 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -904,6 +904,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
struct tegra_dc *dc)
{
unsigned long possible_crtcs = tegra_plane_get_possible_crtcs(drm);
+ unsigned int blend_caps = BIT(DRM_MODE_BLEND_COVERAGE);
enum drm_plane_type type = DRM_PLANE_TYPE_PRIMARY;
struct tegra_plane *plane;
unsigned int num_formats;
@@ -939,6 +940,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
}
drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
+ drm_plane_create_blend_mode_property(&plane->base, blend_caps);
drm_plane_create_zpos_property(&plane->base, plane->index, 0, 255);
err = drm_plane_create_rotation_property(&plane->base,
@@ -1209,6 +1211,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
struct tegra_dc *dc)
{
unsigned long possible_crtcs = tegra_plane_get_possible_crtcs(drm);
+ unsigned int blend_caps = BIT(DRM_MODE_BLEND_COVERAGE);
struct tegra_plane *plane;
unsigned int num_formats;
const u32 *formats;
@@ -1252,6 +1255,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
}
drm_plane_helper_add(&plane->base, &tegra_cursor_plane_helper_funcs);
+ drm_plane_create_blend_mode_property(&plane->base, blend_caps);
drm_plane_create_zpos_immutable_property(&plane->base, 255);
return &plane->base;
@@ -1356,6 +1360,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
bool cursor)
{
unsigned long possible_crtcs = tegra_plane_get_possible_crtcs(drm);
+ unsigned int blend_caps = BIT(DRM_MODE_BLEND_COVERAGE);
struct tegra_plane *plane;
unsigned int num_formats;
enum drm_plane_type type;
@@ -1394,6 +1399,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
}
drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs);
+ drm_plane_create_blend_mode_property(&plane->base, blend_caps);
drm_plane_create_zpos_property(&plane->base, plane->index, 0, 255);
err = drm_plane_create_rotation_property(&plane->base,
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index bd442bfd4540..448f49f3a7d7 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -759,6 +759,7 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm,
unsigned int index,
enum drm_plane_type type)
{
+ unsigned int blend_caps = BIT(DRM_MODE_BLEND_COVERAGE);
struct tegra_drm *tegra = drm->dev_private;
struct tegra_display_hub *hub = tegra->hub;
struct tegra_shared_plane *plane;
@@ -797,6 +798,7 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm,
}
drm_plane_helper_add(p, &tegra_shared_plane_helper_funcs);
+ drm_plane_create_blend_mode_property(p, blend_caps);
drm_plane_create_zpos_property(p, 0, 0, 255);
return p;
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c b/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c
index 2e7b3e87fea1..7583b6ebba2a 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_panel_legacy.c
@@ -22,7 +22,7 @@ tilcdc_panel_update_prop(struct of_changeset *ocs, struct device_node *node,
{
struct property *prop;
- prop = kzalloc(sizeof(*prop), GFP_KERNEL);
+ prop = kzalloc_obj(*prop);
if (!prop)
return -ENOMEM;
diff --git a/drivers/gpu/drm/tiny/cirrus-qemu.c b/drivers/gpu/drm/tiny/cirrus-qemu.c
index 075221b431d3..3bf23fcf6574 100644
--- a/drivers/gpu/drm/tiny/cirrus-qemu.c
+++ b/drivers/gpu/drm/tiny/cirrus-qemu.c
@@ -582,6 +582,9 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
struct cirrus_device *cirrus;
int ret;
+ if (pci_resource_len(pdev, 0) < CIRRUS_VRAM_SIZE)
+ return -ENODEV;
+
ret = aperture_remove_conflicting_pci_devices(pdev, cirrus_driver.name);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c
index 8e4e5fc9d3c5..3c41238a8268 100644
--- a/drivers/gpu/drm/vboxvideo/vbox_mode.c
+++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c
@@ -15,6 +15,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_edid.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
@@ -540,6 +541,9 @@ static struct drm_plane *vbox_create_plane(struct vbox_private *vbox,
drm_plane_helper_add(plane, helper_funcs);
+ drm_plane_create_blend_mode_property(plane,
+ BIT(DRM_MODE_BLEND_COVERAGE));
+
return plane;
free_plane:
diff --git a/drivers/gpu/drm/verisilicon/vs_plane.c b/drivers/gpu/drm/verisilicon/vs_plane.c
index d81f7b8f4c65..7ddb9d2dcb83 100644
--- a/drivers/gpu/drm/verisilicon/vs_plane.c
+++ b/drivers/gpu/drm/verisilicon/vs_plane.c
@@ -136,7 +136,7 @@ struct drm_plane_state *vs_plane_duplicate_state(struct drm_plane *plane)
vs_state_old = to_vs_plane_state(plane->state);
- vs_state = kzalloc_obj(*vs_state, GFP_KERNEL);
+ vs_state = kzalloc_obj(*vs_state);
if (!vs_state)
return NULL;
@@ -166,7 +166,7 @@ void vs_plane_reset(struct drm_plane *plane)
plane->state = NULL;
}
- vs_state = kzalloc_obj(*vs_state, GFP_KERNEL);
+ vs_state = kzalloc_obj(*vs_state);
if (!vs_state)
return;
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 44ffffec550f..a1a875a0c706 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -344,7 +344,7 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev,
if (ret) {
kfree(virtio_gpu_fb);
drm_gem_object_put(obj);
- return NULL;
+ return ERR_PTR(ret);
}
return &virtio_gpu_fb->base;
@@ -378,8 +378,11 @@ int virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev)
vgdev->ddev->mode_config.fb_modifiers_not_supported = true;
- for (i = 0 ; i < vgdev->num_scanouts; ++i)
- vgdev_output_init(vgdev, i);
+ for (i = 0; i < vgdev->num_scanouts; ++i) {
+ ret = vgdev_output_init(vgdev, i);
+ if (ret)
+ return ret;
+ }
ret = drm_vblank_init(vgdev->ddev, vgdev->num_scanouts);
if (ret)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 17a6a4d26516..9df4c7117341 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -43,6 +43,8 @@
#include <drm/drm_probe_helper.h>
#include <drm/virtgpu_drm.h>
+#include <xen/xen.h>
+
#define DRIVER_NAME "virtio_gpu"
#define DRIVER_DESC "virtio GPU"
@@ -60,6 +62,24 @@
/* See virtio_gpu_ctx_create. One additional character for NULL terminator. */
#define DEBUG_NAME_MAX_LEN 65
+/*
+ * Whether the host must be told about resource backing pages by DMA address
+ * rather than guest-physical address.
+ *
+ * This mirrors vring_use_map_api() in drivers/virtio/virtio_ring.c, including
+ * its xen_domain() case.
+ */
+static inline bool virtio_gpu_use_dma_api(const struct virtio_device *vdev)
+{
+ if (!virtio_has_dma_quirk(vdev))
+ return true;
+
+ if (xen_domain())
+ return true;
+
+ return false;
+}
+
struct virtio_gpu_object_params {
unsigned long size;
bool dumb;
@@ -343,6 +363,7 @@ void virtio_gpu_array_put_free_work(struct work_struct *work);
/* virtgpu_vq.c */
int virtio_gpu_alloc_vbufs(struct virtio_gpu_device *vgdev);
void virtio_gpu_free_vbufs(struct virtio_gpu_device *vgdev);
+void virtio_gpu_reclaim_vbufs(struct virtio_gpu_device *vgdev);
void virtio_gpu_cmd_create_resource(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo,
struct virtio_gpu_object_params *params,
diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c
index 1ffe1e431f65..1d4d3bf46a20 100644
--- a/drivers/gpu/drm/virtio/virtgpu_kms.c
+++ b/drivers/gpu/drm/virtio/virtgpu_kms.c
@@ -352,6 +352,7 @@ void virtio_gpu_deinit(struct drm_device *dev)
flush_work(&vgdev->cursorq.dequeue_work);
flush_work(&vgdev->config_changed_work);
virtio_reset_device(vgdev->vdev);
+ virtio_gpu_reclaim_vbufs(vgdev);
vgdev->vdev->config->del_vqs(vgdev->vdev);
mutex_destroy(&vgdev->obj_restore_lock);
}
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index 9bc0bd68c314..49899485be6f 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -173,7 +173,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
struct virtio_gpu_mem_entry **ents,
unsigned int *nents)
{
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
struct scatterlist *sg;
struct sg_table *pages;
int si;
diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c
index 1d1b27ece62a..640815af4098 100644
--- a/drivers/gpu/drm/virtio/virtgpu_plane.c
+++ b/drivers/gpu/drm/virtio/virtgpu_plane.c
@@ -24,6 +24,7 @@
*/
#include <drm/drm_atomic_helper.h>
+#include <drm/drm_blend.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_gem_atomic_helper.h>
@@ -609,6 +610,9 @@ struct drm_plane *virtio_gpu_plane_init(struct virtio_gpu_device *vgdev,
if (type == DRM_PLANE_TYPE_PRIMARY)
drm_plane_enable_fb_damage_clips(plane);
+ else if (type == DRM_PLANE_TYPE_CURSOR)
+ drm_plane_create_blend_mode_property(plane,
+ BIT(DRM_MODE_BLEND_PREMULTI));
return plane;
}
diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
index 216c77cd0d21..149e6bcb5878 100644
--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
+++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
@@ -293,9 +293,7 @@ int virtgpu_dma_buf_obj_resubmit(struct virtio_gpu_device *vgdev,
return -ENOMEM;
}
- ents = kvmalloc_array(bo->sgt->nents,
- sizeof(struct virtio_gpu_mem_entry),
- GFP_KERNEL);
+ ents = kvmalloc_objs(struct virtio_gpu_mem_entry, bo->sgt->nents);
if (!ents) {
DRM_ERROR("failed to allocate ent list\n");
return -ENOMEM;
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index f2b0ab0f610e..c02c03c10d92 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -208,6 +208,21 @@ static void free_vbuf(struct virtio_gpu_device *vgdev,
kmem_cache_free(vgdev->vbufs, vbuf);
}
+void virtio_gpu_reclaim_vbufs(struct virtio_gpu_device *vgdev)
+{
+ struct virtio_gpu_vbuffer *vbuf;
+
+ while ((vbuf = virtqueue_detach_unused_buf(vgdev->ctrlq.vq))) {
+ if (vbuf->objs)
+ virtio_gpu_array_put_free(vbuf->objs);
+ if (vbuf->resp_cb_data)
+ virtio_gpu_cleanup_object(vbuf->resp_cb_data);
+ free_vbuf(vgdev, vbuf);
+ }
+ while ((vbuf = virtqueue_detach_unused_buf(vgdev->cursorq.vq)))
+ free_vbuf(vgdev, vbuf);
+}
+
static void reclaim_vbufs(struct virtqueue *vq, struct list_head *reclaim_list)
{
struct virtio_gpu_vbuffer *vbuf;
@@ -764,7 +779,7 @@ int virtio_gpu_panic_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]);
struct virtio_gpu_transfer_to_host_2d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
if (virtio_gpu_is_shmem(bo) && use_dma_api)
dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
@@ -795,7 +810,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]);
struct virtio_gpu_transfer_to_host_2d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
if (virtio_gpu_is_shmem(bo) && use_dma_api)
dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
@@ -1228,7 +1243,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]);
struct virtio_gpu_transfer_host_3d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
if (virtio_gpu_is_shmem(bo) && use_dma_api)
dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c
index 7551b8c7766d..601e3f128c9f 100644
--- a/drivers/gpu/drm/vkms/vkms_configfs.c
+++ b/drivers/gpu/drm/vkms/vkms_configfs.c
@@ -212,7 +212,7 @@ static struct config_group *make_crtc_group(struct config_group *group,
if (dev->enabled)
return ERR_PTR(-EBUSY);
- crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
+ crtc = kzalloc_obj(*crtc);
if (!crtc)
return ERR_PTR(-ENOMEM);
@@ -368,7 +368,7 @@ static struct config_group *make_plane_group(struct config_group *group,
if (dev->enabled)
return ERR_PTR(-EBUSY);
- plane = kzalloc(sizeof(*plane), GFP_KERNEL);
+ plane = kzalloc_obj(*plane);
if (!plane)
return ERR_PTR(-ENOMEM);
@@ -484,7 +484,7 @@ static struct config_group *make_encoder_group(struct config_group *group,
if (dev->enabled)
return ERR_PTR(-EBUSY);
- encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
+ encoder = kzalloc_obj(*encoder);
if (!encoder)
return ERR_PTR(-ENOMEM);
@@ -651,7 +651,7 @@ static struct config_group *make_connector_group(struct config_group *group,
if (dev->enabled)
return ERR_PTR(-EBUSY);
- connector = kzalloc(sizeof(*connector), GFP_KERNEL);
+ connector = kzalloc_obj(*connector);
if (!connector)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h b/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
index 18d0fde8c98f..faf8d7e2c5c1 100644
--- a/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
+++ b/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
@@ -46,6 +46,7 @@
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
#define PIPE_CONTROL0_QUEUE_DRAIN_MODE BIT(12)
+#define PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH BIT(11) /* gen12 */
#define PIPE_CONTROL0_L3_READ_ONLY_CACHE_INVALIDATE BIT(10) /* gen12 */
#define PIPE_CONTROL0_HDC_PIPELINE_FLUSH BIT(9) /* gen12 */
diff --git a/drivers/gpu/drm/xe/xe_amc.c b/drivers/gpu/drm/xe/xe_amc.c
index 8ecadee6eea3..edd50bf8261e 100644
--- a/drivers/gpu/drm/xe/xe_amc.c
+++ b/drivers/gpu/drm/xe/xe_amc.c
@@ -177,7 +177,7 @@ int xe_amc_init(struct xe_i2c *i2c)
{
struct xe_amc *amc;
- amc = kzalloc(sizeof(*amc), GFP_KERNEL);
+ amc = kzalloc_obj(*amc);
if (!amc)
return -ENOMEM;
diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
index 9c5384b95c63..ab09dcff5860 100644
--- a/drivers/gpu/drm/xe/xe_oa.c
+++ b/drivers/gpu/drm/xe/xe_oa.c
@@ -2435,9 +2435,9 @@ int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *fi
oa_config->id = idr_alloc(&oa->metrics_idr, oa_config, 1, 0, GFP_KERNEL);
if (oa_config->id < 0) {
- drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n");
+ drm_dbg(&oa->xe->drm, "Failed to allocate id for OA config\n");
err = oa_config->id;
- goto sysfs_err;
+ goto id_alloc_err;
}
id = oa_config->id;
@@ -2448,6 +2448,8 @@ int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *fi
return id;
+id_alloc_err:
+ sysfs_remove_group(oa->metrics_kobj, &oa_config->sysfs_metric);
sysfs_err:
mutex_unlock(&oa->metrics_lock);
reg_err:
diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c
index dbf8f71d3328..a4986df8328d 100644
--- a/drivers/gpu/drm/xe/xe_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_pagefault.c
@@ -16,6 +16,7 @@
#include "xe_hw_engine.h"
#include "xe_pagefault.h"
#include "xe_pagefault_types.h"
+#include "xe_pm.h"
#include "xe_svm.h"
#include "xe_trace_bo.h"
#include "xe_vm.h"
@@ -292,9 +293,17 @@ static void xe_pagefault_queue_work(struct work_struct *w)
{
struct xe_pagefault_queue *pf_queue =
container_of(w, typeof(*pf_queue), worker);
+ struct xe_device *xe = pf_queue->xe;
struct xe_pagefault pf;
unsigned long threshold;
+ /*
+ * A live VM holds a PM reference, but a torn-down VM does not.
+ * Guard the entire worker loop to safely drain stale faults and
+ * prevent autosuspends from desyncing batched CT flushes.
+ */
+ guard(xe_pm_runtime)(xe);
+
#define USM_QUEUE_MAX_RUNTIME_MS 20
threshold = jiffies + msecs_to_jiffies(USM_QUEUE_MAX_RUNTIME_MS);
@@ -365,6 +374,7 @@ static int xe_pagefault_queue_init(struct xe_device *xe,
drm_dbg(&xe->drm, "xe_pagefault_entry_size=%d, total_num_eus=%d, pf_queue->size=%u",
xe_pagefault_entry_size(), total_num_eus, pf_queue->size);
+ pf_queue->xe = xe;
spin_lock_init(&pf_queue->lock);
INIT_WORK(&pf_queue->worker, xe_pagefault_queue_work);
diff --git a/drivers/gpu/drm/xe/xe_pagefault_types.h b/drivers/gpu/drm/xe/xe_pagefault_types.h
index c4ee625b93dd..f63a12aa0d4f 100644
--- a/drivers/gpu/drm/xe/xe_pagefault_types.h
+++ b/drivers/gpu/drm/xe/xe_pagefault_types.h
@@ -8,6 +8,7 @@
#include <linux/workqueue.h>
+struct xe_device;
struct xe_gt;
struct xe_pagefault;
@@ -118,6 +119,8 @@ struct xe_pagefault {
* queue to absorb the device’s worst-case number of outstanding faults.
*/
struct xe_pagefault_queue {
+ /** @xe: Back-pointer to the Xe device */
+ struct xe_device *xe;
/**
* @data: Data in queue containing struct xe_pagefault, protected by
* @lock
diff --git a/drivers/gpu/drm/xe/xe_ring_ops.c b/drivers/gpu/drm/xe/xe_ring_ops.c
index 39a670e91ba7..08b4a4283e96 100644
--- a/drivers/gpu/drm/xe/xe_ring_ops.c
+++ b/drivers/gpu/drm/xe/xe_ring_ops.c
@@ -212,6 +212,7 @@ static int emit_render_cache_flush(struct xe_sched_job *job, u32 *dw, int i)
{
struct xe_exec_queue *q = job->q;
struct xe_gt *gt = q->gt;
+ struct xe_device *xe = gt_to_xe(gt);
bool lacks_render = !(gt->info.engine_mask & XE_HW_ENGINE_RCS_MASK);
u32 flags0, flags1;
@@ -220,6 +221,16 @@ static int emit_render_cache_flush(struct xe_sched_job *job, u32 *dw, int i)
LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR, 0);
flags0 = PIPE_CONTROL0_HDC_PIPELINE_FLUSH;
+ /*
+ * Prior to MTL, HDC Pipeline Flush reliably also flushes the LSC
+ * untyped L1 dataport cache, provided HDC_CHICKEN0 is programmed
+ * correctly. Starting with MTL that coupling no longer holds
+ * regardless of how HDC_CHICKEN0 is programmed, but explicitly
+ * requesting the flush via PIPE_CONTROL is itself only reliable
+ * from Xe2 onward, so only gate it in on Xe2+.
+ */
+ if (GRAPHICS_VERx100(xe) >= 2000)
+ flags0 |= PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH;
flags1 = (PIPE_CONTROL_TILE_CACHE_FLUSH |
PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
PIPE_CONTROL_DEPTH_CACHE_FLUSH |
diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c
index 9e0176861cb6..23952ad8951e 100644
--- a/drivers/gpu/drm/xe/xe_vm.c
+++ b/drivers/gpu/drm/xe/xe_vm.c
@@ -4148,7 +4148,7 @@ static int fill_faults(struct xe_vm *vm,
entry_size = sizeof(struct xe_vm_fault);
count = args->size / entry_size;
- fault_list = kcalloc(count, sizeof(struct xe_vm_fault), GFP_KERNEL);
+ fault_list = kzalloc_objs(struct xe_vm_fault, count);
if (!fault_list)
return -ENOMEM;
diff --git a/drivers/gpu/drm/xe/xe_vram.c b/drivers/gpu/drm/xe/xe_vram.c
index 7b4478fb1697..56cff1e44530 100644
--- a/drivers/gpu/drm/xe/xe_vram.c
+++ b/drivers/gpu/drm/xe/xe_vram.c
@@ -90,6 +90,9 @@ static int get_flat_ccs_offset(struct xe_gt *gt, u64 tile_size, u64 *poffset)
offset |= offset_lo << 6; /* HW view bits 31:6 */
offset *= num_enabled; /* convert to SW view */
+ drm_info(&xe->drm, "FLAT_CCS base:%llx, aligned:%s\n", offset,
+ str_yes_no(IS_ALIGNED(offset, SZ_128K)));
+
/*
* Everything below this offset is handed to the VRAM
* allocator, so it has to be the *first* address the