mirror of
https://github.com/torvalds/linux.git
synced 2026-11-09 13:44:03 +01:00
drm/amd/display: Test vline0 irq control
[WHAT] The vline0 interrupt handling in amdgpu_dm_crtc_set_vblank() sits inside a CONFIG_DRM_AMD_SECURE_DISPLAY block. That symbol depends on CONFIG_DRM_AMD_DC_FP, which cannot be enabled on UML because UML does not select ARCH_HAS_KERNEL_FPU_SUPPORT, so the logic is never built by the KUnit tests and stays uncovered. [HOW] Move the block into amdgpu_dm_crtc_set_vline0_irq() and build it whenever CONFIG_DRM_AMD_SECURE_DISPLAY or the KUnit tests are enabled. The DCN-only check becomes an early return. Behaviour of amdgpu_dm_crtc_set_vblank() is unchanged. Add tests for amdgpu_dm_crtc_set_vline0_irq() covering the DCE no-op path, error propagation from amdgpu_irq_get() and the enable/disable refcount round-trip. Assisted-by: Copilot:Claude-Opus-5 Reviewed-by: Bhawanpreet Lakha <bhawanpreet.lakha@amd.com> Signed-off-by: Alex Hung <alex.hung@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
285f6b4557
commit
22dbf5c4b2
|
|
@ -249,6 +249,30 @@ STATIC_IFN_KUNIT void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *w
|
|||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_vblank_control_worker);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) || IS_ENABLED(CONFIG_DRM_AMD_DC_KUNIT_TEST)
|
||||
STATIC_IFN_KUNIT int amdgpu_dm_crtc_set_vline0_irq(struct drm_crtc *crtc, int irq_type,
|
||||
bool enable)
|
||||
{
|
||||
struct amdgpu_device *adev = drm_to_adev(crtc->dev);
|
||||
int rc;
|
||||
|
||||
/* crtc vline0 interrupt, only available on DCN+ */
|
||||
if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0)
|
||||
return 0;
|
||||
|
||||
if (enable) {
|
||||
rc = amdgpu_irq_get(adev, &adev->vline0_irq, irq_type);
|
||||
drm_dbg_vbl(crtc->dev, "Get vline0_irq ret=%d\n", rc);
|
||||
} else {
|
||||
rc = amdgpu_irq_put(adev, &adev->vline0_irq, irq_type);
|
||||
drm_dbg_vbl(crtc->dev, "Put vline0_irq ret=%d\n", rc);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_IF_KUNIT(amdgpu_dm_crtc_set_vline0_irq);
|
||||
#endif
|
||||
|
||||
static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
|
||||
{
|
||||
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
|
||||
|
|
@ -358,19 +382,9 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
|
||||
/* crtc vline0 interrupt, only available on DCN+ */
|
||||
if (amdgpu_ip_version(adev, DCE_HWIP, 0) != 0) {
|
||||
if (enable) {
|
||||
rc = amdgpu_irq_get(adev, &adev->vline0_irq, irq_type);
|
||||
drm_dbg_vbl(crtc->dev, "Get vline0_irq ret=%d\n", rc);
|
||||
} else {
|
||||
rc = amdgpu_irq_put(adev, &adev->vline0_irq, irq_type);
|
||||
drm_dbg_vbl(crtc->dev, "Put vline0_irq ret=%d\n", rc);
|
||||
}
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
rc = amdgpu_dm_crtc_set_vline0_irq(crtc, irq_type, enable);
|
||||
if (rc)
|
||||
return rc;
|
||||
#endif
|
||||
|
||||
if (amdgpu_in_reset(adev))
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ void amdgpu_dm_crtc_update_crtc_active_planes(struct drm_crtc *crtc,
|
|||
struct drm_crtc_state *new_crtc_state);
|
||||
void amdgpu_dm_crtc_vblank_control_worker(struct work_struct *work);
|
||||
void amdgpu_dm_idle_worker(struct work_struct *work);
|
||||
int amdgpu_dm_crtc_set_vline0_irq(struct drm_crtc *crtc, int irq_type, bool enable);
|
||||
int amdgpu_dm_crtc_helper_atomic_check(struct drm_crtc *crtc,
|
||||
struct drm_atomic_commit *state);
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
|
|
|||
|
|
@ -1226,6 +1226,103 @@ static void dm_test_crtc_enable_vblank_ips_restore_replay(struct kunit *test)
|
|||
KUNIT_EXPECT_EQ(test, amdgpu_dm_crtc_enable_vblank(&acrtc->base), 0);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_set_vline0_irq() */
|
||||
|
||||
/*
|
||||
* dm_test_crtc_setup_vline0 - Build an adev/CRTC for the vline0 IRQ helper.
|
||||
* @test: The KUnit test context
|
||||
* @adev_out: Receives the allocated device
|
||||
* @ip_version: DCE IP version stamped on the device (0 selects the DCE path)
|
||||
*
|
||||
* Returns a bare CRTC attached to the device. The IRQ subsystem is left
|
||||
* uninstalled for callers to arm.
|
||||
*/
|
||||
static struct drm_crtc *dm_test_crtc_setup_vline0(struct kunit *test,
|
||||
struct amdgpu_device **adev_out,
|
||||
uint32_t ip_version)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
adev = dm_kunit_alloc_adev(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, adev);
|
||||
|
||||
crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
|
||||
crtc->dev = &adev->ddev;
|
||||
|
||||
adev->ip_versions[DCE_HWIP][0] = ip_version;
|
||||
|
||||
*adev_out = adev;
|
||||
return crtc;
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_crtc_set_vline0_irq_dce_noop - Test vline0 irq is skipped on DCE
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* VLINE0 only exists on DCN+. With no DCE IP version stamped the helper must
|
||||
* return 0 without touching the IRQ source, even though the IRQ subsystem is
|
||||
* uninstalled (which would otherwise make amdgpu_irq_get() fail).
|
||||
*/
|
||||
static void dm_test_crtc_set_vline0_irq_dce_noop(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
crtc = dm_test_crtc_setup_vline0(test, &adev, 0);
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
amdgpu_dm_crtc_set_vline0_irq(crtc, AMDGPU_CRTC_IRQ_VBLANK1, true), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_crtc_set_vline0_irq_error - Test vline0 irq failure is propagated
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* On DCN with the IRQ subsystem uninstalled, amdgpu_irq_get() returns -ENOENT
|
||||
* and the helper must propagate it.
|
||||
*/
|
||||
static void dm_test_crtc_set_vline0_irq_error(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
crtc = dm_test_crtc_setup_vline0(test, &adev, IP_VERSION(3, 5, 0));
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
amdgpu_dm_crtc_set_vline0_irq(crtc, AMDGPU_CRTC_IRQ_VBLANK1, true),
|
||||
-ENOENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_test_crtc_set_vline0_irq_enable_disable - Test vline0 irq refcounting
|
||||
* @test: The KUnit test context
|
||||
*
|
||||
* On DCN with an armed IRQ source, enabling takes a vline0 reference and
|
||||
* disabling drops it again.
|
||||
*/
|
||||
static void dm_test_crtc_set_vline0_irq_enable_disable(struct kunit *test)
|
||||
{
|
||||
struct amdgpu_device *adev;
|
||||
struct drm_crtc *crtc;
|
||||
atomic_t *refcount;
|
||||
|
||||
crtc = dm_test_crtc_setup_vline0(test, &adev, IP_VERSION(3, 5, 0));
|
||||
|
||||
adev->irq.installed = true;
|
||||
dm_test_crtc_arm_irq_src(test, &adev->vline0_irq, 1);
|
||||
refcount = &adev->vline0_irq.enabled_types[AMDGPU_CRTC_IRQ_VBLANK1];
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
amdgpu_dm_crtc_set_vline0_irq(crtc, AMDGPU_CRTC_IRQ_VBLANK1, true), 0);
|
||||
KUNIT_EXPECT_EQ(test, atomic_read(refcount), 2);
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
amdgpu_dm_crtc_set_vline0_irq(crtc, AMDGPU_CRTC_IRQ_VBLANK1, false), 0);
|
||||
KUNIT_EXPECT_EQ(test, atomic_read(refcount), 1);
|
||||
}
|
||||
|
||||
/* Tests for amdgpu_dm_crtc_update_crtc_active_planes() */
|
||||
|
||||
/**
|
||||
|
|
@ -2526,6 +2623,10 @@ static struct kunit_case amdgpu_dm_crtc_tests[] = {
|
|||
KUNIT_CASE(dm_test_crtc_enable_vblank_queues_work),
|
||||
KUNIT_CASE(dm_test_crtc_enable_vblank_ips_restore),
|
||||
KUNIT_CASE(dm_test_crtc_enable_vblank_ips_restore_replay),
|
||||
/* amdgpu_dm_crtc_set_vline0_irq */
|
||||
KUNIT_CASE(dm_test_crtc_set_vline0_irq_dce_noop),
|
||||
KUNIT_CASE(dm_test_crtc_set_vline0_irq_error),
|
||||
KUNIT_CASE(dm_test_crtc_set_vline0_irq_enable_disable),
|
||||
/* amdgpu_dm_crtc_update_crtc_active_planes */
|
||||
KUNIT_CASE(dm_test_crtc_update_active_planes_no_stream),
|
||||
/* amdgpu_dm_crtc_count_crtc_active_planes */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user