* [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management @ 2018-11-28 20:51 David Francis 2018-11-29 0:20 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork 2018-11-29 20:45 ` [igt-dev] [PATCH i-g-t] " Wentland, Harry 0 siblings, 2 replies; 5+ messages in thread From: David Francis @ 2018-11-28 20:51 UTC (permalink / raw) To: igt-dev Adaptive Backlight Management (ABM) is a power-saving feature on AMD ASICs that reduces backlight while increasing pixel contrast and luminance. This test confirms that ABM is present and enabled, and that backlight performance is sane. It uses AMD-specific debugfs entries to read the backlight PWM values. It has 5 subtests: dpms_cycle Sets brightness to half, then confirms that value is restored after dpms off and then on. backlight_monotonic_basic Sets brightness to ten different values, confirming that higher brightness values are brighter. backlight_monotonic_abm Same as backlight_monotonic_basic, but with abm enabled. abm_enabled Sets abm to its four intensity levels, confirming that abm reduces the backlight, and the reduction is greater for higher abm level. abm_gradual Sets abm to off and then maximum intensity, confirming that brightness decreases continually over the first second and eventually reaches the target value. This test takes 30s to run. Signed-off-by: David Francis <David.Francis@amd.com> --- tests/Makefile.sources | 1 + tests/amdgpu/amd_abm.c | 361 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 362 insertions(+) create mode 100644 tests/amdgpu/amd_abm.c diff --git a/tests/Makefile.sources b/tests/Makefile.sources index 5620c1d6..3d560bee 100644 --- a/tests/Makefile.sources +++ b/tests/Makefile.sources @@ -19,6 +19,7 @@ AMDGPU_TESTS = \ amdgpu/amd_basic \ amdgpu/amd_cs_nop \ amdgpu/amd_prime \ + amdgpu/amd_abm \ $(NULL) TESTS_progs = \ diff --git a/tests/amdgpu/amd_abm.c b/tests/amdgpu/amd_abm.c new file mode 100644 index 00000000..90a6f99e --- /dev/null +++ b/tests/amdgpu/amd_abm.c @@ -0,0 +1,361 @@ +/* + * Copyright 2018 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "igt.h" +#include "drmtest.h" +#include "igt_kms.h" +#include <limits.h> +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> +#include <time.h> + +#define BACKLIGHT_PATH "/sys/class/backlight/amdgpu_bl0" + +static int read_current_backlight_pwm(int debugfs_dir) +{ + char buf[20]; + + igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", + buf, sizeof(buf)); + + return strtol(buf, NULL, 0); +} + +static int read_target_backlight_pwm(int debugfs_dir) +{ + char buf[20]; + + igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", + buf, sizeof(buf)); + + return strtol(buf, NULL, 0); +} + +static int backlight_write_brightness(int value) +{ + int fd; + char full[PATH_MAX]; + char src[64]; + int len; + + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "brightness") < PATH_MAX); + fd = open(full, O_WRONLY); + if (fd == -1) + return -errno; + + len = snprintf(src, sizeof(src), "%i", value); + len = write(fd, src, len); + close(fd); + + if (len < 0) + return len; + + return 0; +} + +static void set_abm_level(igt_display_t *display, int level) +{ + int i, ret; + int output_id; + drmModeObjectPropertiesPtr props; + uint32_t prop_id; + drmModePropertyPtr prop; + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; + + for (i = 0; i < display->n_outputs; i++) { + output_id = display->outputs[i].id; + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); + + for (i = 0; i < props->count_props; i++) { + prop_id = props->props[i]; + prop = drmModeGetProperty(display->drm_fd, prop_id); + + igt_assert(prop); + + if (strcmp(prop->name, "abm level") == 0) { + ret = drmModeObjectSetProperty(display->drm_fd, output_id, type, prop_id, level); + + igt_assert_eq(ret, 0); + } + + drmModeFreeProperty(prop); + } + } + +} + +static int backlight_read_max_brightness(int *result) +{ + int fd; + char full[PATH_MAX]; + char dst[64]; + int r, e; + + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "max_brightness") < PATH_MAX); + + fd = open(full, O_RDONLY); + if (fd == -1) + return -errno; + + r = read(fd, dst, sizeof(dst)); + e = errno; + close(fd); + + if (r < 0) + return -e; + + errno = 0; + *result = strtol(dst, NULL, 10); + return errno; +} + +static void skip_if_incompatible(igt_display_t *display, int debugfs_dir) +{ + int ret, i; + char buf[20]; + bool abm_prop_exists; + int output_id; + drmModeObjectPropertiesPtr props; + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; + uint32_t prop_id; + drmModePropertyPtr prop; + + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", + buf, sizeof(buf)); + + if (ret < 0) + igt_skip("No current backlight debugfs entry.\n"); + + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", + buf, sizeof(buf)); + + if (ret < 0) + igt_skip("No target backlight debugfs entry.\n"); + + abm_prop_exists = false; + + for (i = 0; i < display->n_outputs; i++) { + output_id = display->outputs[i].id; + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); + + for (i = 0; i < props->count_props; i++) { + prop_id = props->props[i]; + prop = drmModeGetProperty(display->drm_fd, prop_id); + + if (strcmp(prop->name, "abm level") == 0) + abm_prop_exists = true; + + drmModeFreeProperty(prop); + } + } + + if (!abm_prop_exists) + igt_skip("No abm level property on any connector.\n"); +} + + +static void backlight_dpms_cycle(igt_display_t *display, int debugfs, igt_output_t *output) +{ + int ret; + int max_brightness; + int pwm_1, pwm_2; + + ret = backlight_read_max_brightness(&max_brightness); + igt_assert_eq(ret, 0); + + set_abm_level(display, 0); + backlight_write_brightness(max_brightness / 2); + usleep(100000); + pwm_1 = read_target_backlight_pwm(debugfs); + + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_OFF); + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_ON); + usleep(100000); + pwm_2 = read_target_backlight_pwm(debugfs); + igt_assert_eq(pwm_1, pwm_2); +} + +static void backlight_monotonic_basic(igt_display_t *display, int debugfs) +{ + int ret; + int max_brightness; + int prev_pwm, pwm; + int brightness_step; + int brightness; + + ret = backlight_read_max_brightness(&max_brightness); + igt_assert_eq(ret, 0); + + brightness_step = max_brightness / 10; + + set_abm_level(display, 0); + backlight_write_brightness(max_brightness); + usleep(100000); + prev_pwm = read_target_backlight_pwm(debugfs); + for (brightness = max_brightness - brightness_step; + brightness > 0; + brightness -= brightness_step) { + backlight_write_brightness(brightness); + usleep(100000); + pwm = read_target_backlight_pwm(debugfs); + igt_assert(pwm < prev_pwm); + prev_pwm = pwm; + } + +} + +static void backlight_monotonic_abm(igt_display_t *display, int debugfs) +{ + int ret, i; + int max_brightness; + int prev_pwm, pwm; + int brightness_step; + int brightness; + + ret = backlight_read_max_brightness(&max_brightness); + igt_assert_eq(ret, 0); + + brightness_step = max_brightness / 10; + for (i = 1; i < 5; i++) { + set_abm_level(display, i); + backlight_write_brightness(max_brightness); + usleep(100000); + prev_pwm = read_target_backlight_pwm(debugfs); + for (brightness = max_brightness - brightness_step; + brightness > 0; + brightness -= brightness_step) { + backlight_write_brightness(brightness); + usleep(100000); + pwm = read_target_backlight_pwm(debugfs); + igt_assert(pwm < prev_pwm); + prev_pwm = pwm; + } + } +} + +static void abm_enabled(igt_display_t *display, int debugfs) +{ + int ret, i; + int max_brightness; + int pwm, prev_pwm, pwm_without_abm; + + ret = backlight_read_max_brightness(&max_brightness); + igt_assert_eq(ret, 0); + + set_abm_level(display, 0); + backlight_write_brightness(max_brightness); + usleep(100000); + prev_pwm = read_target_backlight_pwm(debugfs); + pwm_without_abm = prev_pwm; + + for (i = 1; i < 5; i++) { + set_abm_level(display, i); + usleep(100000); + pwm = read_target_backlight_pwm(debugfs); + igt_assert(pwm <= prev_pwm); + igt_assert(pwm < pwm_without_abm); + prev_pwm = pwm; + } + +} + +static void abm_gradual(igt_display_t *display, int debugfs) +{ + int ret, i; + int convergence_delay = 15; + int prev_pwm, pwm, curr; + int max_brightness; + + ret = backlight_read_max_brightness(&max_brightness); + + igt_assert_eq(ret, 0); + + set_abm_level(display, 0); + backlight_write_brightness(max_brightness); + + sleep(convergence_delay); + prev_pwm = read_target_backlight_pwm(debugfs); + curr = read_current_backlight_pwm(debugfs); + + igt_assert_eq(prev_pwm, curr); + set_abm_level(display, 4); + for (i = 0; i < 10; i++) { + usleep(100000); + pwm = read_current_backlight_pwm(debugfs); + igt_assert(pwm < prev_pwm); + prev_pwm = pwm; + } + + sleep(convergence_delay - 1); + + prev_pwm = read_target_backlight_pwm(debugfs); + curr = read_current_backlight_pwm(debugfs); + + igt_assert_eq(prev_pwm, curr); +} + +igt_main +{ + igt_display_t display; + int debugfs; + enum pipe pipe; + igt_output_t *output; + + igt_skip_on_simulation(); + + igt_fixture { + display.drm_fd = drm_open_driver_master(DRIVER_AMDGPU); + + if (display.drm_fd == -1) + igt_skip("Not an amdgpu driver.\n"); + + debugfs = igt_debugfs_dir(display.drm_fd); + + kmstest_set_vt_graphics_mode(); + + igt_display_require(&display, display.drm_fd); + + skip_if_incompatible(&display, debugfs); + + for_each_pipe_with_valid_output(&display, pipe, output) + break; + } + + igt_subtest("dpms_cycle") + backlight_dpms_cycle(&display, debugfs, output); + igt_subtest("backlight_monotonic_basic") + backlight_monotonic_basic(&display, debugfs); + igt_subtest("backlight_monotonic_abm") + backlight_monotonic_abm(&display, debugfs); + igt_subtest("abm_enabled") + abm_enabled(&display, debugfs); + igt_subtest("abm_gradual") + abm_gradual(&display, debugfs); + + igt_fixture { + igt_display_fini(&display); + } +} -- 2.17.1 _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev ^ permalink raw reply related [flat|nested] 5+ messages in thread
* [igt-dev] ✓ Fi.CI.BAT: success for tests/amdgpu: Add test for Adaptive Backlight Management 2018-11-28 20:51 [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management David Francis @ 2018-11-29 0:20 ` Patchwork 2018-11-29 20:45 ` [igt-dev] [PATCH i-g-t] " Wentland, Harry 1 sibling, 0 replies; 5+ messages in thread From: Patchwork @ 2018-11-29 0:20 UTC (permalink / raw) To: David Francis; +Cc: igt-dev == Series Details == Series: tests/amdgpu: Add test for Adaptive Backlight Management URL : https://patchwork.freedesktop.org/series/53186/ State : success == Summary == CI Bug Log - changes from CI_DRM_5217 -> IGTPW_2105 ==================================================== Summary ------- **SUCCESS** No regressions found. External URL: https://patchwork.freedesktop.org/api/1.0/series/53186/revisions/1/mbox/ Known issues ------------ Here are the changes found in IGTPW_2105 that come from known issues: ### IGT changes ### #### Issues hit #### * igt@i915_module_load@reload: - fi-blb-e6850: PASS -> INCOMPLETE [fdo#107718] * igt@kms_pipe_crc_basic@hang-read-crc-pipe-b: - fi-byt-clapper: PASS -> FAIL [fdo#103191] / [fdo#107362] * igt@prime_vgem@basic-fence-flip: - fi-gdg-551: PASS -> FAIL [fdo#103182] * {igt@runner@aborted}: - {fi-icl-u3}: NOTRUN -> FAIL [fdo#108866 ] #### Warnings #### * igt@i915_selftest@live_contexts: - {fi-icl-u3}: DMESG-FAIL [fdo#108569] -> INCOMPLETE [fdo#108315] {name}: This element is suppressed. This means it is ignored when computing the status of the difference (SUCCESS, WARNING, or FAILURE). [fdo#103182]: https://bugs.freedesktop.org/show_bug.cgi?id=103182 [fdo#103191]: https://bugs.freedesktop.org/show_bug.cgi?id=103191 [fdo#107362]: https://bugs.freedesktop.org/show_bug.cgi?id=107362 [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718 [fdo#108315]: https://bugs.freedesktop.org/show_bug.cgi?id=108315 [fdo#108569]: https://bugs.freedesktop.org/show_bug.cgi?id=108569 [fdo#108866 ]: https://bugs.freedesktop.org/show_bug.cgi?id=108866 Participating hosts (49 -> 44) ------------------------------ Additional (1): fi-pnv-d510 Missing (6): fi-kbl-soraka fi-ilk-m540 fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 Build changes ------------- * IGT: IGT_4735 -> IGTPW_2105 CI_DRM_5217: 3b8acd938b1edc326fb69d377cbceca8791df177 @ git://anongit.freedesktop.org/gfx-ci/linux IGTPW_2105: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2105/ IGT_4735: b05c028ccdb6ac8e8d8499a041bb14dfe358ee26 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2105/ _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management 2018-11-28 20:51 [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management David Francis 2018-11-29 0:20 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork @ 2018-11-29 20:45 ` Wentland, Harry 2018-12-07 14:34 ` Francis, David 1 sibling, 1 reply; 5+ messages in thread From: Wentland, Harry @ 2018-11-29 20:45 UTC (permalink / raw) To: Francis, David, igt-dev@lists.freedesktop.org On 2018-11-28 3:51 p.m., David Francis wrote: > Adaptive Backlight Management (ABM) is a power-saving > feature on AMD ASICs that reduces backlight while increasing > pixel contrast and luminance. This test confirms that > ABM is present and enabled, and that backlight performance > is sane. It uses AMD-specific debugfs entries to > read the backlight PWM values. > > It has 5 subtests: > > dpms_cycle > Sets brightness to half, then confirms that value is restored > after dpms off and then on. > > backlight_monotonic_basic > Sets brightness to ten different values, confirming that > higher brightness values are brighter. > > backlight_monotonic_abm > Same as backlight_monotonic_basic, but with abm enabled. > > abm_enabled > Sets abm to its four intensity levels, confirming that > abm reduces the backlight, and the reduction is greater > for higher abm level. > > abm_gradual > Sets abm to off and then maximum intensity, confirming > that brightness decreases continually over the first > second and eventually reaches the target value. > This test takes 30s to run. > > Signed-off-by: David Francis <David.Francis@amd.com> > --- > tests/Makefile.sources | 1 + > tests/amdgpu/amd_abm.c | 361 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 362 insertions(+) > create mode 100644 tests/amdgpu/amd_abm.c > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources > index 5620c1d6..3d560bee 100644 > --- a/tests/Makefile.sources > +++ b/tests/Makefile.sources > @@ -19,6 +19,7 @@ AMDGPU_TESTS = \ > amdgpu/amd_basic \ > amdgpu/amd_cs_nop \ > amdgpu/amd_prime \ > + amdgpu/amd_abm \ > $(NULL) > > TESTS_progs = \ > diff --git a/tests/amdgpu/amd_abm.c b/tests/amdgpu/amd_abm.c > new file mode 100644 > index 00000000..90a6f99e > --- /dev/null > +++ b/tests/amdgpu/amd_abm.c > @@ -0,0 +1,361 @@ > +/* > + * Copyright 2018 Advanced Micro Devices, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include "igt.h" > +#include "drmtest.h" > +#include "igt_kms.h" > +#include <limits.h> > +#include <errno.h> > +#include <stdbool.h> > +#include <stdlib.h> > +#include <stdio.h> > +#include <string.h> > +#include <fcntl.h> > +#include <time.h> > + > +#define BACKLIGHT_PATH "/sys/class/backlight/amdgpu_bl0" > + > +static int read_current_backlight_pwm(int debugfs_dir) > +{ > + char buf[20]; > + > + igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", > + buf, sizeof(buf)); > + > + return strtol(buf, NULL, 0); > +} > + > +static int read_target_backlight_pwm(int debugfs_dir) > +{ > + char buf[20]; > + > + igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", > + buf, sizeof(buf)); > + > + return strtol(buf, NULL, 0); > +} > + > +static int backlight_write_brightness(int value) > +{ > + int fd; > + char full[PATH_MAX]; > + char src[64]; > + int len; > + > + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "brightness") < PATH_MAX); > + fd = open(full, O_WRONLY); > + if (fd == -1) > + return -errno; > + > + len = snprintf(src, sizeof(src), "%i", value); > + len = write(fd, src, len); > + close(fd); > + > + if (len < 0) > + return len; > + > + return 0; > +} > + > +static void set_abm_level(igt_display_t *display, int level) > +{ > + int i, ret; > + int output_id; > + drmModeObjectPropertiesPtr props; > + uint32_t prop_id; > + drmModePropertyPtr prop; > + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; > + > + for (i = 0; i < display->n_outputs; i++) { > + output_id = display->outputs[i].id; > + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); > + > + for (i = 0; i < props->count_props; i++) { > + prop_id = props->props[i]; > + prop = drmModeGetProperty(display->drm_fd, prop_id); > + > + igt_assert(prop); > + > + if (strcmp(prop->name, "abm level") == 0) { > + ret = drmModeObjectSetProperty(display->drm_fd, output_id, type, prop_id, level); > + > + igt_assert_eq(ret, 0); > + } > + > + drmModeFreeProperty(prop); > + } > + } > + > +} > + > +static int backlight_read_max_brightness(int *result) > +{ > + int fd; > + char full[PATH_MAX]; > + char dst[64]; > + int r, e; > + > + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "max_brightness") < PATH_MAX); > + > + fd = open(full, O_RDONLY); > + if (fd == -1) > + return -errno; > + > + r = read(fd, dst, sizeof(dst)); > + e = errno; > + close(fd); > + > + if (r < 0) > + return -e; > + > + errno = 0; > + *result = strtol(dst, NULL, 10); > + return errno; > +} > + > +static void skip_if_incompatible(igt_display_t *display, int debugfs_dir) > +{ > + int ret, i; > + char buf[20]; > + bool abm_prop_exists; > + int output_id; > + drmModeObjectPropertiesPtr props; > + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; > + uint32_t prop_id; > + drmModePropertyPtr prop; > + > + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", > + buf, sizeof(buf)); > + > + if (ret < 0) > + igt_skip("No current backlight debugfs entry.\n"); > + > + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", > + buf, sizeof(buf)); > + > + if (ret < 0) > + igt_skip("No target backlight debugfs entry.\n"); > + > + abm_prop_exists = false; > + > + for (i = 0; i < display->n_outputs; i++) { > + output_id = display->outputs[i].id; > + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); > + > + for (i = 0; i < props->count_props; i++) { > + prop_id = props->props[i]; > + prop = drmModeGetProperty(display->drm_fd, prop_id); > + > + if (strcmp(prop->name, "abm level") == 0) > + abm_prop_exists = true; > + > + drmModeFreeProperty(prop); > + } > + } > + > + if (!abm_prop_exists) > + igt_skip("No abm level property on any connector.\n"); > +} > + > + > +static void backlight_dpms_cycle(igt_display_t *display, int debugfs, igt_output_t *output) > +{ > + int ret; > + int max_brightness; > + int pwm_1, pwm_2; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness / 2); > + usleep(100000); > + pwm_1 = read_target_backlight_pwm(debugfs); > + > + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_OFF); > + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_ON); > + usleep(100000); > + pwm_2 = read_target_backlight_pwm(debugfs); > + igt_assert_eq(pwm_1, pwm_2); > +} > + > +static void backlight_monotonic_basic(igt_display_t *display, int debugfs) > +{ > + int ret; > + int max_brightness; > + int prev_pwm, pwm; > + int brightness_step; > + int brightness; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + brightness_step = max_brightness / 10; > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness); > + usleep(100000); > + prev_pwm = read_target_backlight_pwm(debugfs); > + for (brightness = max_brightness - brightness_step; > + brightness > 0; > + brightness -= brightness_step) { > + backlight_write_brightness(brightness); > + usleep(100000); > + pwm = read_target_backlight_pwm(debugfs); > + igt_assert(pwm < prev_pwm); > + prev_pwm = pwm; > + } > + > +} > + > +static void backlight_monotonic_abm(igt_display_t *display, int debugfs) > +{ > + int ret, i; > + int max_brightness; > + int prev_pwm, pwm; > + int brightness_step; > + int brightness; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + brightness_step = max_brightness / 10; > + for (i = 1; i < 5; i++) { > + set_abm_level(display, i); > + backlight_write_brightness(max_brightness); > + usleep(100000); > + prev_pwm = read_target_backlight_pwm(debugfs); > + for (brightness = max_brightness - brightness_step; > + brightness > 0; > + brightness -= brightness_step) { > + backlight_write_brightness(brightness); > + usleep(100000); > + pwm = read_target_backlight_pwm(debugfs); > + igt_assert(pwm < prev_pwm); > + prev_pwm = pwm; > + } > + } > +} > + > +static void abm_enabled(igt_display_t *display, int debugfs) > +{ > + int ret, i; > + int max_brightness; > + int pwm, prev_pwm, pwm_without_abm; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness); > + usleep(100000); > + prev_pwm = read_target_backlight_pwm(debugfs); > + pwm_without_abm = prev_pwm; > + > + for (i = 1; i < 5; i++) { > + set_abm_level(display, i); > + usleep(100000); > + pwm = read_target_backlight_pwm(debugfs); > + igt_assert(pwm <= prev_pwm); > + igt_assert(pwm < pwm_without_abm); > + prev_pwm = pwm; > + } > + > +} > + > +static void abm_gradual(igt_display_t *display, int debugfs) > +{ > + int ret, i; > + int convergence_delay = 15; > + int prev_pwm, pwm, curr; > + int max_brightness; > + > + ret = backlight_read_max_brightness(&max_brightness); > + > + igt_assert_eq(ret, 0); > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness); > + > + sleep(convergence_delay); > + prev_pwm = read_target_backlight_pwm(debugfs); > + curr = read_current_backlight_pwm(debugfs); > + > + igt_assert_eq(prev_pwm, curr); > + set_abm_level(display, 4); > + for (i = 0; i < 10; i++) { > + usleep(100000); > + pwm = read_current_backlight_pwm(debugfs); > + igt_assert(pwm < prev_pwm); This seems like it very much depends on the usleep value above, the range of expected pwm reduction between no ABM and ABM level 4, as well as how quickly/slowly this executes. Should the usleep time be a function of the convergence_delay? Could this give us flaky test results? How many PWM steps have you usually seen for each iteration of this function? If it's large we're probably fine. Harry > + prev_pwm = pwm; > + } > + > + sleep(convergence_delay - 1); > + > + prev_pwm = read_target_backlight_pwm(debugfs); > + curr = read_current_backlight_pwm(debugfs); > + > + igt_assert_eq(prev_pwm, curr); > +} > + > +igt_main > +{ > + igt_display_t display; > + int debugfs; > + enum pipe pipe; > + igt_output_t *output; > + > + igt_skip_on_simulation(); > + > + igt_fixture { > + display.drm_fd = drm_open_driver_master(DRIVER_AMDGPU); > + > + if (display.drm_fd == -1) > + igt_skip("Not an amdgpu driver.\n"); > + > + debugfs = igt_debugfs_dir(display.drm_fd); > + > + kmstest_set_vt_graphics_mode(); > + > + igt_display_require(&display, display.drm_fd); > + > + skip_if_incompatible(&display, debugfs); > + > + for_each_pipe_with_valid_output(&display, pipe, output) > + break; > + } > + > + igt_subtest("dpms_cycle") > + backlight_dpms_cycle(&display, debugfs, output); > + igt_subtest("backlight_monotonic_basic") > + backlight_monotonic_basic(&display, debugfs); > + igt_subtest("backlight_monotonic_abm") > + backlight_monotonic_abm(&display, debugfs); > + igt_subtest("abm_enabled") > + abm_enabled(&display, debugfs); > + igt_subtest("abm_gradual") > + abm_gradual(&display, debugfs); > + > + igt_fixture { > + igt_display_fini(&display); > + } > +} > _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management 2018-11-29 20:45 ` [igt-dev] [PATCH i-g-t] " Wentland, Harry @ 2018-12-07 14:34 ` Francis, David 2019-01-03 16:55 ` Li, Sun peng (Leo) 0 siblings, 1 reply; 5+ messages in thread From: Francis, David @ 2018-12-07 14:34 UTC (permalink / raw) To: Wentland, Harry, igt-dev@lists.freedesktop.org [-- Attachment #1.1: Type: text/plain, Size: 15014 bytes --] On my machine, the gradual brightness reduction gives the following pwm measurements pwm changed from 65535 to 64758 (-777) pwm changed from 64758 to 63530 (-1228) pwm changed from 63530 to 62594 (-936) pwm changed from 62594 to 61751 (-843) pwm changed from 61751 to 60825 (-926) pwm changed from 60825 to 59480 (-1345) pwm changed from 59480 to 58064 (-1416) pwm changed from 58064 to 56967 (-1097) pwm changed from 56967 to 55956 (-1011) pwm changed from 55956 to 55027 (-929) I think we can assume a change of at least 1 ________________________________ From: Wentland, Harry Sent: November 29, 2018 3:45:30 PM To: Francis, David; igt-dev@lists.freedesktop.org Subject: Re: [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management On 2018-11-28 3:51 p.m., David Francis wrote: > Adaptive Backlight Management (ABM) is a power-saving > feature on AMD ASICs that reduces backlight while increasing > pixel contrast and luminance. This test confirms that > ABM is present and enabled, and that backlight performance > is sane. It uses AMD-specific debugfs entries to > read the backlight PWM values. > > It has 5 subtests: > > dpms_cycle > Sets brightness to half, then confirms that value is restored > after dpms off and then on. > > backlight_monotonic_basic > Sets brightness to ten different values, confirming that > higher brightness values are brighter. > > backlight_monotonic_abm > Same as backlight_monotonic_basic, but with abm enabled. > > abm_enabled > Sets abm to its four intensity levels, confirming that > abm reduces the backlight, and the reduction is greater > for higher abm level. > > abm_gradual > Sets abm to off and then maximum intensity, confirming > that brightness decreases continually over the first > second and eventually reaches the target value. > This test takes 30s to run. > > Signed-off-by: David Francis <David.Francis@amd.com> > --- > tests/Makefile.sources | 1 + > tests/amdgpu/amd_abm.c | 361 +++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 362 insertions(+) > create mode 100644 tests/amdgpu/amd_abm.c > > diff --git a/tests/Makefile.sources b/tests/Makefile.sources > index 5620c1d6..3d560bee 100644 > --- a/tests/Makefile.sources > +++ b/tests/Makefile.sources > @@ -19,6 +19,7 @@ AMDGPU_TESTS = \ > amdgpu/amd_basic \ > amdgpu/amd_cs_nop \ > amdgpu/amd_prime \ > + amdgpu/amd_abm \ > $(NULL) > > TESTS_progs = \ > diff --git a/tests/amdgpu/amd_abm.c b/tests/amdgpu/amd_abm.c > new file mode 100644 > index 00000000..90a6f99e > --- /dev/null > +++ b/tests/amdgpu/amd_abm.c > @@ -0,0 +1,361 @@ > +/* > + * Copyright 2018 Advanced Micro Devices, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + */ > + > +#include "igt.h" > +#include "drmtest.h" > +#include "igt_kms.h" > +#include <limits.h> > +#include <errno.h> > +#include <stdbool.h> > +#include <stdlib.h> > +#include <stdio.h> > +#include <string.h> > +#include <fcntl.h> > +#include <time.h> > + > +#define BACKLIGHT_PATH "/sys/class/backlight/amdgpu_bl0" > + > +static int read_current_backlight_pwm(int debugfs_dir) > +{ > + char buf[20]; > + > + igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", > + buf, sizeof(buf)); > + > + return strtol(buf, NULL, 0); > +} > + > +static int read_target_backlight_pwm(int debugfs_dir) > +{ > + char buf[20]; > + > + igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", > + buf, sizeof(buf)); > + > + return strtol(buf, NULL, 0); > +} > + > +static int backlight_write_brightness(int value) > +{ > + int fd; > + char full[PATH_MAX]; > + char src[64]; > + int len; > + > + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "brightness") < PATH_MAX); > + fd = open(full, O_WRONLY); > + if (fd == -1) > + return -errno; > + > + len = snprintf(src, sizeof(src), "%i", value); > + len = write(fd, src, len); > + close(fd); > + > + if (len < 0) > + return len; > + > + return 0; > +} > + > +static void set_abm_level(igt_display_t *display, int level) > +{ > + int i, ret; > + int output_id; > + drmModeObjectPropertiesPtr props; > + uint32_t prop_id; > + drmModePropertyPtr prop; > + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; > + > + for (i = 0; i < display->n_outputs; i++) { > + output_id = display->outputs[i].id; > + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); > + > + for (i = 0; i < props->count_props; i++) { > + prop_id = props->props[i]; > + prop = drmModeGetProperty(display->drm_fd, prop_id); > + > + igt_assert(prop); > + > + if (strcmp(prop->name, "abm level") == 0) { > + ret = drmModeObjectSetProperty(display->drm_fd, output_id, type, prop_id, level); > + > + igt_assert_eq(ret, 0); > + } > + > + drmModeFreeProperty(prop); > + } > + } > + > +} > + > +static int backlight_read_max_brightness(int *result) > +{ > + int fd; > + char full[PATH_MAX]; > + char dst[64]; > + int r, e; > + > + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "max_brightness") < PATH_MAX); > + > + fd = open(full, O_RDONLY); > + if (fd == -1) > + return -errno; > + > + r = read(fd, dst, sizeof(dst)); > + e = errno; > + close(fd); > + > + if (r < 0) > + return -e; > + > + errno = 0; > + *result = strtol(dst, NULL, 10); > + return errno; > +} > + > +static void skip_if_incompatible(igt_display_t *display, int debugfs_dir) > +{ > + int ret, i; > + char buf[20]; > + bool abm_prop_exists; > + int output_id; > + drmModeObjectPropertiesPtr props; > + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; > + uint32_t prop_id; > + drmModePropertyPtr prop; > + > + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", > + buf, sizeof(buf)); > + > + if (ret < 0) > + igt_skip("No current backlight debugfs entry.\n"); > + > + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", > + buf, sizeof(buf)); > + > + if (ret < 0) > + igt_skip("No target backlight debugfs entry.\n"); > + > + abm_prop_exists = false; > + > + for (i = 0; i < display->n_outputs; i++) { > + output_id = display->outputs[i].id; > + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); > + > + for (i = 0; i < props->count_props; i++) { > + prop_id = props->props[i]; > + prop = drmModeGetProperty(display->drm_fd, prop_id); > + > + if (strcmp(prop->name, "abm level") == 0) > + abm_prop_exists = true; > + > + drmModeFreeProperty(prop); > + } > + } > + > + if (!abm_prop_exists) > + igt_skip("No abm level property on any connector.\n"); > +} > + > + > +static void backlight_dpms_cycle(igt_display_t *display, int debugfs, igt_output_t *output) > +{ > + int ret; > + int max_brightness; > + int pwm_1, pwm_2; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness / 2); > + usleep(100000); > + pwm_1 = read_target_backlight_pwm(debugfs); > + > + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_OFF); > + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_ON); > + usleep(100000); > + pwm_2 = read_target_backlight_pwm(debugfs); > + igt_assert_eq(pwm_1, pwm_2); > +} > + > +static void backlight_monotonic_basic(igt_display_t *display, int debugfs) > +{ > + int ret; > + int max_brightness; > + int prev_pwm, pwm; > + int brightness_step; > + int brightness; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + brightness_step = max_brightness / 10; > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness); > + usleep(100000); > + prev_pwm = read_target_backlight_pwm(debugfs); > + for (brightness = max_brightness - brightness_step; > + brightness > 0; > + brightness -= brightness_step) { > + backlight_write_brightness(brightness); > + usleep(100000); > + pwm = read_target_backlight_pwm(debugfs); > + igt_assert(pwm < prev_pwm); > + prev_pwm = pwm; > + } > + > +} > + > +static void backlight_monotonic_abm(igt_display_t *display, int debugfs) > +{ > + int ret, i; > + int max_brightness; > + int prev_pwm, pwm; > + int brightness_step; > + int brightness; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + brightness_step = max_brightness / 10; > + for (i = 1; i < 5; i++) { > + set_abm_level(display, i); > + backlight_write_brightness(max_brightness); > + usleep(100000); > + prev_pwm = read_target_backlight_pwm(debugfs); > + for (brightness = max_brightness - brightness_step; > + brightness > 0; > + brightness -= brightness_step) { > + backlight_write_brightness(brightness); > + usleep(100000); > + pwm = read_target_backlight_pwm(debugfs); > + igt_assert(pwm < prev_pwm); > + prev_pwm = pwm; > + } > + } > +} > + > +static void abm_enabled(igt_display_t *display, int debugfs) > +{ > + int ret, i; > + int max_brightness; > + int pwm, prev_pwm, pwm_without_abm; > + > + ret = backlight_read_max_brightness(&max_brightness); > + igt_assert_eq(ret, 0); > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness); > + usleep(100000); > + prev_pwm = read_target_backlight_pwm(debugfs); > + pwm_without_abm = prev_pwm; > + > + for (i = 1; i < 5; i++) { > + set_abm_level(display, i); > + usleep(100000); > + pwm = read_target_backlight_pwm(debugfs); > + igt_assert(pwm <= prev_pwm); > + igt_assert(pwm < pwm_without_abm); > + prev_pwm = pwm; > + } > + > +} > + > +static void abm_gradual(igt_display_t *display, int debugfs) > +{ > + int ret, i; > + int convergence_delay = 15; > + int prev_pwm, pwm, curr; > + int max_brightness; > + > + ret = backlight_read_max_brightness(&max_brightness); > + > + igt_assert_eq(ret, 0); > + > + set_abm_level(display, 0); > + backlight_write_brightness(max_brightness); > + > + sleep(convergence_delay); > + prev_pwm = read_target_backlight_pwm(debugfs); > + curr = read_current_backlight_pwm(debugfs); > + > + igt_assert_eq(prev_pwm, curr); > + set_abm_level(display, 4); > + for (i = 0; i < 10; i++) { > + usleep(100000); > + pwm = read_current_backlight_pwm(debugfs); > + igt_assert(pwm < prev_pwm); This seems like it very much depends on the usleep value above, the range of expected pwm reduction between no ABM and ABM level 4, as well as how quickly/slowly this executes. Should the usleep time be a function of the convergence_delay? Could this give us flaky test results? How many PWM steps have you usually seen for each iteration of this function? If it's large we're probably fine. Harry > + prev_pwm = pwm; > + } > + > + sleep(convergence_delay - 1); > + > + prev_pwm = read_target_backlight_pwm(debugfs); > + curr = read_current_backlight_pwm(debugfs); > + > + igt_assert_eq(prev_pwm, curr); > +} > + > +igt_main > +{ > + igt_display_t display; > + int debugfs; > + enum pipe pipe; > + igt_output_t *output; > + > + igt_skip_on_simulation(); > + > + igt_fixture { > + display.drm_fd = drm_open_driver_master(DRIVER_AMDGPU); > + > + if (display.drm_fd == -1) > + igt_skip("Not an amdgpu driver.\n"); > + > + debugfs = igt_debugfs_dir(display.drm_fd); > + > + kmstest_set_vt_graphics_mode(); > + > + igt_display_require(&display, display.drm_fd); > + > + skip_if_incompatible(&display, debugfs); > + > + for_each_pipe_with_valid_output(&display, pipe, output) > + break; > + } > + > + igt_subtest("dpms_cycle") > + backlight_dpms_cycle(&display, debugfs, output); > + igt_subtest("backlight_monotonic_basic") > + backlight_monotonic_basic(&display, debugfs); > + igt_subtest("backlight_monotonic_abm") > + backlight_monotonic_abm(&display, debugfs); > + igt_subtest("abm_enabled") > + abm_enabled(&display, debugfs); > + igt_subtest("abm_gradual") > + abm_gradual(&display, debugfs); > + > + igt_fixture { > + igt_display_fini(&display); > + } > +} > [-- Attachment #1.2: Type: text/html, Size: 29863 bytes --] [-- Attachment #2: Type: text/plain, Size: 154 bytes --] _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management 2018-12-07 14:34 ` Francis, David @ 2019-01-03 16:55 ` Li, Sun peng (Leo) 0 siblings, 0 replies; 5+ messages in thread From: Li, Sun peng (Leo) @ 2019-01-03 16:55 UTC (permalink / raw) To: Francis, David, Wentland, Harry, igt-dev@lists.freedesktop.org On 2018-12-07 9:34 a.m., Francis, David wrote: > On my machine, the gradual brightness reduction gives the following pwm > measurements > > pwm changed from 65535 to 64758 (-777) > pwm changed from 64758 to 63530 (-1228) > pwm changed from 63530 to 62594 (-936) > pwm changed from 62594 to 61751 (-843) > pwm changed from 61751 to 60825 (-926) > pwm changed from 60825 to 59480 (-1345) > pwm changed from 59480 to 58064 (-1416) > pwm changed from 58064 to 56967 (-1097) > pwm changed from 56967 to 55956 (-1011) > pwm changed from 55956 to 55027 (-929) > > I think we can assume a change of at least 1 > > ------------------------------------------------------------------------ > *From:* Wentland, Harry > *Sent:* November 29, 2018 3:45:30 PM > *To:* Francis, David; igt-dev@lists.freedesktop.org > *Subject:* Re: [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for > Adaptive Backlight Management > > > On 2018-11-28 3:51 p.m., David Francis wrote: >> Adaptive Backlight Management (ABM) is a power-saving >> feature on AMD ASICs that reduces backlight while increasing >> pixel contrast and luminance. This test confirms that >> ABM is present and enabled, and that backlight performance >> is sane. It uses AMD-specific debugfs entries to >> read the backlight PWM values. >> >> It has 5 subtests: >> >> dpms_cycle >> Sets brightness to half, then confirms that value is restored >> after dpms off and then on. >> >> backlight_monotonic_basic >> Sets brightness to ten different values, confirming that >> higher brightness values are brighter. >> >> backlight_monotonic_abm >> Same as backlight_monotonic_basic, but with abm enabled. >> >> abm_enabled >> Sets abm to its four intensity levels, confirming that >> abm reduces the backlight, and the reduction is greater >> for higher abm level. >> >> abm_gradual >> Sets abm to off and then maximum intensity, confirming >> that brightness decreases continually over the first >> second and eventually reaches the target value. >> This test takes 30s to run. >> >> Signed-off-by: David Francis <David.Francis@amd.com> >> --- >> tests/Makefile.sources | 1 + >> tests/amdgpu/amd_abm.c | 361 +++++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 362 insertions(+) >> create mode 100644 tests/amdgpu/amd_abm.c >> >> diff --git a/tests/Makefile.sources b/tests/Makefile.sources >> index 5620c1d6..3d560bee 100644 >> --- a/tests/Makefile.sources >> +++ b/tests/Makefile.sources >> @@ -19,6 +19,7 @@ AMDGPU_TESTS = \ >> amdgpu/amd_basic \ >> amdgpu/amd_cs_nop \ >> amdgpu/amd_prime \ >> + amdgpu/amd_abm \ >> $(NULL) >> >> TESTS_progs = \ >> diff --git a/tests/amdgpu/amd_abm.c b/tests/amdgpu/amd_abm.c >> new file mode 100644 >> index 00000000..90a6f99e >> --- /dev/null >> +++ b/tests/amdgpu/amd_abm.c >> @@ -0,0 +1,361 @@ >> +/* >> + * Copyright 2018 Advanced Micro Devices, Inc. >> + * >> + * Permission is hereby granted, free of charge, to any person obtaining a >> + * copy of this software and associated documentation files (the "Software"), >> + * to deal in the Software without restriction, including without limitation >> + * the rights to use, copy, modify, merge, publish, distribute, sublicense, >> + * and/or sell copies of the Software, and to permit persons to whom the >> + * Software is furnished to do so, subject to the following conditions: >> + * >> + * The above copyright notice and this permission notice shall be included in >> + * all copies or substantial portions of the Software. >> + * >> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR >> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, >> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL >> + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR >> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, >> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR >> + * OTHER DEALINGS IN THE SOFTWARE. >> + */ >> + >> +#include "igt.h" >> +#include "drmtest.h" >> +#include "igt_kms.h" >> +#include <limits.h> >> +#include <errno.h> >> +#include <stdbool.h> >> +#include <stdlib.h> >> +#include <stdio.h> >> +#include <string.h> >> +#include <fcntl.h> >> +#include <time.h> >> + >> +#define BACKLIGHT_PATH "/sys/class/backlight/amdgpu_bl0" >> + >> +static int read_current_backlight_pwm(int debugfs_dir) >> +{ >> + char buf[20]; >> + >> + igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", >> + buf, sizeof(buf)); >> + >> + return strtol(buf, NULL, 0); >> +} >> + >> +static int read_target_backlight_pwm(int debugfs_dir) >> +{ >> + char buf[20]; >> + >> + igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", >> + buf, sizeof(buf)); >> + >> + return strtol(buf, NULL, 0); >> +} >> + >> +static int backlight_write_brightness(int value) >> +{ >> + int fd; >> + char full[PATH_MAX]; >> + char src[64]; >> + int len; >> + >> + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "brightness") < PATH_MAX); >> + fd = open(full, O_WRONLY); >> + if (fd == -1) >> + return -errno; >> + >> + len = snprintf(src, sizeof(src), "%i", value); >> + len = write(fd, src, len); >> + close(fd); >> + >> + if (len < 0) >> + return len; >> + >> + return 0; >> +} >> + >> +static void set_abm_level(igt_display_t *display, int level) >> +{ >> + int i, ret; >> + int output_id; >> + drmModeObjectPropertiesPtr props; >> + uint32_t prop_id; >> + drmModePropertyPtr prop; >> + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; >> + >> + for (i = 0; i < display->n_outputs; i++) { >> + output_id = display->outputs[i].id; >> + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); >> + >> + for (i = 0; i < props->count_props; i++) { >> + prop_id = props->props[i]; >> + prop = drmModeGetProperty(display->drm_fd, prop_id); >> + >> + igt_assert(prop); >> + >> + if (strcmp(prop->name, "abm level") == 0) { >> + ret = drmModeObjectSetProperty(display->drm_fd, output_id, type, prop_id, level); >> + >> + igt_assert_eq(ret, 0); >> + } >> + >> + drmModeFreeProperty(prop); >> + } >> + } >> + >> +} >> + >> +static int backlight_read_max_brightness(int *result) >> +{ >> + int fd; >> + char full[PATH_MAX]; >> + char dst[64]; >> + int r, e; >> + >> + igt_assert(snprintf(full, PATH_MAX, "%s/%s", BACKLIGHT_PATH, "max_brightness") < PATH_MAX); >> + >> + fd = open(full, O_RDONLY); >> + if (fd == -1) >> + return -errno; >> + >> + r = read(fd, dst, sizeof(dst)); >> + e = errno; >> + close(fd); >> + >> + if (r < 0) >> + return -e; >> + >> + errno = 0; >> + *result = strtol(dst, NULL, 10); >> + return errno; >> +} >> + >> +static void skip_if_incompatible(igt_display_t *display, int debugfs_dir) >> +{ >> + int ret, i; >> + char buf[20]; >> + bool abm_prop_exists; >> + int output_id; >> + drmModeObjectPropertiesPtr props; >> + uint32_t type = DRM_MODE_OBJECT_CONNECTOR; >> + uint32_t prop_id; >> + drmModePropertyPtr prop; >> + >> + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_current_backlight_pwm", >> + buf, sizeof(buf)); >> + >> + if (ret < 0) >> + igt_skip("No current backlight debugfs entry.\n"); >> + >> + ret = igt_debugfs_simple_read(debugfs_dir, "amdgpu_target_backlight_pwm", >> + buf, sizeof(buf)); >> + >> + if (ret < 0) >> + igt_skip("No target backlight debugfs entry.\n"); >> + >> + abm_prop_exists = false; >> + >> + for (i = 0; i < display->n_outputs; i++) { >> + output_id = display->outputs[i].id; >> + props = drmModeObjectGetProperties(display->drm_fd, output_id, type); >> + >> + for (i = 0; i < props->count_props; i++) { >> + prop_id = props->props[i]; >> + prop = drmModeGetProperty(display->drm_fd, prop_id); >> + >> + if (strcmp(prop->name, "abm level") == 0) >> + abm_prop_exists = true; >> + >> + drmModeFreeProperty(prop); >> + } >> + } >> + >> + if (!abm_prop_exists) >> + igt_skip("No abm level property on any connector.\n"); >> +} >> + >> + >> +static void backlight_dpms_cycle(igt_display_t *display, int debugfs, igt_output_t *output) >> +{ >> + int ret; >> + int max_brightness; >> + int pwm_1, pwm_2; >> + >> + ret = backlight_read_max_brightness(&max_brightness); >> + igt_assert_eq(ret, 0); >> + >> + set_abm_level(display, 0); >> + backlight_write_brightness(max_brightness / 2); >> + usleep(100000); >> + pwm_1 = read_target_backlight_pwm(debugfs); >> + >> + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_OFF); >> + kmstest_set_connector_dpms(display->drm_fd, output->config.connector, DRM_MODE_DPMS_ON); >> + usleep(100000); >> + pwm_2 = read_target_backlight_pwm(debugfs); >> + igt_assert_eq(pwm_1, pwm_2); >> +} >> + >> +static void backlight_monotonic_basic(igt_display_t *display, int debugfs) >> +{ >> + int ret; >> + int max_brightness; >> + int prev_pwm, pwm; >> + int brightness_step; >> + int brightness; >> + >> + ret = backlight_read_max_brightness(&max_brightness); >> + igt_assert_eq(ret, 0); >> + >> + brightness_step = max_brightness / 10; >> + >> + set_abm_level(display, 0); >> + backlight_write_brightness(max_brightness); >> + usleep(100000); >> + prev_pwm = read_target_backlight_pwm(debugfs); >> + for (brightness = max_brightness - brightness_step; >> + brightness > 0; >> + brightness -= brightness_step) { >> + backlight_write_brightness(brightness); >> + usleep(100000); >> + pwm = read_target_backlight_pwm(debugfs); >> + igt_assert(pwm < prev_pwm); >> + prev_pwm = pwm; >> + } >> + >> +} >> + >> +static void backlight_monotonic_abm(igt_display_t *display, int debugfs) >> +{ >> + int ret, i; >> + int max_brightness; >> + int prev_pwm, pwm; >> + int brightness_step; >> + int brightness; >> + >> + ret = backlight_read_max_brightness(&max_brightness); >> + igt_assert_eq(ret, 0); >> + >> + brightness_step = max_brightness / 10; >> + for (i = 1; i < 5; i++) { >> + set_abm_level(display, i); >> + backlight_write_brightness(max_brightness); >> + usleep(100000); >> + prev_pwm = read_target_backlight_pwm(debugfs); >> + for (brightness = max_brightness - brightness_step; >> + brightness > 0; >> + brightness -= brightness_step) { >> + backlight_write_brightness(brightness); >> + usleep(100000); >> + pwm = read_target_backlight_pwm(debugfs); >> + igt_assert(pwm < prev_pwm); >> + prev_pwm = pwm; >> + } >> + } >> +} >> + >> +static void abm_enabled(igt_display_t *display, int debugfs) >> +{ >> + int ret, i; >> + int max_brightness; >> + int pwm, prev_pwm, pwm_without_abm; >> + >> + ret = backlight_read_max_brightness(&max_brightness); >> + igt_assert_eq(ret, 0); >> + >> + set_abm_level(display, 0); >> + backlight_write_brightness(max_brightness); >> + usleep(100000); >> + prev_pwm = read_target_backlight_pwm(debugfs); >> + pwm_without_abm = prev_pwm; >> + >> + for (i = 1; i < 5; i++) { >> + set_abm_level(display, i); >> + usleep(100000); >> + pwm = read_target_backlight_pwm(debugfs); >> + igt_assert(pwm <= prev_pwm); >> + igt_assert(pwm < pwm_without_abm); >> + prev_pwm = pwm; >> + } >> + >> +} >> + >> +static void abm_gradual(igt_display_t *display, int debugfs) >> +{ >> + int ret, i; >> + int convergence_delay = 15; >> + int prev_pwm, pwm, curr; >> + int max_brightness; >> + >> + ret = backlight_read_max_brightness(&max_brightness); >> + >> + igt_assert_eq(ret, 0); >> + >> + set_abm_level(display, 0); >> + backlight_write_brightness(max_brightness); >> + >> + sleep(convergence_delay); >> + prev_pwm = read_target_backlight_pwm(debugfs); >> + curr = read_current_backlight_pwm(debugfs); >> + >> + igt_assert_eq(prev_pwm, curr); >> + set_abm_level(display, 4); >> + for (i = 0; i < 10; i++) { >> + usleep(100000); >> + pwm = read_current_backlight_pwm(debugfs); >> + igt_assert(pwm < prev_pwm); > > This seems like it very much depends on the usleep value above, the > range of expected pwm reduction between no ABM and ABM level 4, as well > as how quickly/slowly this executes. > > Should the usleep time be a function of the convergence_delay? > > Could this give us flaky test results? > > How many PWM steps have you usually seen for each iteration of this > function? If it's large we're probably fine. > > Harry > >> + prev_pwm = pwm; >> + } >> + >> + sleep(convergence_delay - 1); >> + >> + prev_pwm = read_target_backlight_pwm(debugfs); >> + curr = read_current_backlight_pwm(debugfs); >> + >> + igt_assert_eq(prev_pwm, curr); >> +} >> + >> +igt_main >> +{ >> + igt_display_t display; >> + int debugfs; >> + enum pipe pipe; >> + igt_output_t *output; >> + >> + igt_skip_on_simulation(); >> + >> + igt_fixture { >> + display.drm_fd = drm_open_driver_master(DRIVER_AMDGPU); >> + >> + if (display.drm_fd == -1) >> + igt_skip("Not an amdgpu driver.\n"); >> + >> + debugfs = igt_debugfs_dir(display.drm_fd); >> + >> + kmstest_set_vt_graphics_mode(); >> + >> + igt_display_require(&display, display.drm_fd); >> + >> + skip_if_incompatible(&display, debugfs); >> + >> + for_each_pipe_with_valid_output(&display, pipe, output) >> + break; Are we guaranteed to end up with the correct output here? This would give us the first valid output to run the dpms_cycle test on, but will it be the ABM output? pm_backlight.c seems to be doing some name matching to check this. Leo >> + } >> + >> + igt_subtest("dpms_cycle") >> + backlight_dpms_cycle(&display, debugfs, output); >> + igt_subtest("backlight_monotonic_basic") >> + backlight_monotonic_basic(&display, debugfs); >> + igt_subtest("backlight_monotonic_abm") >> + backlight_monotonic_abm(&display, debugfs); >> + igt_subtest("abm_enabled") >> + abm_enabled(&display, debugfs); >> + igt_subtest("abm_gradual") >> + abm_gradual(&display, debugfs); >> + >> + igt_fixture { >> + igt_display_fini(&display); >> + } >> +} >> > > _______________________________________________ > igt-dev mailing list > igt-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/igt-dev > _______________________________________________ igt-dev mailing list igt-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/igt-dev ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-01-03 16:55 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-11-28 20:51 [igt-dev] [PATCH i-g-t] tests/amdgpu: Add test for Adaptive Backlight Management David Francis 2018-11-29 0:20 ` [igt-dev] ✓ Fi.CI.BAT: success for " Patchwork 2018-11-29 20:45 ` [igt-dev] [PATCH i-g-t] " Wentland, Harry 2018-12-07 14:34 ` Francis, David 2019-01-03 16:55 ` Li, Sun peng (Leo)
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox