[PATCH i-g-t 8/9] tests/intel/kms_dp_fallback: add test for validating fallback
Reddy Guddati, Santhosh
santhosh.reddy.guddati at intel.com
Tue Aug 20 03:23:42 UTC 2024
Hi Kunal,
Can we use macros something like below to make code readable ?
#define STR_LINK_RATE(link_rate) \
(link_rate == DP_LINK_RATE_162000 ? "1.62 Gbps" : \
link_rate == DP_LINK_RATE_216000 ? "2.16 Gbps" : \
link_rate == DP_LINK_RATE_243000 ? "2.43 Gbps" : \
link_rate == DP_LINK_RATE_270000 ? "2.70 Gbps" : \
link_rate == DP_LINK_RATE_324000 ? "3.24 Gbps" : \
link_rate == DP_LINK_RATE_432000 ? "4.32 Gbps" : \
link_rate == DP_LINK_RATE_540000 ? "5.40 Gbps" : \
link_rate == DP_LINK_RATE_675000 ? "6.75 Gbps" : \
link_rate == DP_LINK_RATE_810000 ? "8.10 Gbps" : \
link_rate == DP_LINK_RATE_1000000 ? "10.00 Gbps" : \
link_rate == DP_LINK_RATE_1350000 ? "13.50 Gbps" : \
link_rate == DP_LINK_RATE_2000000 ? "20.00 Gbps" : \
(igt_assert_f(0, "Invalid link rate %d\n", link_rate), NULL))
#define STR_LINK_TO_WRITE(link_rate) \
(link_rate == DP_LINK_RATE_162000 ? "162000" : \
link_rate == DP_LINK_RATE_216000 ? "216000" : \
link_rate == DP_LINK_RATE_243000 ? "243000" : \
link_rate == DP_LINK_RATE_270000 ? "270000" : \
link_rate == DP_LINK_RATE_324000 ? "324000" : \
link_rate == DP_LINK_RATE_432000 ? "432000" : \
link_rate == DP_LINK_RATE_540000 ? "540000" : \
link_rate == DP_LINK_RATE_675000 ? "675000" : \
link_rate == DP_LINK_RATE_810000 ? "810000" : \
link_rate == DP_LINK_RATE_1000000 ? "1000000" : \
link_rate == DP_LINK_RATE_1350000 ? "1350000" : \
link_rate == DP_LINK_RATE_2000000 ? "2000000" : \
(igt_assert_f(0, "Invalid link rate %d\n", link_rate), NULL))
#define STR_LANE_COUNT(lane_count) \
(lane_count == DP_LANE_COUNT_1 ? "1" : \
lane_count == DP_LANE_COUNT_2 ? "2" : \
lane_count == DP_LANE_COUNT_4 ? "4" : \
(igt_assert_f(0, "Invalid lane count %d\n", lane_count), NULL))
DP_LINK_RATE link_rate = DP_LINK_RATE_540000;
const char* link_rate_str = STR_LINK_RATE(link_rate);
printf("Link rate: %s\n", link_rate_str);
Thanks,
santhosh
On 10-06-2024 02:55, Kunal Joshi wrote:
> add fallback test which tries to validate fallback by
> reducing link rate / lane count, until retrain is disabled
> or the lowest mode bw requirements are met.
>
> Signed-off-by: Kunal Joshi <kunal1.joshi at intel.com>
> ---
> tests/intel/kms_dp_fallback.c | 207 ++++++++++++++++++++++++++++++++++
> tests/meson.build | 1 +
> 2 files changed, 208 insertions(+)
> create mode 100644 tests/intel/kms_dp_fallback.c
>
> diff --git a/tests/intel/kms_dp_fallback.c b/tests/intel/kms_dp_fallback.c
> new file mode 100644
> index 000000000..935a77cc6
> --- /dev/null
> +++ b/tests/intel/kms_dp_fallback.c
> @@ -0,0 +1,207 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 20234 Intel Corporation
> + */
> +
> +/**
> + * TEST: kms dp fallback
> + * Category: Display
> + * Description: Test link training fallback for DP connectors
> + * Driver requirement: i915, xe
> + * Functionality: link training
> + * Mega feature: General Display Features
> + * Test category: functionality test
> + */
> +
> +#include <sys/types.h>
> +
> +#include "igt.h"
> +#include "igt_psr.h"
> +
> +/**
> + * SUBTEST: fallback
> + * Description: Test fallback
> + */
> +
> +typedef struct {
> + int drm_fd;
> + igt_display_t display;
> + drmModeModeInfo *mode;
> + igt_output_t *output;
> + enum pipe pipe;
> + struct igt_fb fb;
> + struct igt_plane *primary;
> +} data_t;
> +
> +IGT_TEST_DESCRIPTION("Test link training fallback for DP connectors");
> +
> +#define BITS_PER_PIXEL 24
> +#define ENCODING_OVERHEAD_8b_10b 0.8
> +#define ENCODING_OVERHEAD_128b_132b 0.9723
> +
> +static const char *str_link_rate(enum dp_link_rate link_rate)
> +{
> + switch (link_rate) {
> + case DP_LINK_RATE_162000:
> + return "1.62 Gbps";
> + case DP_LINK_RATE_216000:
> + return "2.16 Gbps";
> + case DP_LINK_RATE_243000:
> + return "2.43 Gbps";
> + case DP_LINK_RATE_270000:
> + return "2.70 Gbps";
> + case DP_LINK_RATE_324000:
> + return "3.24 Gbps";
> + case DP_LINK_RATE_432000:
> + return "4.32 Gbps";
> + case DP_LINK_RATE_540000:
> + return "5.40 Gbps";
> + case DP_LINK_RATE_675000:
> + return "6.75 Gbps";
> + case DP_LINK_RATE_810000:
> + return "8.10 Gbps";
> + case DP_LINK_RATE_1000000:
> + return "10.00 Gbps";
> + case DP_LINK_RATE_1350000:
> + return "13.50 Gbps";
> + case DP_LINK_RATE_2000000:
> + return "20.00 Gbps";
> + default:
> + igt_assert_f(0, "Invalid link rate %d\n", link_rate);
> + }
> +}
> +
> +static void find_min_dp_config(int drm_fd, drmModeModeInfo mode, igt_output_t *output, uint64_t *min_link_rate, int *min_lane_count)
> +{
> + int i, lanes;
> + int num_rates = 0;
> + float overhead;
> + uint64_t link_rates[DP_MAX_LINK_RATE_COUNT];
> + uint64_t required_bandwidth, available_bandwidth;
> +
> + igt_require_f(mode.vdisplay > 0, "No modes found\n");
> + igt_require_f(output, "Output cannot be null\n");
> +
> + required_bandwidth = (uint64_t)(mode.clock * BITS_PER_PIXEL);
> + read_link_rates(drm_fd, link_rates, &num_rates, output);
> +
> + for (lanes = 4; lanes > 0 ; lanes = lanes/2) {
> + for (i = num_rates-1; i > 0; i--) {
> + overhead = link_rates[i] >= DP_LINK_RATE_1000000 ?
> + ENCODING_OVERHEAD_128b_132b :
> + ENCODING_OVERHEAD_8b_10b;
> + available_bandwidth = link_rates[i] * lanes * overhead * 10;
> + if (available_bandwidth < required_bandwidth) {
> + igt_info("Lowest link configuration for %s: Link Rate = %"PRIu64" Kbps, Lanes = %d\n", output->name, link_rates[i], lanes);
> + *min_link_rate = link_rates[i];
> + *min_lane_count = lanes;
> + return;
> + }
> + }
> + }
> +}
> +
> +static const char *str_lane_count(enum dp_lane_count lane_count)
> +{
> + switch (lane_count) {
> + case DP_LANE_COUNT_1:
> + return "1";
> + case DP_LANE_COUNT_2:
> + return "2";
> + case DP_LANE_COUNT_4:
> + return "4";
> + default:
> + igt_assert_f(0, "Invalid lane count %d\n", lane_count);
> + }
> +}
> +
> +static bool is_retrain_disabled(data_t *data)
> +{
> + struct dp_link_training_info info;
> +
> + igt_read_link_training_info(data->drm_fd, data->output, &info);
> + return info.retrain_disabled;
> +}
> +
> +static void test_fallback(data_t *data)
> +{
> + bool first = true;
> + uint64_t min_link_rate;
> + int min_lane_count;
> +
> + igt_sort_connector_modes(data->output->config.connector, sort_drm_modes_by_res_asc);
> + find_min_dp_config(data->drm_fd, data->output->config.connector->modes[0], data->output,
> + &min_link_rate, &min_lane_count);
> +
> + while (!is_retrain_disabled(data)) {
> + data->mode = &data->output->config.connector->modes[0];
> + igt_info("mode: %dx%d@%d\n", data->mode->hdisplay, data->mode->vdisplay, data->mode->vrefresh);
> + igt_create_pattern_fb(data->drm_fd, data->mode->hdisplay, data->mode->vdisplay, DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR, &data->fb);
> + igt_output_set_pipe(data->output, data->pipe);
> + data->primary = igt_output_get_plane_type(data->output, DRM_PLANE_TYPE_PRIMARY);
> + igt_plane_set_fb(data->primary, &data->fb);
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> +
> + igt_info("Current link rate : %s, lane count : %s\n",
> + str_link_rate(igt_get_dp_link_rate_set_for_output(data->drm_fd, data->output)),
> + str_lane_count(igt_get_dp_lane_count_set_for_output(data->drm_fd, data->output)));
> + if ((igt_get_dp_link_rate_set_for_output(data->drm_fd, data->output) == min_link_rate) &&
> + (igt_get_dp_lane_count_set_for_output(data->drm_fd, data->output) == min_lane_count))
> + break;
> + kmstest_force_connector_link_training_failure(data->drm_fd, data->output->config.connector, 2);
> + kmstest_force_connector_retrain(data->drm_fd, data->output->config.connector, 1);
> +
> + if (!first) {
> + igt_display_reset(&data->display);
> + igt_display_commit2(&data->display, COMMIT_ATOMIC);
> + }
> + first = false;
> + }
> +}
> +
> +igt_main
> +{
> + data_t data = {};
> + igt_output_t *output;
> + enum pipe pipe;
> + enum dp_link_rate link_rate;
> + enum dp_lane_count lane_count;
> +
> + igt_fixture {
> + data.drm_fd = drm_open_driver_master(DRIVER_INTEL);
> + kmstest_set_vt_graphics_mode();
> + igt_display_require(&data.display, data.drm_fd);
> + }
> +
> + igt_describe_f("Test fallback");
> + igt_subtest_with_dynamic_f("fallback")
> + {
> + for_each_connected_output(&data.display, output) {
> + if (!igt_has_force_link_training_failure_debugfs(data.drm_fd, output)) {
> + igt_info("Skipping output %s as doesn't support fallback\n",
> + output->name);
> + continue;
> + }
> +
> + data.output = output;
> + link_rate = igt_get_dp_max_link_rate(data.drm_fd, data.output);
> + lane_count = igt_get_dp_max_lane_count(data.drm_fd, data.output);
> +
> + for_each_pipe(&data.display, pipe) {
> + igt_display_reset(&data.display);
> + data.pipe = pipe;
> + igt_dynamic_f("%s-pipe-%s", igt_output_name(output), kmstest_pipe_name(pipe))
> + test_fallback(&data);
> + kmstest_force_connector_link_rate(data.drm_fd, data.output->config.connector, link_rate);
> + kmstest_force_connector_lane_count(data.drm_fd, data.output->config.connector, lane_count);
> + igt_reset_connectors();
> + }
> + }
> + }
> +
> + igt_fixture {
> + igt_reset_connectors();
> + igt_display_fini(&data.display);
> + drm_close_driver(data.drm_fd);
> + }
> +}
> diff --git a/tests/meson.build b/tests/meson.build
> index 758ae090c..1a4e6c18b 100644
> --- a/tests/meson.build
> +++ b/tests/meson.build
> @@ -251,6 +251,7 @@ intel_kms_progs = [
> 'kms_ccs',
> 'kms_cdclk',
> 'kms_dirtyfb',
> + 'kms_dp_fallback',
> 'kms_draw_crc',
> 'kms_dsc',
> 'kms_fb_coherency',
More information about the igt-dev
mailing list