* [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