summaryrefslogtreecommitdiff
path: root/tests/amdgpu
diff options
context:
space:
mode:
authorEryk Brol <eryk.brol@amd.com>2021-12-16 09:55:01 -0500
committerRodrigo Siqueira <Rodrigo.Siqueira@amd.com>2021-12-21 15:40:12 -0500
commit731e09c15b4fd559ce8aec30065fccde17a9b834 (patch)
treeb5dfc3bbe3db33f423dd07734c032ca79b57b22e /tests/amdgpu
parent2f59b36a40331e98610dab12baefbe82b6e3cef0 (diff)
tests/amdgpu: Introduces DP DSC test
This commit adds a DP DSC test that checks: * Forces DSC on/off and ensures it is reset properly * Check DSC slice height property * Verify various DSC slice dimensions * Tests various combinations of link_rate + lane_count and logs if DSC enabled/disabled Tests different bpc settings and logs if DSC is enabled/disabled Change since V3: - Drop useless test Change since V2: - Remove IGT_CRTC_DSC_SLICE_HEIGHT crtc property from this commit Change since V1: - Rebase Cc: Harry Wentland <harry.wentland@amd.com> Cc: Nicholas Choi <Nicholas.Choi@amd.com> Cc: Mark Yacoub <markyacoub@chromium.org> Cc: Hayden Goodfellow <hayden.goodfellow@amd.com> Cc: Hersen Wu <hersenxs.wu@amd.com> Cc: Roman Li <roman.li@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Mikita Lipski <mikita.lipski@amd.com> Signed-off-by: Eryk Brol <eryk.brol@amd.com>
Diffstat (limited to 'tests/amdgpu')
-rw-r--r--tests/amdgpu/amd_dp_dsc.c607
-rw-r--r--tests/amdgpu/meson.build1
2 files changed, 608 insertions, 0 deletions
diff --git a/tests/amdgpu/amd_dp_dsc.c b/tests/amdgpu/amd_dp_dsc.c
new file mode 100644
index 00000000..e3f3a39f
--- /dev/null
+++ b/tests/amdgpu/amd_dp_dsc.c
@@ -0,0 +1,607 @@
+/*
+ * Copyright 2021 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 "igt_amd.h"
+#include "sw_sync.h"
+#include <fcntl.h>
+#include <signal.h>
+
+#define NUM_SLICE_SLOTS 4
+
+/* Maximumm pipes on any AMD ASIC. */
+#define MAX_PIPES 6
+
+/* Common test data. */
+typedef struct data {
+ igt_display_t display;
+ igt_plane_t *primary[MAX_PIPES];
+ igt_output_t *output[MAX_PIPES];
+ igt_pipe_t *pipe[MAX_PIPES];
+ igt_pipe_crc_t *pipe_crc[MAX_PIPES];
+ drmModeModeInfo mode[MAX_PIPES];
+ enum pipe pipe_id[MAX_PIPES];
+ int fd;
+} data_t;
+
+/* BPC connector state. */
+typedef struct output_bpc {
+ unsigned int current;
+ unsigned int maximum;
+} output_bpc_t;
+
+/* Common test cleanup. */
+static void test_fini(data_t *data)
+{
+ igt_display_t *display = &data->display;
+ int i;
+
+ for (i = 0; i < display->n_pipes; ++i) {
+ igt_pipe_crc_free(data->pipe_crc[i]);
+ }
+
+ igt_display_reset(display);
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
+}
+
+/* Common test setup. */
+static void test_init(data_t *data)
+{
+ igt_display_t *display = &data->display;
+ int i, n;
+
+ for (i = 0; i < display->n_pipes; ++i) {
+ data->pipe_id[i] = PIPE_A + i;
+ data->pipe[i] = &data->display.pipes[data->pipe_id[i]];
+ data->primary[i] = igt_pipe_get_plane_type(
+ data->pipe[i], DRM_PLANE_TYPE_PRIMARY);
+ data->pipe_crc[i] =
+ igt_pipe_crc_new(data->fd, data->pipe_id[i], "auto");
+ }
+
+ for (i = 0, n = 0; i < display->n_outputs && n < display->n_pipes; ++i) {
+ igt_output_t *output = &display->outputs[i];
+ data->output[n] = output;
+
+ /* Only allow physically connected displays for the tests. */
+ if (!igt_output_is_connected(output))
+ continue;
+
+ /* Ensure that outpus are DP, DSC & FEC capable*/
+ if (!(is_dp_fec_supported(data->fd, output->name) &&
+ is_dp_dsc_supported(data->fd, output->name)))
+ continue;
+
+ if (output->config.connector->connector_type !=
+ DRM_MODE_CONNECTOR_DisplayPort)
+ continue;
+
+ igt_assert(kmstest_get_connector_default_mode(
+ data->fd, output->config.connector, &data->mode[n]));
+
+ n += 1;
+ }
+
+ igt_display_reset(display);
+}
+
+static void test_dsc_enable(data_t *data)
+{
+ bool dsc_on, dsc_after, dsc_before;
+ igt_display_t *display = &data->display;
+ igt_output_t *output;
+ igt_fb_t ref_fb;
+ int i, test_conn_cnt = 0;
+
+ test_init(data);
+ igt_enable_connectors(data->fd);
+
+ for (i = 0; i < display->n_pipes; i++) {
+ /* Setup the output */
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ igt_create_pattern_fb(data->fd,
+ data->mode[i].hdisplay,
+ data->mode[i].vdisplay,
+ DRM_FORMAT_XRGB8888,
+ 0,
+ &ref_fb);
+ igt_output_set_pipe(output, data->pipe_id[i]);
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
+
+ test_conn_cnt++;
+
+ /* Save pipe's initial DSC state */
+ dsc_before = igt_amd_read_dsc_clock_status(data->fd, output->name);
+
+ /* Force enable DSC */
+ igt_amd_write_dsc_clock_en(data->fd, output->name, DSC_FORCE_ON);
+
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ /* Check if DSC is enabled */
+ dsc_on = igt_amd_read_dsc_clock_status(data->fd, output->name) == 1;
+
+ /* Revert DSC to automatic state */
+ igt_amd_write_dsc_clock_en(data->fd, output->name, DSC_FORCE_OFF);
+
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+ igt_display_commit_atomic(display,DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ dsc_after = igt_amd_read_dsc_clock_status(data->fd, output->name);
+
+ /* Revert DSC back to automatic mechanism by disabling state overwrites*/
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+
+ igt_amd_write_dsc_clock_en(data->fd, output->name, DSC_AUTOMATIC);
+
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ igt_assert_f(dsc_on, "Enabling DSC on pipe failed.\n");
+ igt_assert_f(dsc_after == dsc_before, "Reverting DSC to initial state failed.\n");
+
+ /* Cleanup fb */
+ igt_remove_fb(data->fd, &ref_fb);
+ }
+
+ test_fini(data);
+ igt_skip_on(test_conn_cnt == 0);
+}
+
+static bool update_slice_height(data_t *data, int v_addressable,
+ int *num_slices, igt_output_t *output, int conn_idx, igt_fb_t ref_fb)
+{
+ int i;
+ bool pass = true;
+
+ for(i = 0; i < NUM_SLICE_SLOTS; i++) {
+ int act_slice_height;
+ int slice_height = v_addressable / num_slices[i] + (v_addressable % num_slices[i]);
+
+ /* Overwrite DSC slice height */
+ igt_amd_write_dsc_param_slice_height(data->fd, output->name, slice_height);
+ igt_plane_set_fb(data->primary[conn_idx], &ref_fb);
+ igt_display_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ igt_info("Forcing slice height: slice height %d num slices vertical %d\n", slice_height, num_slices[i]);
+
+ act_slice_height = igt_amd_read_dsc_param_slice_height(data->fd, output->name);
+
+ igt_info("Reading slice height: actual slice height %d VS assigned slice height %d\n", act_slice_height, slice_height);
+
+ pass = (slice_height == act_slice_height);
+
+ if (!pass)
+ break;
+ }
+
+ igt_amd_write_dsc_param_slice_height(data->fd, output->name, 0);
+ igt_plane_set_fb(data->primary[conn_idx], &ref_fb);
+ igt_display_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ return pass;
+}
+
+static bool update_slice_width(data_t *data, int h_addressable,
+ int *num_slices, igt_output_t *output, int conn_idx, igt_fb_t ref_fb)
+{
+ int i;
+ bool pass = true;
+
+ for(i = 0; i < NUM_SLICE_SLOTS; i++) {
+ int act_slice_width;
+ int slice_width = h_addressable / num_slices[i] + (h_addressable % num_slices[i]);
+
+ /* Overwrite DSC slice width */
+ igt_amd_write_dsc_param_slice_width(data->fd, output->name, slice_width);
+ igt_plane_set_fb(data->primary[conn_idx], &ref_fb);
+ igt_display_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ igt_info("Forcing slice width: slice width %d num slices horisontal %d\n", slice_width, num_slices[i]);
+
+ act_slice_width = igt_amd_read_dsc_param_slice_width(data->fd, output->name);
+
+ igt_info("Reading slice width: actual slice width %d VS assigned slice width %d\n", act_slice_width, slice_width);
+
+ pass = (slice_width == act_slice_width);
+
+ if (!pass)
+ break;
+ }
+
+ igt_amd_write_dsc_param_slice_width(data->fd, output->name, 0);
+ igt_plane_set_fb(data->primary[conn_idx], &ref_fb);
+ igt_display_commit_atomic(&data->display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ return pass;
+}
+
+static void test_dsc_slice_dimensions_change(data_t *data)
+{
+ bool dsc_on, dsc_after, dsc_before;
+ igt_output_t *output;
+ igt_display_t *display = &data->display;
+ igt_fb_t ref_fb;
+ int num_slices [] = { 1, 2, 4, 8 };
+ int h_addressable, v_addressable;
+ bool ret_slice_height= false, ret_slice_width = false;
+ int i, test_conn_cnt = 0;
+
+ test_init(data);
+ igt_enable_connectors(data->fd);
+
+ for (i = 0; i < display->n_pipes; i++) {
+ /* Setup the output */
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ igt_create_pattern_fb(data->fd,
+ data->mode[i].hdisplay,
+ data->mode[i].vdisplay,
+ DRM_FORMAT_XRGB8888,
+ 0,
+ &ref_fb);
+ igt_output_set_pipe(output, data->pipe_id[i]);
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
+
+ test_conn_cnt++;
+
+ h_addressable = data->mode->hdisplay;
+ v_addressable = data->mode->vdisplay;
+
+ igt_info("Mode info: v_ative %d h_active %d\n", v_addressable, h_addressable);
+
+ /* Save pipe's initial DSC state */
+ dsc_before = igt_amd_read_dsc_clock_status(data->fd, output->name);
+
+ /* Force enable DSC */
+ igt_amd_write_dsc_clock_en(data->fd, output->name, DSC_FORCE_ON);
+
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ /* Check if DSC is enabled */
+ dsc_on = igt_amd_read_dsc_clock_status(data->fd, output->name) == 1;
+
+ if (dsc_on) {
+ ret_slice_height = update_slice_height(data, v_addressable, num_slices, output, i, ref_fb);
+ ret_slice_width = update_slice_width(data, h_addressable, num_slices, output, i, ref_fb);
+ }
+
+ /* Force disable DSC */
+ igt_amd_write_dsc_clock_en(data->fd, output->name, DSC_FORCE_OFF);
+
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ dsc_after = igt_amd_read_dsc_clock_status(data->fd, output->name);
+
+ /* Revert DSC back to automatic mechanism by disabling state overwrites*/
+ igt_plane_set_fb(data->primary[i], &ref_fb);
+
+ igt_amd_write_dsc_clock_en(data->fd, output->name, DSC_AUTOMATIC);
+
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ igt_assert_f(dsc_on, "Enabling DSC on pipe failed.\n");
+ igt_assert_f(ret_slice_height, "Changing slice height failed.\n");
+ igt_assert_f(ret_slice_width, "Changing slice width failed.\n");
+ igt_assert_f(dsc_after == dsc_before, "Reverting DSC to initial state failed.\n");
+
+ /* Cleanup fb */
+ igt_remove_fb(data->fd, &ref_fb);
+ }
+
+ test_fini(data);
+ igt_skip_on(test_conn_cnt == 0);
+}
+
+static void test_dsc_link_settings(data_t *data)
+{
+ igt_output_t *output;
+ igt_fb_t ref_fb[MAX_PIPES];
+ igt_crc_t ref_crc[MAX_PIPES], new_crc[MAX_PIPES];
+ int lane_count[4], link_rate[4], link_spread[4];
+ igt_display_t *display = &data->display;
+ int i, lc, lr;
+ bool dsc_on;
+ const enum dc_lane_count lane_count_vals[] =
+ {
+ LANE_COUNT_TWO,
+ LANE_COUNT_FOUR
+ };
+ const enum dc_link_rate link_rate_vals[] =
+ {
+ LINK_RATE_LOW,
+ LINK_RATE_HIGH,
+ LINK_RATE_HIGH2,
+ LINK_RATE_HIGH3
+ };
+
+ test_init(data);
+
+ /* Setup all outputs */
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ igt_create_pattern_fb(data->fd,
+ data->mode[i].hdisplay,
+ data->mode[i].vdisplay,
+ DRM_FORMAT_XRGB8888,
+ 0,
+ &ref_fb[i]);
+ igt_output_set_pipe(output, data->pipe_id[i]);
+ igt_plane_set_fb(data->primary[i], &ref_fb[i]);
+ }
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
+
+ /* Collect reference CRCs */
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ igt_pipe_crc_collect_crc(data->pipe_crc[i], &ref_crc[i]);
+ }
+
+ for (lc = 0; lc < ARRAY_SIZE(lane_count_vals); lc++) {
+ for (lr = 0; lr < ARRAY_SIZE(link_rate_vals); lr++) {
+ /* Write new link_settings */
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ /* Write lower link settings */
+ igt_info("Applying lane count: %d, link rate 0x%02x, on default training\n",
+ lane_count_vals[lc], link_rate_vals[lr]);
+ igt_amd_write_link_settings(data->fd, output->name,
+ lane_count_vals[lc],
+ link_rate_vals[lr],
+ LINK_TRAINING_DEFAULT);
+ usleep(500 * MSEC_PER_SEC);
+ }
+
+ /* Trigger commit after writing new link settings */
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ /* Verify lower link settings */
+ igt_amd_read_link_settings(data->fd, output->name,
+ lane_count,
+ link_rate,
+ link_spread);
+
+ igt_assert_f(lane_count[0] == lane_count_vals[lc], "Lowering lane count settings failed\n");
+ igt_assert_f(link_rate[0] == link_rate_vals[lr], "Lowering link rate settings failed\n");
+
+ /* Log current mode and DSC status */
+ dsc_on = igt_amd_read_dsc_clock_status(data->fd, output->name) == 1;
+ igt_info("Current mode is: %dx%d @%dHz -- DSC is: %s\n",
+ data->mode[i].hdisplay,
+ data->mode[i].vdisplay,
+ data->mode[i].vrefresh,
+ dsc_on ? "ON" : "OFF");
+
+ igt_pipe_crc_collect_crc(data->pipe_crc[i], &new_crc[i]);
+ igt_assert_crc_equal(&ref_crc[i], &new_crc[i]);
+ }
+ }
+ }
+
+ /* Cleanup all fbs */
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+ igt_remove_fb(data->fd, &ref_fb[i]);
+ }
+
+ test_fini(data);
+}
+
+/* Returns the current and maximum bpc from the connector debugfs. */
+static output_bpc_t get_output_bpc(int data_fd, char *connector_name)
+{
+ char buf[256];
+ char *start_loc;
+ int fd, res;
+ output_bpc_t info;
+
+ fd = igt_debugfs_connector_dir(data_fd, connector_name, O_RDONLY);
+ igt_assert(fd >= 0);
+
+ res = igt_debugfs_simple_read(fd, "output_bpc", buf, sizeof(buf));
+
+ igt_require(res > 0);
+
+ close(fd);
+
+ igt_assert(start_loc = strstr(buf, "Current: "));
+ igt_assert_eq(sscanf(start_loc, "Current: %u", &info.current), 1);
+
+ igt_assert(start_loc = strstr(buf, "Maximum: "));
+ igt_assert_eq(sscanf(start_loc, "Maximum: %u", &info.maximum), 1);
+
+ return info;
+}
+
+/* Verifies that connector has the correct output bpc */
+static void assert_output_bpc(int data_fd, char *connector_name, unsigned int bpc)
+{
+ output_bpc_t info = get_output_bpc(data_fd, connector_name);
+
+ igt_require_f(info.maximum >= bpc,
+ "Monitor doesn't support %u bpc, max is %u\n", bpc,
+ info.maximum);
+
+ igt_assert_eq(info.current, bpc);
+}
+
+/* Returns the highest bpc this dispaly supports */
+static int get_max_supported_bpc(int data_fd, char *connector_name)
+{
+ output_bpc_t info = get_output_bpc(data_fd, connector_name);
+ return info.maximum;
+}
+
+static void test_dsc_bpc(data_t *data)
+{
+ igt_output_t *output;
+ igt_fb_t ref_fb[MAX_PIPES];
+ igt_crc_t test_crc;
+ igt_display_t *display = &data->display;
+ int i, bpc, max_supported_bpc[MAX_PIPES];
+ bool dsc_on;
+ const int bpc_vals[] = {12, 10, 8};
+
+ test_init(data);
+
+ /* Find max supported bpc */
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+ igt_info("Checking bpc support of conn %s\n", output->name);
+ max_supported_bpc[i] = get_max_supported_bpc(data->fd, output->name);
+ }
+
+ /* Setup all outputs */
+ for (bpc = 0; bpc < ARRAY_SIZE(bpc_vals); bpc++) {
+ igt_info("Testing bpc = %d\n", bpc_vals[bpc]);
+
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ if (max_supported_bpc[i] < bpc_vals[bpc]) {
+ igt_info("Display doesn't support bpc of %d, max is %d. Skipping to next bpc value.\n", bpc_vals[bpc], max_supported_bpc[i]);
+ continue;
+ }
+ igt_info("Setting bpc = %d\n", bpc_vals[bpc]);
+ igt_output_set_prop_value(output, IGT_CONNECTOR_MAX_BPC, bpc_vals[bpc]);
+ igt_create_pattern_fb(data->fd,
+ data->mode[i].hdisplay,
+ data->mode[i].vdisplay,
+ DRM_FORMAT_XRGB8888,
+ 0,
+ &ref_fb[i]);
+ igt_output_set_pipe(output, data->pipe_id[i]);
+ igt_plane_set_fb(data->primary[i], &ref_fb[i]);
+ }
+
+ igt_display_commit_atomic(display, DRM_MODE_ATOMIC_ALLOW_MODESET, 0);
+
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ if (max_supported_bpc[i] < bpc_vals[bpc])
+ continue;
+
+ /* Check that crc is non-zero */
+ igt_pipe_crc_collect_crc(data->pipe_crc[i], &test_crc);
+ igt_assert(test_crc.crc[0] && test_crc.crc[1] && test_crc.crc[2]);
+
+ /* Check current bpc */
+ igt_info("Verifying display %s has correct bpc\n", output->name);
+ assert_output_bpc(data->fd, output->name, bpc_vals[bpc]);
+
+ /* Log current mode and DSC status */
+ dsc_on = igt_amd_read_dsc_clock_status(data->fd, output->name) == 1;
+ igt_info("Current mode is: %dx%d @%dHz -- DSC is: %s\n",
+ data->mode[i].hdisplay,
+ data->mode[i].vdisplay,
+ data->mode[i].vrefresh,
+ dsc_on ? "ON" : "OFF");
+ }
+
+ /* Cleanup all fbs */
+ for (i = 0; i < display->n_pipes; i++) {
+ output = data->output[i];
+ if (!output || !igt_output_is_connected(output))
+ continue;
+
+ if (max_supported_bpc[i] < bpc_vals[bpc])
+ continue;
+
+ igt_remove_fb(data->fd, &ref_fb[i]);
+ }
+ }
+
+ test_fini(data);
+}
+
+igt_main
+{
+ data_t data = { 0 };
+
+ igt_skip_on_simulation();
+
+ igt_fixture
+ {
+ data.fd = drm_open_driver_master(DRIVER_ANY);
+
+ igt_display_require(&data.display, data.fd);
+ igt_require(data.display.is_atomic);
+ igt_display_require_output(&data.display);
+
+ igt_amd_require_dsc(&data.display, data.fd);
+ kmstest_set_vt_graphics_mode();
+ }
+
+ igt_describe("Forces DSC on/off & ensures it is reset properly");
+ igt_subtest("dsc-enable-basic")
+ test_dsc_enable(&data);
+
+ igt_describe("Tests various DSC slice dimensions");
+ igt_subtest("dsc-slice-dimensions-change")
+ test_dsc_slice_dimensions_change(&data);
+
+ igt_describe("Tests various combinations of link_rate + lane_count and logs if DSC enabled/disabled");
+ igt_subtest("dsc-link-settings")
+ test_dsc_link_settings(&data);
+
+ igt_describe("Tests different bpc settings and logs if DSC is enabled/disabled");
+ igt_subtest("dsc-bpc")
+ test_dsc_bpc(&data);
+
+ igt_fixture
+ {
+ igt_reset_connectors();
+ igt_display_fini(&data.display);
+ }
+}
diff --git a/tests/amdgpu/meson.build b/tests/amdgpu/meson.build
index d232e490..d8e8ddfb 100644
--- a/tests/amdgpu/meson.build
+++ b/tests/amdgpu/meson.build
@@ -17,6 +17,7 @@ if libdrm_amdgpu.found()
'amd_link_settings',
'amd_vrr_range',
'amd_mode_switch',
+ 'amd_dp_dsc',
'amd_psr',
'amd_plane',
]