@@ -90,4 +90,17 @@ config AMD_DC_BASICS_KUNIT_TEST
If unsure, say N.
+config AMD_DC_KUNIT_TEST
+ bool "Enable KUnit tests for the 'utils' sub-component of DAL" if !KUNIT_ALL_TESTS
+ depends on DRM_AMD_DC && KUNIT
+ default KUNIT_ALL_TESTS
+ help
+ Enables unit tests for the basics folder of Display Core. Only useful for
+ kernel devs running KUnit.
+
+ For more information on KUnit and unit tests in general please refer to
+ the KUnit documentation in Documentation/dev-tools/kunit/.
+
+ If unsure, say N.
+
endmenu
@@ -1415,3 +1415,7 @@ bool dc_wake_and_execute_gpint(const struct dc_context *ctx, enum dmub_gpint_com
return result;
}
+
+#if IS_ENABLED(CONFIG_AMD_DC_KUNIT_TEST)
+#include "../tests/dc/dc_dmub_srv_test.c"
+#endif
new file mode 100644
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dc_dmub_srv.c
+ *
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dc_dmub_srv.h"
+
+/**
+ * DOC: overview
+ *
+ * The file dc_dumb_srv.c has many functions that work as an interface to
+ * generate some of the DMUB parameters. To offload some of the complexity from
+ * the DMUB, the 'dc_dmub_srv.c' file provides functions that perform
+ * mathematical calculations to generate the parameter that will be passed to
+ * the DMUB to enable specific configurations.
+ */
+
+/**
+ * struct populate_subvp_cmd_drr_info_test_case - Fields for subvp validation
+ *
+ * The function populate_subvp_cmd_drr_info() performs calculations based on
+ * different pipe context timing values. This struct maintains those fields
+ * required to be passed to the populate_subvp_cmd_drr_info.
+ */
+struct populate_subvp_cmd_drr_info_test_case {
+ const char *desc;
+ /**
+ * @dc: In the specific context of populate_subvp_cmd_drr_info() test,
+ * we only care about the DC capabilities.
+ */
+ struct dc *dc;
+
+ /**
+ * @subvp_pipe: This parameter plays an essential role in the
+ * populate_subvp_cmd_drr_info validation because it will be used to
+ * derive some of the parameters for the max VTotal, but it is also
+ * employed in a pointer validation that extracts the phantom timing
+ * from the context.
+ */
+ struct pipe_ctx *subvp_pipe;
+
+ /**
+ * @vblank_pipe: This field keeps the DRR timing values used in the Max
+ * and Min VTotal calculation.
+ */
+ struct pipe_ctx *vblank_pipe;
+
+ /**
+ * @context: In the context of populate_subvp_cmd_drr_info(), this
+ * field it is only necessary to fulfill the requirements for
+ * dc_state_get_paired_subvp_stream() helper.
+ */
+ struct dc_state *context;
+};
+
+const struct dc_stream_status mock_dc_stream_state_returned_from_get_paired = {
+ .mall_stream_config = (struct mall_stream_config) {
+ .paired_stream = &(struct dc_stream_state) {
+ .timing = {
+ .v_total = 216,
+ .h_total = 4000,
+ .v_addressable = 149,
+ .pix_clk_100hz = 5332500,
+ .v_front_porch = 1,
+ },
+ }
+ }
+};
+
+struct pipe_ctx mock_vblank_pipe_parameter = {
+ .stream = &(struct dc_stream_state) {
+ .timing = {
+ .v_total = 2250,
+ .h_total = 4400,
+ .v_addressable = 2160,
+ .pix_clk_100hz = 23760000,
+ },
+ },
+};
+
+const struct pipe_ctx mock_subvp_pipe_parameter = {
+ .stream = &(struct dc_stream_state) {
+ .timing = {
+ .h_total = 4000,
+ .v_addressable = 2160,
+ .pix_clk_100hz = 5332500,
+ },
+ },
+};
+
+struct populate_subvp_cmd_drr_info_test_case subvp_4k144_4k240_case = {
+ .desc = "4k144 and 4k240 displays are the perfect scenario for SubVP",
+ .dc = &(struct dc) {
+ .caps = {
+ .subvp_prefetch_end_to_mall_start_us = 15,
+ .subvp_fw_processing_delay_us = 15,
+ }
+ },
+
+ .subvp_pipe = (struct pipe_ctx *) &mock_subvp_pipe_parameter,
+ .vblank_pipe = &mock_vblank_pipe_parameter,
+ .context = &(struct dc_state) {
+ .stream_count = 1,
+ .streams[0] = mock_subvp_pipe_parameter.stream,
+ .stream_status[0] = mock_dc_stream_state_returned_from_get_paired,
+ },
+};
+
+/**
+ * populate_subvp_cmd_drr_info_with_4k144_4k240_parameters - Check two display with 4k144 and 4k240
+ *
+ * @test: Kunit parameter
+ *
+ * One of the scenarios where SubVP can perform really well is in a
+ * high-resolution display with a high refresh rate. In this sense, this test
+ * targets the parameter configuration for 4k144 and 4k240.
+ */
+static void populate_subvp_cmd_drr_info_with_4k144_4k240_parameters(struct kunit *test)
+{
+ struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data;
+ struct populate_subvp_cmd_drr_info_test_case tmp = subvp_4k144_4k240_case;
+
+ pipe_data = kunit_kzalloc(test,
+ sizeof(struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2),
+ GFP_KERNEL);
+
+ populate_subvp_cmd_drr_info(tmp.dc,
+ tmp.context,
+ tmp.subvp_pipe,
+ tmp.vblank_pipe,
+ pipe_data);
+
+ // DRR must be in use
+ KUNIT_EXPECT_EQ(test, true, pipe_data->pipe_config.vblank_data.drr_info.drr_in_use);
+
+ // Use ramp should not be enable
+ KUNIT_EXPECT_EQ(test, false, pipe_data->pipe_config.vblank_data.drr_info.use_ramping);
+
+ // Expects 4ms for the DRR window size
+ KUNIT_EXPECT_EQ(test, 4, pipe_data->pipe_config.vblank_data.drr_info.drr_window_size_ms);
+
+ KUNIT_EXPECT_EQ(test, 2906, pipe_data->pipe_config.vblank_data.drr_info.min_vtotal_supported);
+ KUNIT_EXPECT_EQ(test, 7267, pipe_data->pipe_config.vblank_data.drr_info.max_vtotal_supported);
+}
+
+static struct kunit_case dc_dmub_srv_cases[] = {
+ KUNIT_CASE(populate_subvp_cmd_drr_info_with_4k144_4k240_parameters),
+ { }
+};
+
+static struct kunit_suite dc_dmub_srv_suite = {
+ .name = "dc_dmub_srv",
+ .test_cases = dc_dmub_srv_cases,
+};
+
+kunit_test_suite(dc_dmub_srv_suite);