From: Mario Limonciello <mario.limoncie...@amd.com>

The compositor can directly control ABM, but sysfs should be blocked
when this happens.  Ensure that sysfs writes fail at that time.

To avoid potential test failures, ensure that sysfs control is enabled
at the start of all other tests.

Signed-off-by: Mario Limonciello <mario.limoncie...@amd.com>
---
 tests/amdgpu/amd_abm.c | 81 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)

diff --git a/tests/amdgpu/amd_abm.c b/tests/amdgpu/amd_abm.c
index 3c6a7307f..090806d6a 100644
--- a/tests/amdgpu/amd_abm.c
+++ b/tests/amdgpu/amd_abm.c
@@ -107,6 +107,45 @@ static void fbmem_draw_smpte_pattern(uint32_t *fbmem, int 
width, int height)
        }
 }
 
+static bool set_abm_level_compositor(data_t *data, igt_output_t *output, const 
char *level)
+{
+       uint32_t type = DRM_MODE_OBJECT_CONNECTOR;
+       uint32_t output_id = output->id;
+       drmModePropertyPtr prop = NULL;
+       uint64_t abm_prop_value;
+       uint32_t abm_prop_id;
+       bool abm_prop_exists;
+       int i;
+
+       abm_prop_exists = kmstest_get_property(
+               data->drm_fd, output_id, type, "adaptive backlight modulation",
+               &abm_prop_id, &abm_prop_value, &prop);
+
+       /* not supported in this kernel */
+       if (!abm_prop_exists)
+               return false;
+
+       igt_assert(prop->count_enums != 0);
+
+       for (i = 0; i < prop->count_enums; i++) {
+               if (strcmp(prop->enums[i].name, level) == 0) {
+                       abm_prop_value = prop->enums[i].value;
+                       break;
+               }
+       }
+
+       igt_assert_f(i != prop->count_enums,
+                   "ABM property value '%s' not found in connector %s\n",
+                   level, output->name);
+
+       drmModeFreeProperty(prop);
+
+       igt_assert(drmModeConnectorSetProperty(data->drm_fd, output->id,
+                                              abm_prop_id, abm_prop_value) == 
0);
+
+       return true;
+}
+
 /* Common test setup. */
 static void test_init(data_t *data)
 {
@@ -160,6 +199,8 @@ static void test_init(data_t *data)
        fbmem_draw_smpte_pattern(data->fb_mem, data->w, data->h);
        igt_create_color_fb(data->drm_fd, data->mode->hdisplay,
                data->mode->vdisplay, DRM_FORMAT_XRGB8888, 0, 0.05, 0.05, 0.05, 
&data->ref_fb2);
+
+       set_abm_level_compositor(data, data->output, "sysfs");
 }
 
 /* Common test cleanup. */
@@ -449,6 +490,44 @@ static void abm_enabled(data_t *data)
        }
 }
 
+static void abm_compositor(data_t *data)
+{
+       igt_output_t *output;
+       char buf[PATH_MAX];
+       enum pipe pipe;
+       int fd;
+
+       for_each_valid_output_on_pipe(&data->display, pipe, output) {
+               if (output->config.connector->connector_type != 
DRM_MODE_CONNECTOR_eDP)
+                       continue;
+
+               /* allow sysfs writes */
+               if (!set_abm_level_compositor(data, output, "sysfs"))
+                       igt_skip("No ABM property\n");
+
+               /* Set ABM to 4 */
+               set_abm_level_sysfs(data, output, 4);
+
+               /* block sysfs and turn off ABM */
+               set_abm_level_compositor(data, output, "min");
+
+               /* ensure a sysfs write fails */
+               igt_assert(snprintf(buf, PATH_MAX, PANEL_POWER_SAVINGS_PATH,
+                          output->name) < PATH_MAX);
+               fd = open(buf, O_WRONLY);
+               igt_assert_eq(snprintf(buf, sizeof(buf), "%d", 4), 1);
+               igt_assert_eq(write(fd, buf, 1), -1);
+               igt_assert_eq(close(fd), 0);
+               igt_assert_eq(errno, EBUSY);
+
+               /* re-enable sysfs */
+               set_abm_level_compositor(data, output, "sysfs");
+
+               /* Set ABM to 0 with sysfs */
+               set_abm_level_sysfs(data, output, 0);
+       }
+}
+
 static void abm_gradual(data_t *data)
 {
        int ret, i;
@@ -524,6 +603,8 @@ igt_main
                abm_enabled(&data);
        igt_subtest("abm_gradual")
                abm_gradual(&data);
+       igt_subtest("abm_compositor")
+               abm_compositor(&data);
 
        igt_fixture {
                test_fini(&data);
-- 
2.50.1

Reply via email to