mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-23 17:46:33 -04:00
drm/amd/display: Add KUnit tests for amdgpu_dm_irq
Add KUnit tests for helper functions, IRQ table management paths, and DRM mock-backed CRTC lookup in amdgpu_dm_irq.c. Tests cover: - amdgpu_dm_hpd_to_dal_irq_source(): all HPD types 1-6, AMDGPU_HPD_NONE, and out-of-range values - are_sinks_equal(): NULL inputs, signal mismatch, EDID length mismatch, EDID data mismatch, identical sinks, zero-length EDID, full-length identical EDID, and a single trailing-byte difference - dmub_notification_type_str(): notification type mappings that are always built, plus the unknown/default case - amdgpu_dm_irq_init(): low/high handler list initialization - amdgpu_dm_irq_register_interrupt(): NULL input rejection, invalid context/source rejection, low/high handler insertion, multiple handlers on one source, and the same handler registered in both low and high contexts - amdgpu_dm_irq_unregister_interrupt(): invalid source and NULL handler rejection, removal of registered low/high handlers, and the handler-not-found path - amdgpu_dm_irq_fini(): cleanup of registered low/high handlers and the empty-table case - amdgpu_dm_get_crtc_by_otg_inst(): DRM mock CRTC list match, no-match, and empty-list paths Assisted-by: Copilot:Claude-Opus-4 Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Chenyu Chen <chen-yu.chen@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include "amdgpu_display.h"
|
||||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_irq.h"
|
||||
#include "amdgpu_dm_kunit_helpers.h"
|
||||
#include "amdgpu_dm_crtc.h"
|
||||
#include "amdgpu_dm_hdcp.h"
|
||||
#include "amdgpu_dm_mst_types.h"
|
||||
@@ -372,6 +373,7 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev,
|
||||
|
||||
return handler_data;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_irq_register_interrupt);
|
||||
|
||||
/**
|
||||
* amdgpu_dm_irq_unregister_interrupt() - Remove a handler from the DM IRQ table
|
||||
@@ -416,6 +418,7 @@ void amdgpu_dm_irq_unregister_interrupt(struct amdgpu_device *adev,
|
||||
ih, irq_source);
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_irq_unregister_interrupt);
|
||||
|
||||
/**
|
||||
* amdgpu_dm_irq_init() - Initialize DM IRQ management
|
||||
@@ -450,6 +453,7 @@ int amdgpu_dm_irq_init(struct amdgpu_device *adev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_irq_init);
|
||||
|
||||
/**
|
||||
* amdgpu_dm_irq_fini() - Tear down DM IRQ management
|
||||
@@ -488,6 +492,7 @@ void amdgpu_dm_irq_fini(struct amdgpu_device *adev)
|
||||
/* Deallocate handlers from the table. */
|
||||
unregister_all_irq_handlers(adev);
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_irq_fini);
|
||||
|
||||
void amdgpu_dm_irq_suspend(struct amdgpu_device *adev)
|
||||
{
|
||||
@@ -690,7 +695,7 @@ static int amdgpu_dm_irq_handler(struct amdgpu_device *adev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum dc_irq_source amdgpu_dm_hpd_to_dal_irq_source(unsigned int type)
|
||||
STATIC_IFN_KUNIT enum dc_irq_source amdgpu_dm_hpd_to_dal_irq_source(unsigned int type)
|
||||
{
|
||||
switch (type) {
|
||||
case AMDGPU_HPD_1:
|
||||
@@ -709,6 +714,7 @@ static enum dc_irq_source amdgpu_dm_hpd_to_dal_irq_source(unsigned int type)
|
||||
return DC_IRQ_SOURCE_INVALID;
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_hpd_to_dal_irq_source);
|
||||
|
||||
static int amdgpu_dm_set_hpd_irq_state(struct amdgpu_device *adev,
|
||||
struct amdgpu_irq_src *source,
|
||||
@@ -1192,7 +1198,7 @@ void amdgpu_dm_hpd_rx_irq_work_suspend(struct amdgpu_display_manager *dm)
|
||||
}
|
||||
}
|
||||
|
||||
static bool are_sinks_equal(const struct dc_sink *sink1, const struct dc_sink *sink2)
|
||||
STATIC_IFN_KUNIT bool are_sinks_equal(const struct dc_sink *sink1, const struct dc_sink *sink2)
|
||||
{
|
||||
if (!sink1 || !sink2)
|
||||
return false;
|
||||
@@ -1207,6 +1213,7 @@ static bool are_sinks_equal(const struct dc_sink *sink1, const struct dc_sink *s
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
EXPORT_IF_KUNIT(are_sinks_equal);
|
||||
|
||||
|
||||
/**
|
||||
@@ -1692,6 +1699,7 @@ amdgpu_dm_get_crtc_by_otg_inst(struct amdgpu_device *adev,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_get_crtc_by_otg_inst);
|
||||
|
||||
/**
|
||||
* dm_pflip_high_irq() - Handle pageflip interrupt
|
||||
@@ -2067,7 +2075,7 @@ static void dm_handle_hpd_work(struct work_struct *work)
|
||||
|
||||
}
|
||||
|
||||
static const char *dmub_notification_type_str(enum dmub_notification_type e)
|
||||
STATIC_IFN_KUNIT const char *dmub_notification_type_str(enum dmub_notification_type e)
|
||||
{
|
||||
switch (e) {
|
||||
case DMUB_NOTIFICATION_NO_DATA:
|
||||
@@ -2090,6 +2098,7 @@ static const char *dmub_notification_type_str(enum dmub_notification_type e)
|
||||
return "<unknown>";
|
||||
}
|
||||
}
|
||||
EXPORT_IF_KUNIT(dmub_notification_type_str);
|
||||
|
||||
#define DMUB_TRACE_MAX_READ 64
|
||||
/**
|
||||
|
||||
@@ -30,8 +30,10 @@
|
||||
struct amdgpu_device;
|
||||
struct amdgpu_crtc;
|
||||
struct amdgpu_display_manager;
|
||||
struct dc_sink;
|
||||
struct hpd_rx_irq_offload_work_queue;
|
||||
struct work_struct;
|
||||
enum dmub_notification_type;
|
||||
|
||||
/*
|
||||
* Display Manager IRQ-related interfaces (for use by DAL).
|
||||
@@ -120,4 +122,10 @@ int amdgpu_dm_dce110_register_irq_handlers(struct amdgpu_device *adev);
|
||||
int amdgpu_dm_dcn10_register_irq_handlers(struct amdgpu_device *adev);
|
||||
int amdgpu_dm_register_outbox_irq_handlers(struct amdgpu_device *adev);
|
||||
|
||||
#if IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
|
||||
enum dc_irq_source amdgpu_dm_hpd_to_dal_irq_source(unsigned int type);
|
||||
bool are_sinks_equal(const struct dc_sink *sink1, const struct dc_sink *sink2);
|
||||
const char *dmub_notification_type_str(enum dmub_notification_type e);
|
||||
#endif
|
||||
|
||||
#endif /* __AMDGPU_DM_IRQ_H__ */
|
||||
|
||||
@@ -22,6 +22,7 @@ obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_dmub_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_psr_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_replay_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_ism_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_irq_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_wb_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_mst_types_test.o
|
||||
obj-$(CONFIG_DRM_AMD_DC_KUNIT_TEST) += amdgpu_dm_pp_smu_test.o
|
||||
|
||||
934
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
Normal file
934
drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_irq_test.c
Normal file
@@ -0,0 +1,934 @@
|
||||
// SPDX-License-Identifier: GPL-2.0 OR MIT
|
||||
/*
|
||||
* KUnit tests for amdgpu_dm_irq.c
|
||||
*
|
||||
* Copyright 2026 Advanced Micro Devices, Inc.
|
||||
*/
|
||||
|
||||
#include <kunit/test.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
|
||||
#include "dc.h"
|
||||
#include "amdgpu.h"
|
||||
#include "amdgpu_mode.h"
|
||||
#include "amdgpu_dm.h"
|
||||
#include "amdgpu_dm_irq.h"
|
||||
#include "dmub/dmub_srv.h"
|
||||
|
||||
static void dm_test_irq_handler(void *arg)
|
||||
{
|
||||
}
|
||||
|
||||
static void dm_test_irq_handler_alt(void *arg)
|
||||
{
|
||||
}
|
||||
|
||||
static void dm_test_crtc_list_del(void *data)
|
||||
{
|
||||
struct amdgpu_crtc *acrtc = data;
|
||||
|
||||
list_del_init(&acrtc->base.head);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_hpd_to_dal_irq_source() */
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_hpd1 - Test Hpd to dal irq source hpd1
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_hpd1(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(AMDGPU_HPD_1),
|
||||
(int)DC_IRQ_SOURCE_HPD1);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_hpd2 - Test Hpd to dal irq source hpd2
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_hpd2(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(AMDGPU_HPD_2),
|
||||
(int)DC_IRQ_SOURCE_HPD2);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_hpd3 - Test Hpd to dal irq source hpd3
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_hpd3(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(AMDGPU_HPD_3),
|
||||
(int)DC_IRQ_SOURCE_HPD3);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_hpd4 - Test Hpd to dal irq source hpd4
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_hpd4(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(AMDGPU_HPD_4),
|
||||
(int)DC_IRQ_SOURCE_HPD4);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_hpd5 - Test Hpd to dal irq source hpd5
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_hpd5(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(AMDGPU_HPD_5),
|
||||
(int)DC_IRQ_SOURCE_HPD5);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_hpd6 - Test Hpd to dal irq source hpd6
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_hpd6(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(AMDGPU_HPD_6),
|
||||
(int)DC_IRQ_SOURCE_HPD6);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_invalid - Test Hpd to dal irq source invalid
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_invalid(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(AMDGPU_HPD_NONE),
|
||||
(int)DC_IRQ_SOURCE_INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_hpd_to_dal_irq_source_out_of_range - Test Hpd to dal irq source out of range
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_hpd_to_dal_irq_source_out_of_range(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_EQ(test, (int)amdgpu_dm_hpd_to_dal_irq_source(99),
|
||||
(int)DC_IRQ_SOURCE_INVALID);
|
||||
}
|
||||
|
||||
/* Tests for are_sinks_equal() */
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_both_null - Test Are sinks equal both null
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_both_null(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_FALSE(test, are_sinks_equal(NULL, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_first_null - Test Are sinks equal first null
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_first_null(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink2;
|
||||
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, are_sinks_equal(NULL, sink2));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_second_null - Test Are sinks equal second null
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_second_null(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, are_sinks_equal(sink1, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_different_signal - Test Are sinks equal different signal
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_different_signal(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1, *sink2;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
sink1->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink2->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, are_sinks_equal(sink1, sink2));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_different_edid_length - Test Are sinks equal different edid length
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_different_edid_length(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1, *sink2;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
sink1->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink2->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink1->dc_edid.length = 128;
|
||||
sink2->dc_edid.length = 256;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, are_sinks_equal(sink1, sink2));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_different_edid_data - Test Are sinks equal different edid data
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_different_edid_data(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1, *sink2;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
sink1->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink2->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink1->dc_edid.length = 4;
|
||||
sink2->dc_edid.length = 4;
|
||||
memset(sink1->dc_edid.raw_edid, 0xAA, 4);
|
||||
memset(sink2->dc_edid.raw_edid, 0xBB, 4);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, are_sinks_equal(sink1, sink2));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_identical - Test Are sinks equal identical
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_identical(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1, *sink2;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
sink1->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink2->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink1->dc_edid.length = 4;
|
||||
sink2->dc_edid.length = 4;
|
||||
memset(sink1->dc_edid.raw_edid, 0xAA, 4);
|
||||
memset(sink2->dc_edid.raw_edid, 0xAA, 4);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, are_sinks_equal(sink1, sink2));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_zero_length - Test Are sinks equal zero length
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_zero_length(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1, *sink2;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
sink1->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
|
||||
sink2->sink_signal = SIGNAL_TYPE_DISPLAY_PORT;
|
||||
sink1->dc_edid.length = 0;
|
||||
sink2->dc_edid.length = 0;
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, are_sinks_equal(sink1, sink2));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_full_edid_identical - Test Are sinks equal full edid identical
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_full_edid_identical(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1, *sink2;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
sink1->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink2->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink1->dc_edid.length = 128;
|
||||
sink2->dc_edid.length = 128;
|
||||
memset(sink1->dc_edid.raw_edid, 0x5A, 128);
|
||||
memset(sink2->dc_edid.raw_edid, 0x5A, 128);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, are_sinks_equal(sink1, sink2));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_are_sinks_equal_full_edid_last_byte_differs - Test Are sinks equal last byte differs
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_are_sinks_equal_full_edid_last_byte_differs(struct kunit *test)
|
||||
{
|
||||
struct dc_sink *sink1, *sink2;
|
||||
|
||||
sink1 = kunit_kzalloc(test, sizeof(*sink1), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink1);
|
||||
sink2 = kunit_kzalloc(test, sizeof(*sink2), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sink2);
|
||||
|
||||
sink1->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink2->sink_signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||
sink1->dc_edid.length = 128;
|
||||
sink2->dc_edid.length = 128;
|
||||
memset(sink1->dc_edid.raw_edid, 0x5A, 128);
|
||||
memset(sink2->dc_edid.raw_edid, 0x5A, 128);
|
||||
sink2->dc_edid.raw_edid[127] = 0x5B;
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, are_sinks_equal(sink1, sink2));
|
||||
}
|
||||
|
||||
/* Tests for dmub_notification_type_str() */
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_no_data - Test Notification str no data
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_no_data(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_NO_DATA), "NO_DATA");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_aux_reply - Test Notification str aux reply
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_aux_reply(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_AUX_REPLY), "AUX_REPLY");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_hpd - Test Notification str hpd
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_hpd(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_HPD), "HPD");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_hpd_irq - Test Notification str hpd irq
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_hpd_irq(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_HPD_IRQ), "HPD_IRQ");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_set_config - Test Notification str set config
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_set_config(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_SET_CONFIG_REPLY),
|
||||
"SET_CONFIG_REPLY");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_dpia - Test Notification str dpia
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_dpia(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_DPIA_NOTIFICATION),
|
||||
"DPIA_NOTIFICATION");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_hpd_sense - Test Notification str hpd sense
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_hpd_sense(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_HPD_SENSE_NOTIFY),
|
||||
"HPD_SENSE_NOTIFY");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_fused_io - Test Notification str fused io
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_fused_io(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_FUSED_IO),
|
||||
"FUSED_IO");
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_notification_str_unknown - Test Notification str unknown
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_notification_str_unknown(struct kunit *test)
|
||||
{
|
||||
KUNIT_EXPECT_STREQ(test, dmub_notification_type_str(DMUB_NOTIFICATION_MAX), "<unknown>");
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_irq_init() */
|
||||
|
||||
/**
|
||||
* dm_test_irq_init_initializes_lists - Test irq init initializes list heads
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_init_initializes_lists(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
int src;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[src]));
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[src]));
|
||||
}
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_irq_register_interrupt() */
|
||||
|
||||
/**
|
||||
* dm_test_irq_register_rejects_null_params - Test register rejects null params
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_register_rejects_null_params(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
|
||||
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD1;
|
||||
|
||||
KUNIT_EXPECT_NULL(test,
|
||||
amdgpu_dm_irq_register_interrupt(adev, NULL,
|
||||
dm_test_irq_handler, NULL));
|
||||
KUNIT_EXPECT_NULL(test,
|
||||
amdgpu_dm_irq_register_interrupt(adev, &int_params, NULL, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_register_rejects_invalid_context - Test register rejects context
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_register_rejects_invalid_context(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
|
||||
int_params.int_context = INTERRUPT_CONTEXT_NUMBER;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD1;
|
||||
|
||||
KUNIT_EXPECT_NULL(test,
|
||||
amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_register_rejects_invalid_source - Test register rejects source
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_register_rejects_invalid_source(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
|
||||
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_INVALID;
|
||||
|
||||
KUNIT_EXPECT_NULL(test,
|
||||
amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_register_adds_low_context_handler - Test register adds low handler
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_register_adds_low_context_handler(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
void *handler;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD1;
|
||||
|
||||
handler = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler);
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD1,
|
||||
dm_test_irq_handler);
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_register_adds_high_context_handler - Test register adds high handler
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_register_adds_high_context_handler(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
void *handler;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD2;
|
||||
|
||||
handler = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler);
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD2]));
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD2]));
|
||||
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD2,
|
||||
dm_test_irq_handler);
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD2]));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_register_multiple_handlers - Test register keeps multiple handlers
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_register_multiple_handlers(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
struct list_head *hnd_list;
|
||||
void *handler1, *handler2;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD1;
|
||||
|
||||
handler1 = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler1);
|
||||
handler2 = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler_alt, adev);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler2);
|
||||
|
||||
hnd_list = &adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD1];
|
||||
KUNIT_EXPECT_EQ(test, list_count_nodes(hnd_list), 2);
|
||||
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD1,
|
||||
dm_test_irq_handler);
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD1,
|
||||
dm_test_irq_handler_alt);
|
||||
KUNIT_EXPECT_TRUE(test, list_empty(hnd_list));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_register_separate_contexts - Test register same source in two contexts
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_register_separate_contexts(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
void *handler;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD5;
|
||||
|
||||
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
|
||||
handler = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler);
|
||||
|
||||
int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
|
||||
handler = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD5]));
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD5]));
|
||||
|
||||
/*
|
||||
* A single unregister call stops at the first context where the handler
|
||||
* is found (low context), leaving the high context handler in place.
|
||||
*/
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD5,
|
||||
dm_test_irq_handler);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD5]));
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD5]));
|
||||
|
||||
/* A second call removes the remaining high context handler. */
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD5,
|
||||
dm_test_irq_handler);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD5]));
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_irq_unregister_interrupt() */
|
||||
|
||||
/**
|
||||
* dm_test_irq_unregister_rejects_invalid_source - Test unregister rejects source
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_unregister_rejects_invalid_source(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_INVALID,
|
||||
dm_test_irq_handler);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_unregister_rejects_null_handler - Test unregister rejects handler
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_unregister_rejects_null_handler(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD1,
|
||||
DAL_INVALID_IRQ_HANDLER_IDX);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_unregister_handler_not_found - Test unregister keeps unmatched handler
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_unregister_handler_not_found(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
void *handler;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD1;
|
||||
handler = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler);
|
||||
|
||||
/* Unregister a handler that was never registered for this source. */
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD1,
|
||||
dm_test_irq_handler_alt);
|
||||
|
||||
/* The originally registered handler must still be present. */
|
||||
KUNIT_EXPECT_FALSE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
|
||||
amdgpu_dm_irq_unregister_interrupt(adev, DC_IRQ_SOURCE_HPD1,
|
||||
dm_test_irq_handler);
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD1]));
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_irq_fini() */
|
||||
|
||||
/**
|
||||
* dm_test_irq_fini_removes_registered_handlers - Test fini removes handlers
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_fini_removes_registered_handlers(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct dc_interrupt_params int_params = { 0 };
|
||||
void *handler;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
int_params.int_context = INTERRUPT_LOW_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD3;
|
||||
handler = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler);
|
||||
|
||||
int_params.int_context = INTERRUPT_HIGH_IRQ_CONTEXT;
|
||||
int_params.irq_source = DC_IRQ_SOURCE_HPD4;
|
||||
handler = amdgpu_dm_irq_register_interrupt(adev, &int_params,
|
||||
dm_test_irq_handler, adev);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, handler);
|
||||
|
||||
amdgpu_dm_irq_fini(adev);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[DC_IRQ_SOURCE_HPD3]));
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[DC_IRQ_SOURCE_HPD4]));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_irq_fini_on_empty_tables - Test fini on tables with no handlers
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_irq_fini_on_empty_tables(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
int src;
|
||||
|
||||
adev = kunit_kzalloc(test, sizeof(*adev), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
KUNIT_ASSERT_EQ(test, amdgpu_dm_irq_init(adev), 0);
|
||||
|
||||
amdgpu_dm_irq_fini(adev);
|
||||
|
||||
for (src = 0; src < DAL_IRQ_SOURCES_NUMBER; src++) {
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_low_tab[src]));
|
||||
KUNIT_EXPECT_TRUE(test,
|
||||
list_empty(&adev->dm.irq_handler_list_high_tab[src]));
|
||||
}
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_get_crtc_by_otg_inst() */
|
||||
|
||||
/**
|
||||
* dm_test_get_crtc_by_otg_inst_returns_match - Test CRTC lookup by OTG instance
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_get_crtc_by_otg_inst_returns_match(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_crtc *acrtc_a, *acrtc_b;
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
|
||||
dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
drm = __drm_kunit_helper_alloc_drm_device(test, dev,
|
||||
sizeof(*adev),
|
||||
offsetof(struct amdgpu_device, ddev),
|
||||
DRIVER_MODESET);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
|
||||
adev = drm_to_adev(drm);
|
||||
|
||||
acrtc_a = kunit_kzalloc(test, sizeof(*acrtc_a), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, acrtc_a);
|
||||
acrtc_b = kunit_kzalloc(test, sizeof(*acrtc_b), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, acrtc_b);
|
||||
|
||||
INIT_LIST_HEAD(&acrtc_a->base.head);
|
||||
INIT_LIST_HEAD(&acrtc_b->base.head);
|
||||
acrtc_a->otg_inst = 1;
|
||||
acrtc_b->otg_inst = 3;
|
||||
|
||||
list_add_tail(&acrtc_a->base.head, &drm->mode_config.crtc_list);
|
||||
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, dm_test_crtc_list_del,
|
||||
acrtc_a), 0);
|
||||
list_add_tail(&acrtc_b->base.head, &drm->mode_config.crtc_list);
|
||||
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, dm_test_crtc_list_del,
|
||||
acrtc_b), 0);
|
||||
|
||||
KUNIT_EXPECT_PTR_EQ(test, amdgpu_dm_get_crtc_by_otg_inst(adev, 3), acrtc_b);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_get_crtc_by_otg_inst_returns_null - Test CRTC lookup misses unknown OTG
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_get_crtc_by_otg_inst_returns_null(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_crtc *acrtc;
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
|
||||
dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
drm = __drm_kunit_helper_alloc_drm_device(test, dev,
|
||||
sizeof(*adev),
|
||||
offsetof(struct amdgpu_device, ddev),
|
||||
DRIVER_MODESET);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
|
||||
adev = drm_to_adev(drm);
|
||||
|
||||
acrtc = kunit_kzalloc(test, sizeof(*acrtc), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, acrtc);
|
||||
|
||||
INIT_LIST_HEAD(&acrtc->base.head);
|
||||
acrtc->otg_inst = 2;
|
||||
|
||||
list_add_tail(&acrtc->base.head, &drm->mode_config.crtc_list);
|
||||
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, dm_test_crtc_list_del,
|
||||
acrtc), 0);
|
||||
|
||||
KUNIT_EXPECT_NULL(test, amdgpu_dm_get_crtc_by_otg_inst(adev, 5));
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_get_crtc_by_otg_inst_empty_list - Test CRTC lookup on empty CRTC list
|
||||
* @test: The KUnit test context
|
||||
*/
|
||||
static void dm_test_get_crtc_by_otg_inst_empty_list(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
|
||||
dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
drm = __drm_kunit_helper_alloc_drm_device(test, dev,
|
||||
sizeof(*adev),
|
||||
offsetof(struct amdgpu_device, ddev),
|
||||
DRIVER_MODESET);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
|
||||
adev = drm_to_adev(drm);
|
||||
|
||||
KUNIT_EXPECT_NULL(test, amdgpu_dm_get_crtc_by_otg_inst(adev, 0));
|
||||
}
|
||||
|
||||
static struct kunit_case amdgpu_dm_irq_tests[] = {
|
||||
/* amdgpu_dm_hpd_to_dal_irq_source */
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_hpd1),
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_hpd2),
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_hpd3),
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_hpd4),
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_hpd5),
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_hpd6),
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_invalid),
|
||||
KUNIT_CASE(dm_test_hpd_to_dal_irq_source_out_of_range),
|
||||
/* are_sinks_equal */
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_both_null),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_first_null),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_second_null),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_different_signal),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_different_edid_length),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_different_edid_data),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_identical),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_zero_length),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_full_edid_identical),
|
||||
KUNIT_CASE(dm_test_are_sinks_equal_full_edid_last_byte_differs),
|
||||
/* dmub_notification_type_str */
|
||||
KUNIT_CASE(dm_test_notification_str_no_data),
|
||||
KUNIT_CASE(dm_test_notification_str_aux_reply),
|
||||
KUNIT_CASE(dm_test_notification_str_hpd),
|
||||
KUNIT_CASE(dm_test_notification_str_hpd_irq),
|
||||
KUNIT_CASE(dm_test_notification_str_set_config),
|
||||
KUNIT_CASE(dm_test_notification_str_dpia),
|
||||
KUNIT_CASE(dm_test_notification_str_hpd_sense),
|
||||
KUNIT_CASE(dm_test_notification_str_fused_io),
|
||||
KUNIT_CASE(dm_test_notification_str_unknown),
|
||||
/* amdgpu_dm_irq_init */
|
||||
KUNIT_CASE(dm_test_irq_init_initializes_lists),
|
||||
/* amdgpu_dm_irq_register_interrupt */
|
||||
KUNIT_CASE(dm_test_irq_register_rejects_null_params),
|
||||
KUNIT_CASE(dm_test_irq_register_rejects_invalid_context),
|
||||
KUNIT_CASE(dm_test_irq_register_rejects_invalid_source),
|
||||
KUNIT_CASE(dm_test_irq_register_adds_low_context_handler),
|
||||
KUNIT_CASE(dm_test_irq_register_adds_high_context_handler),
|
||||
KUNIT_CASE(dm_test_irq_register_multiple_handlers),
|
||||
KUNIT_CASE(dm_test_irq_register_separate_contexts),
|
||||
/* amdgpu_dm_irq_unregister_interrupt */
|
||||
KUNIT_CASE(dm_test_irq_unregister_rejects_invalid_source),
|
||||
KUNIT_CASE(dm_test_irq_unregister_rejects_null_handler),
|
||||
KUNIT_CASE(dm_test_irq_unregister_handler_not_found),
|
||||
/* amdgpu_dm_irq_fini */
|
||||
KUNIT_CASE(dm_test_irq_fini_removes_registered_handlers),
|
||||
KUNIT_CASE(dm_test_irq_fini_on_empty_tables),
|
||||
/* amdgpu_dm_get_crtc_by_otg_inst */
|
||||
KUNIT_CASE(dm_test_get_crtc_by_otg_inst_returns_match),
|
||||
KUNIT_CASE(dm_test_get_crtc_by_otg_inst_returns_null),
|
||||
KUNIT_CASE(dm_test_get_crtc_by_otg_inst_empty_list),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite amdgpu_dm_irq_test_suite = {
|
||||
.name = "amdgpu_dm_irq",
|
||||
.test_cases = amdgpu_dm_irq_tests,
|
||||
};
|
||||
|
||||
kunit_test_suite(amdgpu_dm_irq_test_suite);
|
||||
|
||||
MODULE_AUTHOR("AMD");
|
||||
MODULE_DESCRIPTION("KUnit tests for amdgpu_dm_irq");
|
||||
MODULE_LICENSE("Dual MIT/GPL");
|
||||
Reference in New Issue
Block a user