An upcoming patch makes the store apply the level with an atomic commit. The store tests allocate their connector with kunit_kzalloc() instead of initialising it on the DRM device, and have no CRTC, plane or encoder, so a commit can't run on it
Build a primary plane, a CRTC, an encoder and an eDP connector on the KUnit device instead, with runtime PM enabled as on a probed device, and move the two store tests onto it. They check the same results as before Signed-off-by: Hugo Sales <[email protected]> --- .../amdgpu_dm/tests/amdgpu_dm_backlight_test.c | 88 ++++++++++++++++++++-- 1 file changed, 82 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c index c6d15fb8ad989..35e245b078f7a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_backlight_test.c @@ -7,10 +7,14 @@ #include <kunit/test.h> #include <linux/backlight.h> +#include <linux/pm_runtime.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_connector.h> +#include <drm/drm_kunit_helpers.h> +#include <drm/drm_managed.h> #include <drm/drm_mode_config.h> +#include <drm/drm_modeset_helper_vtables.h> #include <drm/drm_property.h> #include "dc.h" @@ -544,6 +548,75 @@ static struct drm_connector *setup_panel_power_savings_connector(struct kunit *t return connector; } +static const struct drm_connector_funcs dm_test_pps_connector_funcs = { + .reset = amdgpu_dm_connector_funcs_reset, + .atomic_duplicate_state = amdgpu_dm_connector_atomic_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int dm_test_pps_get_modes(struct drm_connector *connector) +{ + return 0; +} + +/* update_connector_routing() dereferences the helper funcs unconditionally */ +static const struct drm_connector_helper_funcs dm_test_pps_connector_helper_funcs = { + .get_modes = dm_test_pps_get_modes, +}; + +/* + * Build a primary plane, a CRTC, an encoder and an eDP connector that the + * store can commit to. The KUnit device uses the generic atomic helpers, so a + * commit runs drm_atomic_helper_check() and drm_atomic_helper_commit() rather + * than the DM implementations + */ +static struct drm_connector * +setup_panel_power_savings_pipe(struct kunit *test, struct device **device_out) +{ + struct amdgpu_dm_connector *aconnector; + struct drm_connector *connector; + struct drm_encoder *encoder; + struct amdgpu_device *adev; + struct drm_plane *primary; + struct drm_crtc *crtc; + struct device *device; + + adev = dm_kunit_alloc_adev(test); + KUNIT_ASSERT_EQ(test, pm_runtime_set_active(adev->ddev.dev), 0); + KUNIT_ASSERT_EQ(test, devm_pm_runtime_enable(adev->ddev.dev), 0); + + primary = drm_kunit_helper_create_primary_plane(test, &adev->ddev, NULL, + NULL, NULL, 0, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, primary); + crtc = drm_kunit_helper_create_crtc(test, &adev->ddev, primary, NULL, + NULL, NULL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc); + + encoder = drmm_kzalloc(&adev->ddev, sizeof(*encoder), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, encoder); + KUNIT_ASSERT_EQ(test, drmm_encoder_init(&adev->ddev, encoder, NULL, + DRM_MODE_ENCODER_TMDS, NULL), 0); + encoder->possible_crtcs = drm_crtc_mask(crtc); + + aconnector = drmm_kzalloc(&adev->ddev, sizeof(*aconnector), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, aconnector); + connector = &aconnector->base; + KUNIT_ASSERT_EQ(test, drmm_connector_init(&adev->ddev, connector, + &dm_test_pps_connector_funcs, + DRM_MODE_CONNECTOR_eDP, NULL), 0); + drm_connector_helper_add(connector, &dm_test_pps_connector_helper_funcs); + KUNIT_ASSERT_EQ(test, drm_connector_attach_encoder(connector, encoder), 0); + + drm_mode_config_reset(&adev->ddev); + + device = kunit_kzalloc(test, sizeof(*device), GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, device); + dev_set_drvdata(device, connector); + *device_out = device; + + return connector; +} + static void dm_test_free_sysfs_buf(void *data) { free_page((unsigned long)data); @@ -607,15 +680,16 @@ static void dm_test_panel_power_savings_show_reports_level(struct kunit *test) */ static void dm_test_panel_power_savings_store_sets_disable(struct kunit *test) { - struct dm_connector_state *state; + struct drm_connector *connector; struct device *device; size_t count = strlen("0"); - setup_panel_power_savings_connector(test, &device, &state); + connector = setup_panel_power_savings_pipe(test, &device); KUNIT_EXPECT_EQ(test, panel_power_savings_store(device, NULL, "0", count), (ssize_t)count); - KUNIT_EXPECT_EQ(test, state->abm_level, ABM_LEVEL_IMMEDIATE_DISABLE); + KUNIT_EXPECT_EQ(test, to_dm_connector_state(connector->state)->abm_level, + ABM_LEVEL_IMMEDIATE_DISABLE); } /** @@ -624,11 +698,13 @@ static void dm_test_panel_power_savings_store_sets_disable(struct kunit *test) */ static void dm_test_panel_power_savings_store_forbidden(struct kunit *test) { - struct dm_connector_state *state; + struct dm_connector_state *dm_state; + struct drm_connector *connector; struct device *device; - setup_panel_power_savings_connector(test, &device, &state); - state->abm_sysfs_forbidden = true; + connector = setup_panel_power_savings_pipe(test, &device); + dm_state = to_dm_connector_state(connector->state); + dm_state->abm_sysfs_forbidden = true; KUNIT_EXPECT_EQ(test, panel_power_savings_store(device, NULL, "1", 1), -EBUSY); } -- 2.56.0
