mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 07:33:19 +02:00
Short summary of fixes pull:
ivpu: - Fix firewall IRQ handling panthor: - Fix firmware initialization wrt page sizes - Fix handling and reporting of dead job groups sched: - Guarantee forward progress via WC_MEM_RECLAIM tests: - Fix memory leak in drm_display_mode_from_cea_vic() -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEEchf7rIzpz2NEoWjlaA3BHVMLeiMFAmcjl28ACgkQaA3BHVML eiMePgf/aO8pHJDeUzDzbQ4FnT38RRlwpBCG6Z8BYBHU7QsSfrZ8f99quHArK9Pq DwSWkb44YgEETaerfXO4QizhmVFVcM9CnDKJzLg598dqfo9mAXu3mnXS8UKnEA43 wz9KAkdkl7P+fsGfvYK8iN/rSeHISQvh2XU5XF/tp7UNtc0HHwfvK/+MC+rkPo/z cwOErNUXEQFfW0f0Y5g2bvcIB5xykdY7JOtHVbVe6Y0fuw66wuznE/vexYSbgoE+ taJhQTNuz6E8rWKyNUR4PLvggYj5MU57uk94dWx34AFXKDS6TBiZph1auQctXldu 6caGwJkcIsCmCy0n+iWoiNahH10NRA== =m9+F -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2024-10-31' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes Short summary of fixes pull: ivpu: - Fix firewall IRQ handling panthor: - Fix firmware initialization wrt page sizes - Fix handling and reporting of dead job groups sched: - Guarantee forward progress via WC_MEM_RECLAIM tests: - Fix memory leak in drm_display_mode_from_cea_vic() Signed-off-by: Dave Airlie <airlied@redhat.com> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20241031144348.GA7826@linux-2.fritz.box
This commit is contained in:
commit
989c5b9051
|
|
@ -108,6 +108,14 @@ static int reset_pending_show(struct seq_file *s, void *v)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int firewall_irq_counter_show(struct seq_file *s, void *v)
|
||||
{
|
||||
struct ivpu_device *vdev = seq_to_ivpu(s);
|
||||
|
||||
seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_debugfs_info vdev_debugfs_list[] = {
|
||||
{"bo_list", bo_list_show, 0},
|
||||
{"fw_name", fw_name_show, 0},
|
||||
|
|
@ -116,6 +124,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = {
|
|||
{"last_bootmode", last_bootmode_show, 0},
|
||||
{"reset_counter", reset_counter_show, 0},
|
||||
{"reset_pending", reset_pending_show, 0},
|
||||
{"firewall_irq_counter", firewall_irq_counter_show, 0},
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
|
|
|
|||
|
|
@ -249,6 +249,7 @@ int ivpu_hw_init(struct ivpu_device *vdev)
|
|||
platform_init(vdev);
|
||||
wa_init(vdev);
|
||||
timeouts_init(vdev);
|
||||
atomic_set(&vdev->hw->firewall_irq_counter, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ struct ivpu_hw_info {
|
|||
int dma_bits;
|
||||
ktime_t d0i3_entry_host_ts;
|
||||
u64 d0i3_entry_vpu_ts;
|
||||
atomic_t firewall_irq_counter;
|
||||
};
|
||||
|
||||
int ivpu_hw_init(struct ivpu_device *vdev);
|
||||
|
|
|
|||
|
|
@ -1062,7 +1062,10 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev)
|
|||
|
||||
static void irq_noc_firewall_handler(struct ivpu_device *vdev)
|
||||
{
|
||||
ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ");
|
||||
atomic_inc(&vdev->hw->firewall_irq_counter);
|
||||
|
||||
ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",
|
||||
atomic_read(&vdev->hw->firewall_irq_counter));
|
||||
}
|
||||
|
||||
/* Handler for IRQs from NPU core */
|
||||
|
|
|
|||
|
|
@ -487,6 +487,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
|
|||
struct panthor_fw_binary_iter *iter,
|
||||
u32 ehdr)
|
||||
{
|
||||
ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm);
|
||||
struct panthor_fw_binary_section_entry_hdr hdr;
|
||||
struct panthor_fw_section *section;
|
||||
u32 section_size;
|
||||
|
|
@ -515,8 +516,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((hdr.va.start & ~PAGE_MASK) != 0 ||
|
||||
(hdr.va.end & ~PAGE_MASK) != 0) {
|
||||
if (!IS_ALIGNED(hdr.va.start, vm_pgsz) || !IS_ALIGNED(hdr.va.end, vm_pgsz)) {
|
||||
drm_err(&ptdev->base, "Firmware corrupted, virtual addresses not page aligned: 0x%x-0x%x\n",
|
||||
hdr.va.start, hdr.va.end);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo)
|
|||
to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm)))
|
||||
goto out_free_bo;
|
||||
|
||||
ret = panthor_vm_unmap_range(vm, bo->va_node.start,
|
||||
panthor_kernel_bo_size(bo));
|
||||
ret = panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size);
|
||||
if (ret)
|
||||
goto out_free_bo;
|
||||
|
||||
|
|
@ -95,10 +94,16 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm,
|
|||
}
|
||||
|
||||
bo = to_panthor_bo(&obj->base);
|
||||
size = obj->base.size;
|
||||
kbo->obj = &obj->base;
|
||||
bo->flags = bo_flags;
|
||||
|
||||
/* The system and GPU MMU page size might differ, which becomes a
|
||||
* problem for FW sections that need to be mapped at explicit address
|
||||
* since our PAGE_SIZE alignment might cover a VA range that's
|
||||
* expected to be used for another section.
|
||||
* Make sure we never map more than we need.
|
||||
*/
|
||||
size = ALIGN(size, panthor_vm_page_size(vm));
|
||||
ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node);
|
||||
if (ret)
|
||||
goto err_put_obj;
|
||||
|
|
|
|||
|
|
@ -826,6 +826,14 @@ void panthor_vm_idle(struct panthor_vm *vm)
|
|||
mutex_unlock(&ptdev->mmu->as.slots_lock);
|
||||
}
|
||||
|
||||
u32 panthor_vm_page_size(struct panthor_vm *vm)
|
||||
{
|
||||
const struct io_pgtable *pgt = io_pgtable_ops_to_pgtable(vm->pgtbl_ops);
|
||||
u32 pg_shift = ffs(pgt->cfg.pgsize_bitmap) - 1;
|
||||
|
||||
return 1u << pg_shift;
|
||||
}
|
||||
|
||||
static void panthor_vm_stop(struct panthor_vm *vm)
|
||||
{
|
||||
drm_sched_stop(&vm->sched, NULL);
|
||||
|
|
@ -1025,12 +1033,13 @@ int
|
|||
panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, u64 size,
|
||||
struct drm_mm_node *va_node)
|
||||
{
|
||||
ssize_t vm_pgsz = panthor_vm_page_size(vm);
|
||||
int ret;
|
||||
|
||||
if (!size || (size & ~PAGE_MASK))
|
||||
if (!size || !IS_ALIGNED(size, vm_pgsz))
|
||||
return -EINVAL;
|
||||
|
||||
if (va != PANTHOR_VM_KERNEL_AUTO_VA && (va & ~PAGE_MASK))
|
||||
if (va != PANTHOR_VM_KERNEL_AUTO_VA && !IS_ALIGNED(va, vm_pgsz))
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&vm->mm_lock);
|
||||
|
|
@ -2366,11 +2375,12 @@ panthor_vm_bind_prepare_op_ctx(struct drm_file *file,
|
|||
const struct drm_panthor_vm_bind_op *op,
|
||||
struct panthor_vm_op_ctx *op_ctx)
|
||||
{
|
||||
ssize_t vm_pgsz = panthor_vm_page_size(vm);
|
||||
struct drm_gem_object *gem;
|
||||
int ret;
|
||||
|
||||
/* Aligned on page size. */
|
||||
if ((op->va | op->size) & ~PAGE_MASK)
|
||||
if (!IS_ALIGNED(op->va | op->size, vm_pgsz))
|
||||
return -EINVAL;
|
||||
|
||||
switch (op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ panthor_vm_get_bo_for_va(struct panthor_vm *vm, u64 va, u64 *bo_offset);
|
|||
|
||||
int panthor_vm_active(struct panthor_vm *vm);
|
||||
void panthor_vm_idle(struct panthor_vm *vm);
|
||||
u32 panthor_vm_page_size(struct panthor_vm *vm);
|
||||
int panthor_vm_as(struct panthor_vm *vm);
|
||||
int panthor_vm_flush_all(struct panthor_vm *vm);
|
||||
|
||||
|
|
|
|||
|
|
@ -589,10 +589,11 @@ struct panthor_group {
|
|||
* @timedout: True when a timeout occurred on any of the queues owned by
|
||||
* this group.
|
||||
*
|
||||
* Timeouts can be reported by drm_sched or by the FW. In any case, any
|
||||
* timeout situation is unrecoverable, and the group becomes useless.
|
||||
* We simply wait for all references to be dropped so we can release the
|
||||
* group object.
|
||||
* Timeouts can be reported by drm_sched or by the FW. If a reset is required,
|
||||
* and the group can't be suspended, this also leads to a timeout. In any case,
|
||||
* any timeout situation is unrecoverable, and the group becomes useless. We
|
||||
* simply wait for all references to be dropped so we can release the group
|
||||
* object.
|
||||
*/
|
||||
bool timedout;
|
||||
|
||||
|
|
@ -2640,6 +2641,12 @@ void panthor_sched_suspend(struct panthor_device *ptdev)
|
|||
csgs_upd_ctx_init(&upd_ctx);
|
||||
while (slot_mask) {
|
||||
u32 csg_id = ffs(slot_mask) - 1;
|
||||
struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id];
|
||||
|
||||
/* We consider group suspension failures as fatal and flag the
|
||||
* group as unusable by setting timedout=true.
|
||||
*/
|
||||
csg_slot->group->timedout = true;
|
||||
|
||||
csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id,
|
||||
CSG_STATE_TERMINATE,
|
||||
|
|
@ -3409,6 +3416,11 @@ panthor_job_create(struct panthor_file *pfile,
|
|||
goto err_put_job;
|
||||
}
|
||||
|
||||
if (!group_can_run(job->group)) {
|
||||
ret = -EINVAL;
|
||||
goto err_put_job;
|
||||
}
|
||||
|
||||
if (job->queue_idx >= job->group->queue_count ||
|
||||
!job->group->queues[job->queue_idx]) {
|
||||
ret = -EINVAL;
|
||||
|
|
|
|||
|
|
@ -1276,10 +1276,11 @@ int drm_sched_init(struct drm_gpu_scheduler *sched,
|
|||
sched->own_submit_wq = false;
|
||||
} else {
|
||||
#ifdef CONFIG_LOCKDEP
|
||||
sched->submit_wq = alloc_ordered_workqueue_lockdep_map(name, 0,
|
||||
sched->submit_wq = alloc_ordered_workqueue_lockdep_map(name,
|
||||
WQ_MEM_RECLAIM,
|
||||
&drm_sched_lockdep_map);
|
||||
#else
|
||||
sched->submit_wq = alloc_ordered_workqueue(name, 0);
|
||||
sched->submit_wq = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM);
|
||||
#endif
|
||||
if (!sched->submit_wq)
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -1153,8 +1153,8 @@ static int host1x_drm_probe(struct host1x_device *dev)
|
|||
|
||||
if (host1x_drm_wants_iommu(dev) && device_iommu_mapped(dma_dev)) {
|
||||
tegra->domain = iommu_paging_domain_alloc(dma_dev);
|
||||
if (!tegra->domain) {
|
||||
err = -ENOMEM;
|
||||
if (IS_ERR(tegra->domain)) {
|
||||
err = PTR_ERR(tegra->domain);
|
||||
goto free;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -996,7 +996,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
|
|||
unsigned long long rate;
|
||||
struct drm_device *drm = &priv->drm;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 16);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1017,7 +1017,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
|
|||
unsigned long long rate;
|
||||
struct drm_device *drm = &priv->drm;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 16);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1038,7 +1038,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *t
|
|||
unsigned long long rate;
|
||||
struct drm_device *drm = &priv->drm;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 1);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
|
||||
|
|
@ -1056,7 +1056,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
|
|||
unsigned long long rate;
|
||||
struct drm_device *drm = &priv->drm;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 16);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1077,7 +1077,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *t
|
|||
unsigned long long rate;
|
||||
struct drm_device *drm = &priv->drm;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 1);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
|
||||
|
|
@ -1095,7 +1095,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
|
|||
unsigned long long rate;
|
||||
struct drm_device *drm = &priv->drm;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 6);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1118,7 +1118,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit
|
|||
unsigned long long rate;
|
||||
unsigned int vic = *(unsigned int *)test->param_value;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, vic);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1155,7 +1155,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kuni
|
|||
drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
|
||||
unsigned long long rate;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, vic);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1180,7 +1180,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kuni
|
|||
drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
|
||||
unsigned long long rate;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, vic);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1203,7 +1203,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit
|
|||
struct drm_device *drm = &priv->drm;
|
||||
unsigned long long rate;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 16);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1225,7 +1225,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kuni
|
|||
struct drm_device *drm = &priv->drm;
|
||||
unsigned long long rate;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 16);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
@ -1247,7 +1247,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kuni
|
|||
struct drm_device *drm = &priv->drm;
|
||||
unsigned long long rate;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 16);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
|
||||
|
|
|
|||
|
|
@ -441,7 +441,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
|
|||
ctx = drm_kunit_helper_acquire_ctx_alloc(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 1);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
drm = &priv->drm;
|
||||
|
|
@ -555,7 +555,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
|
|||
ctx = drm_kunit_helper_acquire_ctx_alloc(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 1);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
drm = &priv->drm;
|
||||
|
|
@ -671,7 +671,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te
|
|||
ctx = drm_kunit_helper_acquire_ctx_alloc(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 1);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
drm = &priv->drm;
|
||||
|
|
@ -1263,7 +1263,7 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
|
|||
ctx = drm_kunit_helper_acquire_ctx_alloc(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(drm, 1);
|
||||
mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
#include <drm/drm_managed.h>
|
||||
|
|
@ -311,6 +312,47 @@ drm_kunit_helper_create_crtc(struct kunit *test,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc);
|
||||
|
||||
static void kunit_action_drm_mode_destroy(void *ptr)
|
||||
{
|
||||
struct drm_display_mode *mode = ptr;
|
||||
|
||||
drm_mode_destroy(NULL, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC
|
||||
for a KUnit test
|
||||
* @test: The test context object
|
||||
* @dev: DRM device
|
||||
* @video_code: CEA VIC of the mode
|
||||
*
|
||||
* Creates a new mode matching the specified CEA VIC for a KUnit test.
|
||||
*
|
||||
* Resources will be cleaned up automatically.
|
||||
*
|
||||
* Returns: A new drm_display_mode on success or NULL on failure
|
||||
*/
|
||||
struct drm_display_mode *
|
||||
drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
|
||||
u8 video_code)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
int ret;
|
||||
|
||||
mode = drm_display_mode_from_cea_vic(dev, video_code);
|
||||
if (!mode)
|
||||
return NULL;
|
||||
|
||||
ret = kunit_add_action_or_reset(test,
|
||||
kunit_action_drm_mode_destroy,
|
||||
mode);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
return mode;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_kunit_display_mode_from_cea_vic);
|
||||
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
|
||||
MODULE_DESCRIPTION("KUnit test suite helper functions");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -120,4 +120,8 @@ drm_kunit_helper_create_crtc(struct kunit *test,
|
|||
const struct drm_crtc_funcs *funcs,
|
||||
const struct drm_crtc_helper_funcs *helper_funcs);
|
||||
|
||||
struct drm_display_mode *
|
||||
drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
|
||||
u8 video_code);
|
||||
|
||||
#endif // DRM_KUNIT_HELPERS_H_
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user