All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] drm/amd/display: Introduce KUnit to Display Mode Library
@ 2022-08-31 17:22 ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

Hello,

This series is version 2 of the introduction of unit testing to the
AMDPGU driver [1].

Our main goal is to bring unit testing to the AMD display driver; in
particular, we'll focus on the Display Mode Library (DML) for DCN2.0,
DMUB, and some of the DCE functions. This implementation intends to
help developers to recognize bugs before they are merged into the
mainline and also makes it possible for future code refactors of the
AMD display driver.

For the implementation of the tests, we decided to go with the Kernel
Unit Testing Framework (KUnit). KUnit makes it possible to run test
suites on kernel boot or load the tests as a module. It reports all test
case results through a TAP (Test Anything Protocol) in the kernel log.
Moreover, KUnit unifies the test structure and provides tools to
simplify the testing for developers and CI systems.

In regards to CI pipelines, we believe kunit_tool [2] provides
ease of use, but we are also working on integrating KUnit into IGT.

In this second version, we've chosen a mix of approaches to integrate
KUnit tests into amdgpu:
    1. Tests that use static functions are included through guards [3].
    2. Tests without static functions are included through a Makefile.

We understand that testing static functions is not ideal, but taking into
consideration that this driver relies heavily on static functions with
complex behavior which would benefit from unit testing, otherwise, black-box
tested through public functions with dozens of arguments and sometimes high
cyclomatic complexity.

The first seven patches represent what we intend to do for the rest of the
DML modules: systematic testing of the DML functions, especially mathematically
complicated functions. Also, it shows how simple it is to add new tests to the DML.

Among the tests, we highlight the dcn20_fpu_test, which, had it existed
then, could catch the defects introduced to dcn20_fpu.c by 8861c27a6c [4]
later fixed by 9ad5d02c2a [5].

In this series, there's also an example of how unit tests can help avoid
regressions and keep track of changes in behavior.

Applying this series on top of the amd-staging-drm-next (787df47adb1f)
and running its tests will fail the `dc_dmub_srv` test, you can verify
that with:

$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
                --kunitconfig=drivers/gpu/drm/amd/display/tests

```
...
[17:37:28] # Subtest: populate_subvp_cmd_drr_info_test
[17:37:28] # populate_subvp_cmd_drr_info_test: pass:0 fail:5 skip:0 total:5
[17:37:28] not ok 1 - populate_subvp_cmd_drr_info_test
[17:37:28] ======== [FAILED] populate_subvp_cmd_drr_info_test =========
[17:37:28] # Subtest: dc_dmub_srv
[17:37:28] 1..1
[17:37:28] # Totals: pass:0 fail:5 skip:0 total:5
[17:37:28] not ok 4 - dc_dmub_srv
[17:37:28] =================== [FAILED] dc_dmub_srv ===================
[17:37:28] ============================================================
[17:37:28] Testing complete. Passed: 88, Failed: 5, Crashed: 0, Skipped: 0, Errors: 0
```
Full output at: https://pastebin.com/PfmbXAJ9

This is due to a known regression introduced by commit 5da7f4134357
("drm/amd/display: fix 32 bit compilation errors in dc_dmub_srv.c")
[6], which resulted in the struct's members being zero. As an
exercise, you can revert the offending patch, run the tests again, and
the test-series will result in success.

```
[17:41:44] Testing complete. Passed: 93, Failed: 0, Crashed: 0, Skipped: 0, Errors: 0
```
Full successful output: https://pastebin.com/Nn2rRRkd

This series depends on a couple of KUnit patches already merged into
torvalds/master, which themselves depend on older patches:

commit 61695f8c5d51 ("kunit: split resource API from test.h into new resource.h")
commit 2852ca7fba9f ("panic: Taint kernel if tests are run")
commit cfc1d277891e ("module: Move all into module/")
commit cdebea6968fa ("kunit: split resource API impl from test.c into new resource.c")
commit cae56e1740f5 ("kunit: rename print_subtest_{start,end} for clarity (s/subtest/suite)")
commit 1cdba21db2ca ("kunit: add ability to specify suite-level init and exit functions")
commit c272612cb4a2 ("kunit: Taint the kernel when KUnit tests are run")
commit 3d6e44623841 ("kunit: unify module and builtin suite definitions")
commit a02353f49162 ("kunit: bail out of test filtering logic quicker if OOM")
commit 1b11063d32d7 ("kunit: fix executor OOM error handling logic on non-UML")
commit e5857d396f35 ("kunit: flatten kunit_suite*** to kunit_suite** in .kunit_test_suites")
commit 94681e289bf5 ("kunit: executor: Fix a memory leak on failure in kunit_filter_tests")

Thanks in advance for your time taking a look and sending any feedback!

Best regards,
Isabella Basso, Magali Lemes, Maíra Canal, and Tales Aparecida`

[1] https://summerofcode.withgoogle.com/programs/2022/organizations/xorg-foundation
[2] https://www.kernel.org/doc/html/latest/dev-tools/kunit/kunit-tool.html
[3] https://docs.kernel.org/dev-tools/kunit/usage.html#testing-static-functions
[4] https://lore.kernel.org/amd-gfx/20220603185042.3408844-6-Rodrigo.Siqueira@amd.com/
[5] https://lore.kernel.org/amd-gfx/20220608164856.1870594-1-sunpeng.li@amd.com/
[6] https://lore.kernel.org/amd-gfx/20220708052650.1029150-1-alexander.deucher@amd.com/

---
v1 -> v2: https://lore.kernel.org/amd-gfx/20220811004010.61299-1-tales.aparecida@gmail.com/

- Add comments to display_mode_vba_20_test and display_rq_dlg_calc_20_test (Maíra Canal).
- Fix checkpatch warnings (Maíra Canal).
- Add three more tests to display_mode_vba_20 (Maíra Canal).
- Create three Kconfig entries for the tests (Tales Aparecida).
- Add a "depends on" in the Kconfig to assure no broken configs with UML (David Gow).
- Create a Makefile for tests that don´t hold static function testing (Tales Aparecida).
- Update the documentation with new Kconfig entries and more details on how to add new tests.
- Add David's Reviewed-by.
---

Isabella Basso (1):
  drm/amd/display: Introduce KUnit tests to display_rq_dlg_calc_20

Magali Lemes (1):
  drm/amd/display: Introduce KUnit tests for dcn20_fpu

Maíra Canal (5):
  drm/amd/display: Introduce KUnit tests to the bw_fixed library
  drm/amd/display: Introduce KUnit tests to the display_mode_vba library
  drm/amd/display: Introduce KUnit to dcn20/display_mode_vba_20 library
  drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
  Documentation/gpu: Add Display Core Unit Test documentation

Tales Aparecida (1):
  drm/amd/display: Introduce KUnit tests for fixed31_32 library

 .../gpu/amdgpu/display/display-test.rst       |  88 ++
 Documentation/gpu/amdgpu/display/index.rst    |   1 +
 drivers/gpu/drm/amd/display/Kconfig           |  51 +
 drivers/gpu/drm/amd/display/Makefile          |   2 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   4 +
 .../drm/amd/display/dc/dml/calcs/bw_fixed.c   |   3 +
 .../dc/dml/dcn20/display_mode_vba_20.c        |   4 +
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c     |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   9 +
 drivers/gpu/drm/amd/display/tests/Makefile    |  18 +
 .../display/tests/dc/basics/fixpt31_32_test.c | 232 +++++
 .../amd/display/tests/dc/dc_dmub_srv_test.c   | 285 ++++++
 .../tests/dc/dml/calcs/bw_fixed_test.c        | 323 +++++++
 .../tests/dc/dml/dcn20/dcn20_fpu_test.c       | 561 +++++++++++
 .../dc/dml/dcn20/display_mode_vba_20_test.c   | 888 ++++++++++++++++++
 .../dml/dcn20/display_rq_dlg_calc_20_test.c   | 124 +++
 .../tests/dc/dml/display_mode_vba_test.c      | 741 +++++++++++++++
 17 files changed, 3337 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/gpu/amdgpu/display/display-test.rst
 create mode 100644 drivers/gpu/drm/amd/display/tests/.kunitconfig
 create mode 100644 drivers/gpu/drm/amd/display/tests/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c

-- 
2.37.2


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 0/8] drm/amd/display: Introduce KUnit to Display Mode Library
@ 2022-08-31 17:22 ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

Hello,

This series is version 2 of the introduction of unit testing to the
AMDPGU driver [1].

Our main goal is to bring unit testing to the AMD display driver; in
particular, we'll focus on the Display Mode Library (DML) for DCN2.0,
DMUB, and some of the DCE functions. This implementation intends to
help developers to recognize bugs before they are merged into the
mainline and also makes it possible for future code refactors of the
AMD display driver.

For the implementation of the tests, we decided to go with the Kernel
Unit Testing Framework (KUnit). KUnit makes it possible to run test
suites on kernel boot or load the tests as a module. It reports all test
case results through a TAP (Test Anything Protocol) in the kernel log.
Moreover, KUnit unifies the test structure and provides tools to
simplify the testing for developers and CI systems.

In regards to CI pipelines, we believe kunit_tool [2] provides
ease of use, but we are also working on integrating KUnit into IGT.

In this second version, we've chosen a mix of approaches to integrate
KUnit tests into amdgpu:
    1. Tests that use static functions are included through guards [3].
    2. Tests without static functions are included through a Makefile.

We understand that testing static functions is not ideal, but taking into
consideration that this driver relies heavily on static functions with
complex behavior which would benefit from unit testing, otherwise, black-box
tested through public functions with dozens of arguments and sometimes high
cyclomatic complexity.

The first seven patches represent what we intend to do for the rest of the
DML modules: systematic testing of the DML functions, especially mathematically
complicated functions. Also, it shows how simple it is to add new tests to the DML.

Among the tests, we highlight the dcn20_fpu_test, which, had it existed
then, could catch the defects introduced to dcn20_fpu.c by 8861c27a6c [4]
later fixed by 9ad5d02c2a [5].

In this series, there's also an example of how unit tests can help avoid
regressions and keep track of changes in behavior.

Applying this series on top of the amd-staging-drm-next (787df47adb1f)
and running its tests will fail the `dc_dmub_srv` test, you can verify
that with:

$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
                --kunitconfig=drivers/gpu/drm/amd/display/tests

```
...
[17:37:28] # Subtest: populate_subvp_cmd_drr_info_test
[17:37:28] # populate_subvp_cmd_drr_info_test: pass:0 fail:5 skip:0 total:5
[17:37:28] not ok 1 - populate_subvp_cmd_drr_info_test
[17:37:28] ======== [FAILED] populate_subvp_cmd_drr_info_test =========
[17:37:28] # Subtest: dc_dmub_srv
[17:37:28] 1..1
[17:37:28] # Totals: pass:0 fail:5 skip:0 total:5
[17:37:28] not ok 4 - dc_dmub_srv
[17:37:28] =================== [FAILED] dc_dmub_srv ===================
[17:37:28] ============================================================
[17:37:28] Testing complete. Passed: 88, Failed: 5, Crashed: 0, Skipped: 0, Errors: 0
```
Full output at: https://pastebin.com/PfmbXAJ9

This is due to a known regression introduced by commit 5da7f4134357
("drm/amd/display: fix 32 bit compilation errors in dc_dmub_srv.c")
[6], which resulted in the struct's members being zero. As an
exercise, you can revert the offending patch, run the tests again, and
the test-series will result in success.

```
[17:41:44] Testing complete. Passed: 93, Failed: 0, Crashed: 0, Skipped: 0, Errors: 0
```
Full successful output: https://pastebin.com/Nn2rRRkd

This series depends on a couple of KUnit patches already merged into
torvalds/master, which themselves depend on older patches:

commit 61695f8c5d51 ("kunit: split resource API from test.h into new resource.h")
commit 2852ca7fba9f ("panic: Taint kernel if tests are run")
commit cfc1d277891e ("module: Move all into module/")
commit cdebea6968fa ("kunit: split resource API impl from test.c into new resource.c")
commit cae56e1740f5 ("kunit: rename print_subtest_{start,end} for clarity (s/subtest/suite)")
commit 1cdba21db2ca ("kunit: add ability to specify suite-level init and exit functions")
commit c272612cb4a2 ("kunit: Taint the kernel when KUnit tests are run")
commit 3d6e44623841 ("kunit: unify module and builtin suite definitions")
commit a02353f49162 ("kunit: bail out of test filtering logic quicker if OOM")
commit 1b11063d32d7 ("kunit: fix executor OOM error handling logic on non-UML")
commit e5857d396f35 ("kunit: flatten kunit_suite*** to kunit_suite** in .kunit_test_suites")
commit 94681e289bf5 ("kunit: executor: Fix a memory leak on failure in kunit_filter_tests")

Thanks in advance for your time taking a look and sending any feedback!

Best regards,
Isabella Basso, Magali Lemes, Maíra Canal, and Tales Aparecida`

[1] https://summerofcode.withgoogle.com/programs/2022/organizations/xorg-foundation
[2] https://www.kernel.org/doc/html/latest/dev-tools/kunit/kunit-tool.html
[3] https://docs.kernel.org/dev-tools/kunit/usage.html#testing-static-functions
[4] https://lore.kernel.org/amd-gfx/20220603185042.3408844-6-Rodrigo.Siqueira@amd.com/
[5] https://lore.kernel.org/amd-gfx/20220608164856.1870594-1-sunpeng.li@amd.com/
[6] https://lore.kernel.org/amd-gfx/20220708052650.1029150-1-alexander.deucher@amd.com/

---
v1 -> v2: https://lore.kernel.org/amd-gfx/20220811004010.61299-1-tales.aparecida@gmail.com/

- Add comments to display_mode_vba_20_test and display_rq_dlg_calc_20_test (Maíra Canal).
- Fix checkpatch warnings (Maíra Canal).
- Add three more tests to display_mode_vba_20 (Maíra Canal).
- Create three Kconfig entries for the tests (Tales Aparecida).
- Add a "depends on" in the Kconfig to assure no broken configs with UML (David Gow).
- Create a Makefile for tests that don´t hold static function testing (Tales Aparecida).
- Update the documentation with new Kconfig entries and more details on how to add new tests.
- Add David's Reviewed-by.
---

Isabella Basso (1):
  drm/amd/display: Introduce KUnit tests to display_rq_dlg_calc_20

Magali Lemes (1):
  drm/amd/display: Introduce KUnit tests for dcn20_fpu

Maíra Canal (5):
  drm/amd/display: Introduce KUnit tests to the bw_fixed library
  drm/amd/display: Introduce KUnit tests to the display_mode_vba library
  drm/amd/display: Introduce KUnit to dcn20/display_mode_vba_20 library
  drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
  Documentation/gpu: Add Display Core Unit Test documentation

Tales Aparecida (1):
  drm/amd/display: Introduce KUnit tests for fixed31_32 library

 .../gpu/amdgpu/display/display-test.rst       |  88 ++
 Documentation/gpu/amdgpu/display/index.rst    |   1 +
 drivers/gpu/drm/amd/display/Kconfig           |  51 +
 drivers/gpu/drm/amd/display/Makefile          |   2 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   4 +
 .../drm/amd/display/dc/dml/calcs/bw_fixed.c   |   3 +
 .../dc/dml/dcn20/display_mode_vba_20.c        |   4 +
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c     |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   9 +
 drivers/gpu/drm/amd/display/tests/Makefile    |  18 +
 .../display/tests/dc/basics/fixpt31_32_test.c | 232 +++++
 .../amd/display/tests/dc/dc_dmub_srv_test.c   | 285 ++++++
 .../tests/dc/dml/calcs/bw_fixed_test.c        | 323 +++++++
 .../tests/dc/dml/dcn20/dcn20_fpu_test.c       | 561 +++++++++++
 .../dc/dml/dcn20/display_mode_vba_20_test.c   | 888 ++++++++++++++++++
 .../dml/dcn20/display_rq_dlg_calc_20_test.c   | 124 +++
 .../tests/dc/dml/display_mode_vba_test.c      | 741 +++++++++++++++
 17 files changed, 3337 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/gpu/amdgpu/display/display-test.rst
 create mode 100644 drivers/gpu/drm/amd/display/tests/.kunitconfig
 create mode 100644 drivers/gpu/drm/amd/display/tests/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c

-- 
2.37.2


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 0/8] drm/amd/display: Introduce KUnit to Display Mode Library
@ 2022-08-31 17:22 ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

Hello,

This series is version 2 of the introduction of unit testing to the
AMDPGU driver [1].

Our main goal is to bring unit testing to the AMD display driver; in
particular, we'll focus on the Display Mode Library (DML) for DCN2.0,
DMUB, and some of the DCE functions. This implementation intends to
help developers to recognize bugs before they are merged into the
mainline and also makes it possible for future code refactors of the
AMD display driver.

For the implementation of the tests, we decided to go with the Kernel
Unit Testing Framework (KUnit). KUnit makes it possible to run test
suites on kernel boot or load the tests as a module. It reports all test
case results through a TAP (Test Anything Protocol) in the kernel log.
Moreover, KUnit unifies the test structure and provides tools to
simplify the testing for developers and CI systems.

In regards to CI pipelines, we believe kunit_tool [2] provides
ease of use, but we are also working on integrating KUnit into IGT.

In this second version, we've chosen a mix of approaches to integrate
KUnit tests into amdgpu:
    1. Tests that use static functions are included through guards [3].
    2. Tests without static functions are included through a Makefile.

We understand that testing static functions is not ideal, but taking into
consideration that this driver relies heavily on static functions with
complex behavior which would benefit from unit testing, otherwise, black-box
tested through public functions with dozens of arguments and sometimes high
cyclomatic complexity.

The first seven patches represent what we intend to do for the rest of the
DML modules: systematic testing of the DML functions, especially mathematically
complicated functions. Also, it shows how simple it is to add new tests to the DML.

Among the tests, we highlight the dcn20_fpu_test, which, had it existed
then, could catch the defects introduced to dcn20_fpu.c by 8861c27a6c [4]
later fixed by 9ad5d02c2a [5].

In this series, there's also an example of how unit tests can help avoid
regressions and keep track of changes in behavior.

Applying this series on top of the amd-staging-drm-next (787df47adb1f)
and running its tests will fail the `dc_dmub_srv` test, you can verify
that with:

$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
                --kunitconfig=drivers/gpu/drm/amd/display/tests

```
...
[17:37:28] # Subtest: populate_subvp_cmd_drr_info_test
[17:37:28] # populate_subvp_cmd_drr_info_test: pass:0 fail:5 skip:0 total:5
[17:37:28] not ok 1 - populate_subvp_cmd_drr_info_test
[17:37:28] ======== [FAILED] populate_subvp_cmd_drr_info_test =========
[17:37:28] # Subtest: dc_dmub_srv
[17:37:28] 1..1
[17:37:28] # Totals: pass:0 fail:5 skip:0 total:5
[17:37:28] not ok 4 - dc_dmub_srv
[17:37:28] =================== [FAILED] dc_dmub_srv ===================
[17:37:28] ============================================================
[17:37:28] Testing complete. Passed: 88, Failed: 5, Crashed: 0, Skipped: 0, Errors: 0
```
Full output at: https://pastebin.com/PfmbXAJ9

This is due to a known regression introduced by commit 5da7f4134357
("drm/amd/display: fix 32 bit compilation errors in dc_dmub_srv.c")
[6], which resulted in the struct's members being zero. As an
exercise, you can revert the offending patch, run the tests again, and
the test-series will result in success.

```
[17:41:44] Testing complete. Passed: 93, Failed: 0, Crashed: 0, Skipped: 0, Errors: 0
```
Full successful output: https://pastebin.com/Nn2rRRkd

This series depends on a couple of KUnit patches already merged into
torvalds/master, which themselves depend on older patches:

commit 61695f8c5d51 ("kunit: split resource API from test.h into new resource.h")
commit 2852ca7fba9f ("panic: Taint kernel if tests are run")
commit cfc1d277891e ("module: Move all into module/")
commit cdebea6968fa ("kunit: split resource API impl from test.c into new resource.c")
commit cae56e1740f5 ("kunit: rename print_subtest_{start,end} for clarity (s/subtest/suite)")
commit 1cdba21db2ca ("kunit: add ability to specify suite-level init and exit functions")
commit c272612cb4a2 ("kunit: Taint the kernel when KUnit tests are run")
commit 3d6e44623841 ("kunit: unify module and builtin suite definitions")
commit a02353f49162 ("kunit: bail out of test filtering logic quicker if OOM")
commit 1b11063d32d7 ("kunit: fix executor OOM error handling logic on non-UML")
commit e5857d396f35 ("kunit: flatten kunit_suite*** to kunit_suite** in .kunit_test_suites")
commit 94681e289bf5 ("kunit: executor: Fix a memory leak on failure in kunit_filter_tests")

Thanks in advance for your time taking a look and sending any feedback!

Best regards,
Isabella Basso, Magali Lemes, Maíra Canal, and Tales Aparecida`

[1] https://summerofcode.withgoogle.com/programs/2022/organizations/xorg-foundation
[2] https://www.kernel.org/doc/html/latest/dev-tools/kunit/kunit-tool.html
[3] https://docs.kernel.org/dev-tools/kunit/usage.html#testing-static-functions
[4] https://lore.kernel.org/amd-gfx/20220603185042.3408844-6-Rodrigo.Siqueira@amd.com/
[5] https://lore.kernel.org/amd-gfx/20220608164856.1870594-1-sunpeng.li@amd.com/
[6] https://lore.kernel.org/amd-gfx/20220708052650.1029150-1-alexander.deucher@amd.com/

---
v1 -> v2: https://lore.kernel.org/amd-gfx/20220811004010.61299-1-tales.aparecida@gmail.com/

- Add comments to display_mode_vba_20_test and display_rq_dlg_calc_20_test (Maíra Canal).
- Fix checkpatch warnings (Maíra Canal).
- Add three more tests to display_mode_vba_20 (Maíra Canal).
- Create three Kconfig entries for the tests (Tales Aparecida).
- Add a "depends on" in the Kconfig to assure no broken configs with UML (David Gow).
- Create a Makefile for tests that don´t hold static function testing (Tales Aparecida).
- Update the documentation with new Kconfig entries and more details on how to add new tests.
- Add David's Reviewed-by.
---

Isabella Basso (1):
  drm/amd/display: Introduce KUnit tests to display_rq_dlg_calc_20

Magali Lemes (1):
  drm/amd/display: Introduce KUnit tests for dcn20_fpu

Maíra Canal (5):
  drm/amd/display: Introduce KUnit tests to the bw_fixed library
  drm/amd/display: Introduce KUnit tests to the display_mode_vba library
  drm/amd/display: Introduce KUnit to dcn20/display_mode_vba_20 library
  drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
  Documentation/gpu: Add Display Core Unit Test documentation

Tales Aparecida (1):
  drm/amd/display: Introduce KUnit tests for fixed31_32 library

 .../gpu/amdgpu/display/display-test.rst       |  88 ++
 Documentation/gpu/amdgpu/display/index.rst    |   1 +
 drivers/gpu/drm/amd/display/Kconfig           |  51 +
 drivers/gpu/drm/amd/display/Makefile          |   2 +-
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   4 +
 .../drm/amd/display/dc/dml/calcs/bw_fixed.c   |   3 +
 .../dc/dml/dcn20/display_mode_vba_20.c        |   4 +
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c     |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   9 +
 drivers/gpu/drm/amd/display/tests/Makefile    |  18 +
 .../display/tests/dc/basics/fixpt31_32_test.c | 232 +++++
 .../amd/display/tests/dc/dc_dmub_srv_test.c   | 285 ++++++
 .../tests/dc/dml/calcs/bw_fixed_test.c        | 323 +++++++
 .../tests/dc/dml/dcn20/dcn20_fpu_test.c       | 561 +++++++++++
 .../dc/dml/dcn20/display_mode_vba_20_test.c   | 888 ++++++++++++++++++
 .../dml/dcn20/display_rq_dlg_calc_20_test.c   | 124 +++
 .../tests/dc/dml/display_mode_vba_test.c      | 741 +++++++++++++++
 17 files changed, 3337 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/gpu/amdgpu/display/display-test.rst
 create mode 100644 drivers/gpu/drm/amd/display/tests/.kunitconfig
 create mode 100644 drivers/gpu/drm/amd/display/tests/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c

-- 
2.37.2


^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH v2 1/8] drm/amd/display: Introduce KUnit tests for fixed31_32 library
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

From: Tales Aparecida <tales.aparecida@gmail.com>

The fixed31_32 library performs a lot of the mathematical operations
involving fixed-point arithmetic and the conversion of integers to
fixed-point representation.

This unit tests intend to assure the proper functioning of the basic
mathematical operations of fixed-point arithmetic, such as
multiplication, conversion from fractional to fixed-point number,
and more. Use kunit_tool to run:

$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
	--kunitconfig=drivers/gpu/drm/amd/display/tests/

Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 +
 drivers/gpu/drm/amd/display/Makefile          |   2 +-
 .../gpu/drm/amd/display/tests/.kunitconfig    |   6 +
 drivers/gpu/drm/amd/display/tests/Makefile    |  12 +
 .../display/tests/dc/basics/fixpt31_32_test.c | 232 ++++++++++++++++++
 5 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/.kunitconfig
 create mode 100644 drivers/gpu/drm/amd/display/tests/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 96cbc87f7b6b..cc44cfe88607 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -55,4 +55,17 @@ config DRM_AMD_SECURE_DISPLAY
             Cooperate with specific DMCU FW.
 
 
+config AMD_DC_BASICS_KUNIT_TEST
+	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the 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
diff --git a/drivers/gpu/drm/amd/display/Makefile b/drivers/gpu/drm/amd/display/Makefile
index 2633de77de5e..0f329aab13f0 100644
--- a/drivers/gpu/drm/amd/display/Makefile
+++ b/drivers/gpu/drm/amd/display/Makefile
@@ -43,7 +43,7 @@ endif
 #TODO: remove when Timing Sync feature is complete
 subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
 
-DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet modules/power dmub/src
+DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet modules/power dmub/src tests
 
 ifdef CONFIG_DRM_AMD_DC_HDCP
 DAL_LIBS += modules/hdcp
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
new file mode 100644
index 000000000000..60f2ff8158f5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -0,0 +1,6 @@
+CONFIG_KUNIT=y
+CONFIG_PCI=y
+CONFIG_DRM=y
+CONFIG_DRM_AMDGPU=y
+CONFIG_DRM_AMD_DC=y
+CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
\ No newline at end of file
diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
new file mode 100644
index 000000000000..ef16497318e8
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: MIT
+#
+# Makefile for the KUnit Tests for DC
+#
+
+ifdef CONFIG_AMD_DC_BASICS_KUNIT_TEST
+	DC_TESTS += dc/basics/fixpt31_32_test.o
+endif
+
+AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DC_TESTS)
diff --git a/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c b/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
new file mode 100644
index 000000000000..2fc489203499
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: MIT
+/* Unit tests for display/include/fixed31_32.h and dc/basics/fixpt31_32.c
+ *
+ * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
+ */
+
+#include <kunit/test.h>
+#include "os_types.h"
+#include "fixed31_32.h"
+
+static const struct fixed31_32 dc_fixpt_minus_one = { -0x100000000LL };
+
+/**
+ * dc_fixpt_from_int_test - KUnit test for dc_fixpt_from_int
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_from_int_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+
+	res = dc_fixpt_from_int(0);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_zero.value);
+
+	res = dc_fixpt_from_int(1);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_int(-1);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_int(INT_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, 0x7FFFFFFF00000000LL);
+
+	res = dc_fixpt_from_int(INT_MIN);
+	KUNIT_EXPECT_EQ(test, res.value,
+			0x8000000000000000LL); /* implicit negative signal */
+}
+
+/**
+ * dc_fixpt_from_fraction_test - KUnit test for dc_fixpt_from_fraction
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_from_fraction_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+
+	/* Assert signal works as expected */
+	res = dc_fixpt_from_fraction(1LL, 1LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-1LL, 1LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(1LL, -1LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-1LL, -1LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert that the greatest parameter values works as expected */
+	res = dc_fixpt_from_fraction(LLONG_MAX, LLONG_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(LLONG_MIN, LLONG_MIN);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Edge case using the smallest fraction possible without LSB rounding */
+	res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART));
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
+
+	/* Edge case using the smallest fraction possible with LSB rounding */
+	res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART + 1));
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
+
+	/* Assert an nil numerator is a valid input */
+	res = dc_fixpt_from_fraction(0LL, LLONG_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, 0LL);
+
+	/* Edge case using every bit of the decimal part without rounding */
+	res = dc_fixpt_from_fraction(8589934590LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0FFFFFFFFLL);
+
+	res = dc_fixpt_from_fraction(-8589934590LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, -0x0FFFFFFFFLL);
+
+	/* Edge case using every bit of the decimal part then rounding LSB */
+	res = dc_fixpt_from_fraction(8589934591LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-8589934591LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+	/*  A repeating decimal in binary representation that doesn't round up the LSB */
+	res = dc_fixpt_from_fraction(4, 3);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0000000155555555LL);
+
+	res = dc_fixpt_from_fraction(-4, 3);
+	KUNIT_EXPECT_EQ(test, res.value, -0x0000000155555555LL);
+
+	/* A repeating decimal in binary representation that rounds up the LSB */
+	res = dc_fixpt_from_fraction(5, 3);
+	KUNIT_EXPECT_EQ(test, res.value, 0x00000001AAAAAAABLL);
+
+	res = dc_fixpt_from_fraction(-5, 3);
+	KUNIT_EXPECT_EQ(test, res.value, -0x00000001AAAAAAABLL);
+}
+
+/**
+ * dc_fixpt_mul_test - KUnit test for dc_fixpt_mul
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_mul_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	/* Assert signal works as expected */
+	res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_minus_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_minus_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert that the greatest parameter values works as expected */
+	arg.value = LONG_MAX;
+	res = dc_fixpt_mul(arg, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MIN;
+	res = dc_fixpt_mul(arg, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MAX;
+	res = dc_fixpt_mul(dc_fixpt_one, arg);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MIN;
+	res = dc_fixpt_mul(dc_fixpt_one, arg);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	/* Assert it doesn't round LSB as expected */
+	arg.value = 0x7FFFFFFF7fffffffLL;
+	res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
+	KUNIT_EXPECT_EQ(test, res.value, 0x000000007FFFFFFF);
+
+	/* Assert it rounds LSB as expected */
+	arg.value = 0x7FFFFFFF80000000LL;
+	res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0000000080000000);
+}
+
+/**
+ * dc_fixpt_sqr_test - KUnit test for dc_fixpt_sqr
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_sqr_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	arg.value = dc_fixpt_one.value;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	arg.value = dc_fixpt_minus_one.value;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	arg.value = 0;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, 0);
+
+	/* Test some recognizable values */
+	arg = dc_fixpt_from_int(100);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_from_int(10000).value);
+
+	arg = dc_fixpt_from_fraction(1, 100);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value,
+			dc_fixpt_from_fraction(1, 10000).value);
+
+	/* LSB rounding */
+	arg = dc_fixpt_from_fraction(3, 2);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value,
+			dc_fixpt_from_fraction(9, 4).value + 1LL);
+}
+
+/**
+ * dc_fixpt_recip_test - KUnit test for dc_fixpt_recip
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_recip_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	/* Assert 1/1 works as expected */
+	res = dc_fixpt_recip(dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert smallest parameters work as expected. */
+	arg.value = 3LL;
+	res = dc_fixpt_recip(arg);
+	KUNIT_EXPECT_EQ(test, res.value, 0x5555555555555555LL);
+
+	arg.value = -3LL;
+	res = dc_fixpt_recip(arg);
+	KUNIT_EXPECT_EQ(test, res.value, -0x5555555555555555LL);
+}
+
+static struct kunit_case dc_basics_fixpt31_32_test_cases[] = {
+	KUNIT_CASE(dc_fixpt_from_int_test),
+	KUNIT_CASE(dc_fixpt_from_fraction_test),
+	KUNIT_CASE(dc_fixpt_mul_test),
+	KUNIT_CASE(dc_fixpt_sqr_test),
+	KUNIT_CASE(dc_fixpt_recip_test),
+	{}
+};
+
+static struct kunit_suite dc_basics_fixpt31_32_test_suite = {
+	.name = "dc_basics_fixpt31_32",
+	.test_cases = dc_basics_fixpt31_32_test_cases,
+};
+
+kunit_test_suites(&dc_basics_fixpt31_32_test_suite);
+
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 1/8] drm/amd/display: Introduce KUnit tests for fixed31_32 library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

From: Tales Aparecida <tales.aparecida@gmail.com>

The fixed31_32 library performs a lot of the mathematical operations
involving fixed-point arithmetic and the conversion of integers to
fixed-point representation.

This unit tests intend to assure the proper functioning of the basic
mathematical operations of fixed-point arithmetic, such as
multiplication, conversion from fractional to fixed-point number,
and more. Use kunit_tool to run:

$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
	--kunitconfig=drivers/gpu/drm/amd/display/tests/

Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 +
 drivers/gpu/drm/amd/display/Makefile          |   2 +-
 .../gpu/drm/amd/display/tests/.kunitconfig    |   6 +
 drivers/gpu/drm/amd/display/tests/Makefile    |  12 +
 .../display/tests/dc/basics/fixpt31_32_test.c | 232 ++++++++++++++++++
 5 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/.kunitconfig
 create mode 100644 drivers/gpu/drm/amd/display/tests/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 96cbc87f7b6b..cc44cfe88607 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -55,4 +55,17 @@ config DRM_AMD_SECURE_DISPLAY
             Cooperate with specific DMCU FW.
 
 
+config AMD_DC_BASICS_KUNIT_TEST
+	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the 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
diff --git a/drivers/gpu/drm/amd/display/Makefile b/drivers/gpu/drm/amd/display/Makefile
index 2633de77de5e..0f329aab13f0 100644
--- a/drivers/gpu/drm/amd/display/Makefile
+++ b/drivers/gpu/drm/amd/display/Makefile
@@ -43,7 +43,7 @@ endif
 #TODO: remove when Timing Sync feature is complete
 subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
 
-DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet modules/power dmub/src
+DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet modules/power dmub/src tests
 
 ifdef CONFIG_DRM_AMD_DC_HDCP
 DAL_LIBS += modules/hdcp
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
new file mode 100644
index 000000000000..60f2ff8158f5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -0,0 +1,6 @@
+CONFIG_KUNIT=y
+CONFIG_PCI=y
+CONFIG_DRM=y
+CONFIG_DRM_AMDGPU=y
+CONFIG_DRM_AMD_DC=y
+CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
\ No newline at end of file
diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
new file mode 100644
index 000000000000..ef16497318e8
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: MIT
+#
+# Makefile for the KUnit Tests for DC
+#
+
+ifdef CONFIG_AMD_DC_BASICS_KUNIT_TEST
+	DC_TESTS += dc/basics/fixpt31_32_test.o
+endif
+
+AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DC_TESTS)
diff --git a/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c b/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
new file mode 100644
index 000000000000..2fc489203499
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: MIT
+/* Unit tests for display/include/fixed31_32.h and dc/basics/fixpt31_32.c
+ *
+ * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
+ */
+
+#include <kunit/test.h>
+#include "os_types.h"
+#include "fixed31_32.h"
+
+static const struct fixed31_32 dc_fixpt_minus_one = { -0x100000000LL };
+
+/**
+ * dc_fixpt_from_int_test - KUnit test for dc_fixpt_from_int
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_from_int_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+
+	res = dc_fixpt_from_int(0);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_zero.value);
+
+	res = dc_fixpt_from_int(1);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_int(-1);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_int(INT_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, 0x7FFFFFFF00000000LL);
+
+	res = dc_fixpt_from_int(INT_MIN);
+	KUNIT_EXPECT_EQ(test, res.value,
+			0x8000000000000000LL); /* implicit negative signal */
+}
+
+/**
+ * dc_fixpt_from_fraction_test - KUnit test for dc_fixpt_from_fraction
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_from_fraction_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+
+	/* Assert signal works as expected */
+	res = dc_fixpt_from_fraction(1LL, 1LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-1LL, 1LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(1LL, -1LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-1LL, -1LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert that the greatest parameter values works as expected */
+	res = dc_fixpt_from_fraction(LLONG_MAX, LLONG_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(LLONG_MIN, LLONG_MIN);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Edge case using the smallest fraction possible without LSB rounding */
+	res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART));
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
+
+	/* Edge case using the smallest fraction possible with LSB rounding */
+	res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART + 1));
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
+
+	/* Assert an nil numerator is a valid input */
+	res = dc_fixpt_from_fraction(0LL, LLONG_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, 0LL);
+
+	/* Edge case using every bit of the decimal part without rounding */
+	res = dc_fixpt_from_fraction(8589934590LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0FFFFFFFFLL);
+
+	res = dc_fixpt_from_fraction(-8589934590LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, -0x0FFFFFFFFLL);
+
+	/* Edge case using every bit of the decimal part then rounding LSB */
+	res = dc_fixpt_from_fraction(8589934591LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-8589934591LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+	/*  A repeating decimal in binary representation that doesn't round up the LSB */
+	res = dc_fixpt_from_fraction(4, 3);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0000000155555555LL);
+
+	res = dc_fixpt_from_fraction(-4, 3);
+	KUNIT_EXPECT_EQ(test, res.value, -0x0000000155555555LL);
+
+	/* A repeating decimal in binary representation that rounds up the LSB */
+	res = dc_fixpt_from_fraction(5, 3);
+	KUNIT_EXPECT_EQ(test, res.value, 0x00000001AAAAAAABLL);
+
+	res = dc_fixpt_from_fraction(-5, 3);
+	KUNIT_EXPECT_EQ(test, res.value, -0x00000001AAAAAAABLL);
+}
+
+/**
+ * dc_fixpt_mul_test - KUnit test for dc_fixpt_mul
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_mul_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	/* Assert signal works as expected */
+	res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_minus_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_minus_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert that the greatest parameter values works as expected */
+	arg.value = LONG_MAX;
+	res = dc_fixpt_mul(arg, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MIN;
+	res = dc_fixpt_mul(arg, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MAX;
+	res = dc_fixpt_mul(dc_fixpt_one, arg);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MIN;
+	res = dc_fixpt_mul(dc_fixpt_one, arg);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	/* Assert it doesn't round LSB as expected */
+	arg.value = 0x7FFFFFFF7fffffffLL;
+	res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
+	KUNIT_EXPECT_EQ(test, res.value, 0x000000007FFFFFFF);
+
+	/* Assert it rounds LSB as expected */
+	arg.value = 0x7FFFFFFF80000000LL;
+	res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0000000080000000);
+}
+
+/**
+ * dc_fixpt_sqr_test - KUnit test for dc_fixpt_sqr
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_sqr_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	arg.value = dc_fixpt_one.value;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	arg.value = dc_fixpt_minus_one.value;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	arg.value = 0;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, 0);
+
+	/* Test some recognizable values */
+	arg = dc_fixpt_from_int(100);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_from_int(10000).value);
+
+	arg = dc_fixpt_from_fraction(1, 100);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value,
+			dc_fixpt_from_fraction(1, 10000).value);
+
+	/* LSB rounding */
+	arg = dc_fixpt_from_fraction(3, 2);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value,
+			dc_fixpt_from_fraction(9, 4).value + 1LL);
+}
+
+/**
+ * dc_fixpt_recip_test - KUnit test for dc_fixpt_recip
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_recip_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	/* Assert 1/1 works as expected */
+	res = dc_fixpt_recip(dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert smallest parameters work as expected. */
+	arg.value = 3LL;
+	res = dc_fixpt_recip(arg);
+	KUNIT_EXPECT_EQ(test, res.value, 0x5555555555555555LL);
+
+	arg.value = -3LL;
+	res = dc_fixpt_recip(arg);
+	KUNIT_EXPECT_EQ(test, res.value, -0x5555555555555555LL);
+}
+
+static struct kunit_case dc_basics_fixpt31_32_test_cases[] = {
+	KUNIT_CASE(dc_fixpt_from_int_test),
+	KUNIT_CASE(dc_fixpt_from_fraction_test),
+	KUNIT_CASE(dc_fixpt_mul_test),
+	KUNIT_CASE(dc_fixpt_sqr_test),
+	KUNIT_CASE(dc_fixpt_recip_test),
+	{}
+};
+
+static struct kunit_suite dc_basics_fixpt31_32_test_suite = {
+	.name = "dc_basics_fixpt31_32",
+	.test_cases = dc_basics_fixpt31_32_test_cases,
+};
+
+kunit_test_suites(&dc_basics_fixpt31_32_test_suite);
+
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 1/8] drm/amd/display: Introduce KUnit tests for fixed31_32 library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

From: Tales Aparecida <tales.aparecida@gmail.com>

The fixed31_32 library performs a lot of the mathematical operations
involving fixed-point arithmetic and the conversion of integers to
fixed-point representation.

This unit tests intend to assure the proper functioning of the basic
mathematical operations of fixed-point arithmetic, such as
multiplication, conversion from fractional to fixed-point number,
and more. Use kunit_tool to run:

$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
	--kunitconfig=drivers/gpu/drm/amd/display/tests/

Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 +
 drivers/gpu/drm/amd/display/Makefile          |   2 +-
 .../gpu/drm/amd/display/tests/.kunitconfig    |   6 +
 drivers/gpu/drm/amd/display/tests/Makefile    |  12 +
 .../display/tests/dc/basics/fixpt31_32_test.c | 232 ++++++++++++++++++
 5 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/.kunitconfig
 create mode 100644 drivers/gpu/drm/amd/display/tests/Makefile
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 96cbc87f7b6b..cc44cfe88607 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -55,4 +55,17 @@ config DRM_AMD_SECURE_DISPLAY
             Cooperate with specific DMCU FW.
 
 
+config AMD_DC_BASICS_KUNIT_TEST
+	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the 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
diff --git a/drivers/gpu/drm/amd/display/Makefile b/drivers/gpu/drm/amd/display/Makefile
index 2633de77de5e..0f329aab13f0 100644
--- a/drivers/gpu/drm/amd/display/Makefile
+++ b/drivers/gpu/drm/amd/display/Makefile
@@ -43,7 +43,7 @@ endif
 #TODO: remove when Timing Sync feature is complete
 subdir-ccflags-y += -DBUILD_FEATURE_TIMING_SYNC=0
 
-DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet modules/power dmub/src
+DAL_LIBS = amdgpu_dm dc	modules/freesync modules/color modules/info_packet modules/power dmub/src tests
 
 ifdef CONFIG_DRM_AMD_DC_HDCP
 DAL_LIBS += modules/hdcp
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
new file mode 100644
index 000000000000..60f2ff8158f5
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -0,0 +1,6 @@
+CONFIG_KUNIT=y
+CONFIG_PCI=y
+CONFIG_DRM=y
+CONFIG_DRM_AMDGPU=y
+CONFIG_DRM_AMD_DC=y
+CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
\ No newline at end of file
diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
new file mode 100644
index 000000000000..ef16497318e8
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: MIT
+#
+# Makefile for the KUnit Tests for DC
+#
+
+ifdef CONFIG_AMD_DC_BASICS_KUNIT_TEST
+	DC_TESTS += dc/basics/fixpt31_32_test.o
+endif
+
+AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
+
+AMD_DISPLAY_FILES += $(AMD_DAL_DC_TESTS)
diff --git a/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c b/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
new file mode 100644
index 000000000000..2fc489203499
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/basics/fixpt31_32_test.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: MIT
+/* Unit tests for display/include/fixed31_32.h and dc/basics/fixpt31_32.c
+ *
+ * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
+ */
+
+#include <kunit/test.h>
+#include "os_types.h"
+#include "fixed31_32.h"
+
+static const struct fixed31_32 dc_fixpt_minus_one = { -0x100000000LL };
+
+/**
+ * dc_fixpt_from_int_test - KUnit test for dc_fixpt_from_int
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_from_int_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+
+	res = dc_fixpt_from_int(0);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_zero.value);
+
+	res = dc_fixpt_from_int(1);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_int(-1);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_int(INT_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, 0x7FFFFFFF00000000LL);
+
+	res = dc_fixpt_from_int(INT_MIN);
+	KUNIT_EXPECT_EQ(test, res.value,
+			0x8000000000000000LL); /* implicit negative signal */
+}
+
+/**
+ * dc_fixpt_from_fraction_test - KUnit test for dc_fixpt_from_fraction
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_from_fraction_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+
+	/* Assert signal works as expected */
+	res = dc_fixpt_from_fraction(1LL, 1LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-1LL, 1LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(1LL, -1LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-1LL, -1LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert that the greatest parameter values works as expected */
+	res = dc_fixpt_from_fraction(LLONG_MAX, LLONG_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(LLONG_MIN, LLONG_MIN);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Edge case using the smallest fraction possible without LSB rounding */
+	res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART));
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
+
+	/* Edge case using the smallest fraction possible with LSB rounding */
+	res = dc_fixpt_from_fraction(1, 1LL << (FIXED31_32_BITS_PER_FRACTIONAL_PART + 1));
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_epsilon.value);
+
+	/* Assert an nil numerator is a valid input */
+	res = dc_fixpt_from_fraction(0LL, LLONG_MAX);
+	KUNIT_EXPECT_EQ(test, res.value, 0LL);
+
+	/* Edge case using every bit of the decimal part without rounding */
+	res = dc_fixpt_from_fraction(8589934590LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0FFFFFFFFLL);
+
+	res = dc_fixpt_from_fraction(-8589934590LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, -0x0FFFFFFFFLL);
+
+	/* Edge case using every bit of the decimal part then rounding LSB */
+	res = dc_fixpt_from_fraction(8589934591LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_from_fraction(-8589934591LL, 8589934592LL);
+	KUNIT_EXPECT_EQ(test, res.value, -dc_fixpt_one.value);
+	/*  A repeating decimal in binary representation that doesn't round up the LSB */
+	res = dc_fixpt_from_fraction(4, 3);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0000000155555555LL);
+
+	res = dc_fixpt_from_fraction(-4, 3);
+	KUNIT_EXPECT_EQ(test, res.value, -0x0000000155555555LL);
+
+	/* A repeating decimal in binary representation that rounds up the LSB */
+	res = dc_fixpt_from_fraction(5, 3);
+	KUNIT_EXPECT_EQ(test, res.value, 0x00000001AAAAAAABLL);
+
+	res = dc_fixpt_from_fraction(-5, 3);
+	KUNIT_EXPECT_EQ(test, res.value, -0x00000001AAAAAAABLL);
+}
+
+/**
+ * dc_fixpt_mul_test - KUnit test for dc_fixpt_mul
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_mul_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	/* Assert signal works as expected */
+	res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_one, dc_fixpt_minus_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_minus_one.value);
+
+	res = dc_fixpt_mul(dc_fixpt_minus_one, dc_fixpt_minus_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert that the greatest parameter values works as expected */
+	arg.value = LONG_MAX;
+	res = dc_fixpt_mul(arg, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MIN;
+	res = dc_fixpt_mul(arg, dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MAX;
+	res = dc_fixpt_mul(dc_fixpt_one, arg);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	arg.value = LONG_MIN;
+	res = dc_fixpt_mul(dc_fixpt_one, arg);
+	KUNIT_EXPECT_EQ(test, res.value, arg.value);
+
+	/* Assert it doesn't round LSB as expected */
+	arg.value = 0x7FFFFFFF7fffffffLL;
+	res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
+	KUNIT_EXPECT_EQ(test, res.value, 0x000000007FFFFFFF);
+
+	/* Assert it rounds LSB as expected */
+	arg.value = 0x7FFFFFFF80000000LL;
+	res = dc_fixpt_mul(arg, dc_fixpt_epsilon);
+	KUNIT_EXPECT_EQ(test, res.value, 0x0000000080000000);
+}
+
+/**
+ * dc_fixpt_sqr_test - KUnit test for dc_fixpt_sqr
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_sqr_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	arg.value = dc_fixpt_one.value;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	arg.value = dc_fixpt_minus_one.value;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	arg.value = 0;
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, 0);
+
+	/* Test some recognizable values */
+	arg = dc_fixpt_from_int(100);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_from_int(10000).value);
+
+	arg = dc_fixpt_from_fraction(1, 100);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value,
+			dc_fixpt_from_fraction(1, 10000).value);
+
+	/* LSB rounding */
+	arg = dc_fixpt_from_fraction(3, 2);
+	res = dc_fixpt_sqr(arg);
+	KUNIT_EXPECT_EQ(test, res.value,
+			dc_fixpt_from_fraction(9, 4).value + 1LL);
+}
+
+/**
+ * dc_fixpt_recip_test - KUnit test for dc_fixpt_recip
+ * @test: represents a running instance of a test.
+ */
+static void dc_fixpt_recip_test(struct kunit *test)
+{
+	struct fixed31_32 res;
+	struct fixed31_32 arg;
+
+	/* Assert 1/1 works as expected */
+	res = dc_fixpt_recip(dc_fixpt_one);
+	KUNIT_EXPECT_EQ(test, res.value, dc_fixpt_one.value);
+
+	/* Assert smallest parameters work as expected. */
+	arg.value = 3LL;
+	res = dc_fixpt_recip(arg);
+	KUNIT_EXPECT_EQ(test, res.value, 0x5555555555555555LL);
+
+	arg.value = -3LL;
+	res = dc_fixpt_recip(arg);
+	KUNIT_EXPECT_EQ(test, res.value, -0x5555555555555555LL);
+}
+
+static struct kunit_case dc_basics_fixpt31_32_test_cases[] = {
+	KUNIT_CASE(dc_fixpt_from_int_test),
+	KUNIT_CASE(dc_fixpt_from_fraction_test),
+	KUNIT_CASE(dc_fixpt_mul_test),
+	KUNIT_CASE(dc_fixpt_sqr_test),
+	KUNIT_CASE(dc_fixpt_recip_test),
+	{}
+};
+
+static struct kunit_suite dc_basics_fixpt31_32_test_suite = {
+	.name = "dc_basics_fixpt31_32",
+	.test_cases = dc_basics_fixpt31_32_test_cases,
+};
+
+kunit_test_suites(&dc_basics_fixpt31_32_test_suite);
+
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 2/8] drm/amd/display: Introduce KUnit tests to the bw_fixed library
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

KUnit unifies the test structure and provides helper tools that simplify
the development of tests. Basic use case allows running tests as regular
processes, which makes easier to run unit tests on a development machine
and to integrate the tests in a CI system.

This commit introduces a unit test to the bw_fixed library, which
performs a lot of the mathematical operations involving fixed-point
arithmetic and the conversion of integers to fixed-point representation
inside the Display Mode Library.

As fixed-point representation is the base foundation of the DML calcs
operations, this unit tests intend to assure the proper functioning of
the basic mathematical operations of fixed-point arithmetic, such as
multiplication, conversion from fractional to fixed-point number, and
more.  You can run it with: ./tools/testing/kunit/kunit.py run \
	--arch=x86_64 \
	--kunitconfig=drivers/gpu/drm/amd/display/tests/

Co-developed-by: Magali Lemes <magalilemes00@gmail.com>
Signed-off-by: Magali Lemes <magalilemes00@gmail.com>
Co-developed-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  12 +
 .../drm/amd/display/dc/dml/calcs/bw_fixed.c   |   3 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   3 +-
 .../tests/dc/dml/calcs/bw_fixed_test.c        | 323 ++++++++++++++++++
 4 files changed, 340 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index cc44cfe88607..ce882a8c24f5 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -54,6 +54,18 @@ config DRM_AMD_SECURE_DISPLAY
             of crc of specific region via debugfs.
             Cooperate with specific DMCU FW.
 
+config DCE_KUNIT_TEST
+	bool "Run all KUnit tests for DCE" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the Display Controller Engine. 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.
 
 config AMD_DC_BASICS_KUNIT_TEST
 	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
index 3aa8dd0acd5e..79ef53ea2480 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
@@ -187,3 +187,6 @@ struct bw_fixed bw_mul(const struct bw_fixed arg1, const struct bw_fixed arg2)
 	return res;
 }
 
+#if IS_ENABLED(CONFIG_DCE_KUNIT_TEST)
+#include "../../../tests/dc/dml/calcs/bw_fixed_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index 60f2ff8158f5..7a58f75a8dfc 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -3,4 +3,5 @@ CONFIG_PCI=y
 CONFIG_DRM=y
 CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
-CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
\ No newline at end of file
+CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+CONFIG_DCE_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
new file mode 100644
index 000000000000..1369da49f444
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/calcs/bw_fixed.h
+ *
+ * Copyright (C) 2022, Magali Lemes <magalilemes00@gmail.com>
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
+ */
+
+#include <kunit/test.h>
+#include <drm/drm_util.h>
+#include "bw_fixed.h"
+
+/**
+ * DOC: Unit tests for AMDGPU DML calcs/bw_fixed.h
+ *
+ * bw_fixed.h performs a lot of the mathematical operations involving
+ * fixed-point arithmetic and the conversion of integers to fixed-point
+ * representation.
+ *
+ * As fixed-point representation is the base foundation of the DML calcs
+ * operations, these tests intend to assure the proper functioning of the
+ * basic mathematical operations of fixed-point arithmetic, such as
+ * multiplication, conversion from fractional to fixed-point number, and more.
+ *
+ */
+
+/**
+ * abs_i64_test - KUnit test for abs_i64
+ * @test: represents a running instance of a test.
+ */
+static void abs_i64_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, 0ULL, abs_i64(0LL));
+
+	/* Argument type limits */
+	KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64, abs_i64(MAX_I64));
+	KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64 + 1, abs_i64(MIN_I64));
+}
+
+/**
+ * bw_int_to_fixed_nonconst_test - KUnit test for bw_int_to_fixed_nonconst
+ * @test: represents a running instance of a test.
+ */
+static void bw_int_to_fixed_nonconst_test(struct kunit *test)
+{
+	struct bw_fixed res;
+
+	/* Add BW_FIXED_BITS_PER_FRACTIONAL_PART trailing 0s to binary number */
+	res = bw_int_to_fixed_nonconst(1000);          /* 0x3E8 */
+	KUNIT_EXPECT_EQ(test, 16777216000, res.value); /* 0x3E8000000 */
+
+	res = bw_int_to_fixed_nonconst(-1000);          /* -0x3E8 */
+	KUNIT_EXPECT_EQ(test, -16777216000, res.value); /* -0x3E8000000 */
+
+	res = bw_int_to_fixed_nonconst(0LL);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	/**
+	 * Test corner cases, as the function's argument has to be an int64_t
+	 * between BW_FIXED_MIN_I32 and BW_FIXED_MAX_I32.
+	 */
+	res = bw_int_to_fixed_nonconst(BW_FIXED_MAX_I32 - 1);  /* 0x7FFFFFFFFE */
+	KUNIT_EXPECT_EQ(test, 9223372036821221376, res.value); /* 0x7FFFFFFFFE000000 */
+
+	res = bw_int_to_fixed_nonconst(BW_FIXED_MIN_I32 + 1);   /* -0x7FFFFFFFFF */
+	KUNIT_EXPECT_EQ(test, -9223372036837998592, res.value); /* -0x7FFFFFFFFF000000 */
+}
+
+/**
+ * bw_frc_to_fixed_test - KUnit test for bw_frc_to_fixed
+ * @test: represents a running instance of a test.
+ */
+static void bw_frc_to_fixed_test(struct kunit *test)
+{
+	struct bw_fixed res;
+
+	/* Extreme scenarios */
+
+	/* A fraction of N/N should result in "1.0" */
+	res = bw_frc_to_fixed(MAX_I64, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+	res = bw_frc_to_fixed(1, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+	res = bw_frc_to_fixed(0, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+	/* Turn a repeating decimal to the fixed-point representation */
+
+	/* A repeating decimal that doesn't round up the LSB */
+	res = bw_frc_to_fixed(4, 3);
+	KUNIT_EXPECT_EQ(test, 22369621LL, res.value);     /* 0x1555555 */
+
+	res = bw_frc_to_fixed(-4, 3);
+	KUNIT_EXPECT_EQ(test, -22369621LL, res.value);    /* -0x1555555 */
+
+	res = bw_frc_to_fixed(99999997, 100000000);
+	KUNIT_EXPECT_EQ(test, 16777215LL, res.value);     /* 0x0FFFFFF */
+
+	/* A repeating decimal that rounds up the MSB */
+	res = bw_frc_to_fixed(5, 3);
+	KUNIT_EXPECT_EQ(test, 27962027LL, res.value);     /* 0x1AAAAAB */
+
+	res = bw_frc_to_fixed(-5, 3);
+	KUNIT_EXPECT_EQ(test, -27962027LL, res.value);    /* -0x1AAAAAB */
+
+	res = bw_frc_to_fixed(99999998, 100000000);
+	KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+	/* Turn a terminating decimal to the fixed-point representation */
+	res = bw_frc_to_fixed(62609, 100);
+	KUNIT_EXPECT_EQ(test, 10504047165LL, res.value);  /* 0X272170A3D */
+
+	res = bw_frc_to_fixed(-62609, 100);
+	KUNIT_EXPECT_EQ(test, -10504047165LL, res.value); /* -0X272170A3D */
+}
+
+/**
+ * bw_floor2_test - KUnit test for bw_floor2
+ * @test: represents a running instance of a test.
+ */
+static void bw_floor2_test(struct kunit *test)
+{
+	struct bw_fixed arg;
+	struct bw_fixed significance;
+	struct bw_fixed res;
+
+	/* Round 10 down to the nearest multiple of 3 */
+	arg.value = 10;
+	significance.value = 3;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 9, res.value);
+
+	/* Round 10 down to the nearest multiple of 5 */
+	arg.value = 10;
+	significance.value = 5;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 10, res.value);
+
+	/* Round 100 down to the nearest multiple of 7 */
+	arg.value = 100;
+	significance.value = 7;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 98, res.value);
+
+	/* Round an integer down to its nearest multiple should return itself */
+	arg.value = MAX_I64;
+	significance.value = MAX_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	arg.value = MIN_I64;
+	significance.value = MIN_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MIN_I64, res.value);
+
+	/* Value is a multiple of significance, result should be value */
+	arg.value = MAX_I64;
+	significance.value = MIN_I64 + 1;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	/* Round 0 down to the nearest multiple of any number should return 0 */
+	arg.value = 0;
+	significance.value = MAX_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg.value = 0;
+	significance.value = MIN_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+/**
+ * bw_ceil2_test - KUnit test for bw_ceil2
+ * @test: represents a running instance of a test.
+ */
+static void bw_ceil2_test(struct kunit *test)
+{
+	struct bw_fixed arg;
+	struct bw_fixed significance;
+	struct bw_fixed res;
+
+	/* Round 10 up to the nearest multiple of 3 */
+	arg.value = 10;
+	significance.value = 3;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 12, res.value);
+
+	/* Round 10 up to the nearest multiple of 5 */
+	arg.value = 10;
+	significance.value = 5;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 10, res.value);
+
+	/* Round 100 up to the nearest multiple of 7 */
+	arg.value = 100;
+	significance.value = 7;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 105, res.value);
+
+	/* Round an integer up to its nearest multiple should return itself */
+	arg.value = MAX_I64;
+	significance.value = MAX_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	arg.value = MIN_I64 + 1;
+	significance.value = MIN_I64 + 1;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MIN_I64 + 1, res.value);
+
+	/* Value is a multiple of significance, result should be value */
+	arg.value = MAX_I64;
+	significance.value = MIN_I64 + 1;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	/* Round 0 up to the nearest multiple of any number should return 0 */
+	arg.value = 0;
+	significance.value = MAX_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg.value = 0;
+	significance.value = MIN_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+/**
+ * bw_mul_test - KUnit test for bw_mul
+ * @test: represents a running instance of a test.
+ */
+static void bw_mul_test(struct kunit *test)
+{
+	struct bw_fixed arg1;
+	struct bw_fixed arg2;
+	struct bw_fixed res;
+	struct bw_fixed expected;
+
+	/* Extreme scenario */
+	arg1.value = MAX_I64;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+	/* Testing multiplication property: x * 1 = x */
+	arg1.value = 1;
+	arg2.value = MAX_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+	arg1.value = 1;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MIN_I32, res.value);
+
+	/* Testing multiplication property: x * 0 = 0 */
+	arg1.value = 0;
+	arg2.value = 0;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg1.value = 0;
+	arg2.value = MAX_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg1.value = 0;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	/* Testing multiplication between integers */
+	res = bw_mul(bw_int_to_fixed(8), bw_int_to_fixed(10));
+	KUNIT_EXPECT_EQ(test, 1342177280LL, res.value); /* 0x50000000 */
+
+	res = bw_mul(bw_int_to_fixed(10), bw_int_to_fixed(5));
+	KUNIT_EXPECT_EQ(test, 838860800LL, res.value); /* 0x32000000 */
+
+	res = bw_mul(bw_int_to_fixed(-10), bw_int_to_fixed(7));
+	KUNIT_EXPECT_EQ(test, -1174405120LL, res.value); /* -0x46000000 */
+
+	/* Testing multiplication between fractions and integers */
+	res = bw_mul(bw_frc_to_fixed(4, 3), bw_int_to_fixed(3));
+	expected = bw_int_to_fixed(4);
+
+	/*
+	 * As bw_frc_to_fixed(4, 3) didn't round up the fixed-point representation,
+	 * the expected must be subtracted by 1.
+	 */
+	KUNIT_EXPECT_EQ(test, expected.value - 1, res.value);
+
+	res = bw_mul(bw_frc_to_fixed(5, 3), bw_int_to_fixed(3));
+	expected = bw_int_to_fixed(5);
+
+	/*
+	 * As bw_frc_to_fixed(5, 3) rounds up the fixed-point representation,
+	 * the expected must be added by 1.
+	 */
+	KUNIT_EXPECT_EQ(test, expected.value + 1, res.value);
+}
+
+static struct kunit_case bw_fixed_test_cases[] = {
+	KUNIT_CASE(abs_i64_test),
+	KUNIT_CASE(bw_int_to_fixed_nonconst_test),
+	KUNIT_CASE(bw_frc_to_fixed_test),
+	KUNIT_CASE(bw_floor2_test),
+	KUNIT_CASE(bw_ceil2_test),
+	KUNIT_CASE(bw_mul_test),
+	{  }
+};
+
+static struct kunit_suite bw_fixed_test_suite = {
+	.name = "dml_calcs_bw_fixed",
+	.test_cases = bw_fixed_test_cases,
+};
+
+kunit_test_suites(&bw_fixed_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 2/8] drm/amd/display: Introduce KUnit tests to the bw_fixed library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

KUnit unifies the test structure and provides helper tools that simplify
the development of tests. Basic use case allows running tests as regular
processes, which makes easier to run unit tests on a development machine
and to integrate the tests in a CI system.

This commit introduces a unit test to the bw_fixed library, which
performs a lot of the mathematical operations involving fixed-point
arithmetic and the conversion of integers to fixed-point representation
inside the Display Mode Library.

As fixed-point representation is the base foundation of the DML calcs
operations, this unit tests intend to assure the proper functioning of
the basic mathematical operations of fixed-point arithmetic, such as
multiplication, conversion from fractional to fixed-point number, and
more.  You can run it with: ./tools/testing/kunit/kunit.py run \
	--arch=x86_64 \
	--kunitconfig=drivers/gpu/drm/amd/display/tests/

Co-developed-by: Magali Lemes <magalilemes00@gmail.com>
Signed-off-by: Magali Lemes <magalilemes00@gmail.com>
Co-developed-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  12 +
 .../drm/amd/display/dc/dml/calcs/bw_fixed.c   |   3 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   3 +-
 .../tests/dc/dml/calcs/bw_fixed_test.c        | 323 ++++++++++++++++++
 4 files changed, 340 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index cc44cfe88607..ce882a8c24f5 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -54,6 +54,18 @@ config DRM_AMD_SECURE_DISPLAY
             of crc of specific region via debugfs.
             Cooperate with specific DMCU FW.
 
+config DCE_KUNIT_TEST
+	bool "Run all KUnit tests for DCE" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the Display Controller Engine. 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.
 
 config AMD_DC_BASICS_KUNIT_TEST
 	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
index 3aa8dd0acd5e..79ef53ea2480 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
@@ -187,3 +187,6 @@ struct bw_fixed bw_mul(const struct bw_fixed arg1, const struct bw_fixed arg2)
 	return res;
 }
 
+#if IS_ENABLED(CONFIG_DCE_KUNIT_TEST)
+#include "../../../tests/dc/dml/calcs/bw_fixed_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index 60f2ff8158f5..7a58f75a8dfc 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -3,4 +3,5 @@ CONFIG_PCI=y
 CONFIG_DRM=y
 CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
-CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
\ No newline at end of file
+CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+CONFIG_DCE_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
new file mode 100644
index 000000000000..1369da49f444
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/calcs/bw_fixed.h
+ *
+ * Copyright (C) 2022, Magali Lemes <magalilemes00@gmail.com>
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
+ */
+
+#include <kunit/test.h>
+#include <drm/drm_util.h>
+#include "bw_fixed.h"
+
+/**
+ * DOC: Unit tests for AMDGPU DML calcs/bw_fixed.h
+ *
+ * bw_fixed.h performs a lot of the mathematical operations involving
+ * fixed-point arithmetic and the conversion of integers to fixed-point
+ * representation.
+ *
+ * As fixed-point representation is the base foundation of the DML calcs
+ * operations, these tests intend to assure the proper functioning of the
+ * basic mathematical operations of fixed-point arithmetic, such as
+ * multiplication, conversion from fractional to fixed-point number, and more.
+ *
+ */
+
+/**
+ * abs_i64_test - KUnit test for abs_i64
+ * @test: represents a running instance of a test.
+ */
+static void abs_i64_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, 0ULL, abs_i64(0LL));
+
+	/* Argument type limits */
+	KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64, abs_i64(MAX_I64));
+	KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64 + 1, abs_i64(MIN_I64));
+}
+
+/**
+ * bw_int_to_fixed_nonconst_test - KUnit test for bw_int_to_fixed_nonconst
+ * @test: represents a running instance of a test.
+ */
+static void bw_int_to_fixed_nonconst_test(struct kunit *test)
+{
+	struct bw_fixed res;
+
+	/* Add BW_FIXED_BITS_PER_FRACTIONAL_PART trailing 0s to binary number */
+	res = bw_int_to_fixed_nonconst(1000);          /* 0x3E8 */
+	KUNIT_EXPECT_EQ(test, 16777216000, res.value); /* 0x3E8000000 */
+
+	res = bw_int_to_fixed_nonconst(-1000);          /* -0x3E8 */
+	KUNIT_EXPECT_EQ(test, -16777216000, res.value); /* -0x3E8000000 */
+
+	res = bw_int_to_fixed_nonconst(0LL);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	/**
+	 * Test corner cases, as the function's argument has to be an int64_t
+	 * between BW_FIXED_MIN_I32 and BW_FIXED_MAX_I32.
+	 */
+	res = bw_int_to_fixed_nonconst(BW_FIXED_MAX_I32 - 1);  /* 0x7FFFFFFFFE */
+	KUNIT_EXPECT_EQ(test, 9223372036821221376, res.value); /* 0x7FFFFFFFFE000000 */
+
+	res = bw_int_to_fixed_nonconst(BW_FIXED_MIN_I32 + 1);   /* -0x7FFFFFFFFF */
+	KUNIT_EXPECT_EQ(test, -9223372036837998592, res.value); /* -0x7FFFFFFFFF000000 */
+}
+
+/**
+ * bw_frc_to_fixed_test - KUnit test for bw_frc_to_fixed
+ * @test: represents a running instance of a test.
+ */
+static void bw_frc_to_fixed_test(struct kunit *test)
+{
+	struct bw_fixed res;
+
+	/* Extreme scenarios */
+
+	/* A fraction of N/N should result in "1.0" */
+	res = bw_frc_to_fixed(MAX_I64, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+	res = bw_frc_to_fixed(1, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+	res = bw_frc_to_fixed(0, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+	/* Turn a repeating decimal to the fixed-point representation */
+
+	/* A repeating decimal that doesn't round up the LSB */
+	res = bw_frc_to_fixed(4, 3);
+	KUNIT_EXPECT_EQ(test, 22369621LL, res.value);     /* 0x1555555 */
+
+	res = bw_frc_to_fixed(-4, 3);
+	KUNIT_EXPECT_EQ(test, -22369621LL, res.value);    /* -0x1555555 */
+
+	res = bw_frc_to_fixed(99999997, 100000000);
+	KUNIT_EXPECT_EQ(test, 16777215LL, res.value);     /* 0x0FFFFFF */
+
+	/* A repeating decimal that rounds up the MSB */
+	res = bw_frc_to_fixed(5, 3);
+	KUNIT_EXPECT_EQ(test, 27962027LL, res.value);     /* 0x1AAAAAB */
+
+	res = bw_frc_to_fixed(-5, 3);
+	KUNIT_EXPECT_EQ(test, -27962027LL, res.value);    /* -0x1AAAAAB */
+
+	res = bw_frc_to_fixed(99999998, 100000000);
+	KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+	/* Turn a terminating decimal to the fixed-point representation */
+	res = bw_frc_to_fixed(62609, 100);
+	KUNIT_EXPECT_EQ(test, 10504047165LL, res.value);  /* 0X272170A3D */
+
+	res = bw_frc_to_fixed(-62609, 100);
+	KUNIT_EXPECT_EQ(test, -10504047165LL, res.value); /* -0X272170A3D */
+}
+
+/**
+ * bw_floor2_test - KUnit test for bw_floor2
+ * @test: represents a running instance of a test.
+ */
+static void bw_floor2_test(struct kunit *test)
+{
+	struct bw_fixed arg;
+	struct bw_fixed significance;
+	struct bw_fixed res;
+
+	/* Round 10 down to the nearest multiple of 3 */
+	arg.value = 10;
+	significance.value = 3;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 9, res.value);
+
+	/* Round 10 down to the nearest multiple of 5 */
+	arg.value = 10;
+	significance.value = 5;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 10, res.value);
+
+	/* Round 100 down to the nearest multiple of 7 */
+	arg.value = 100;
+	significance.value = 7;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 98, res.value);
+
+	/* Round an integer down to its nearest multiple should return itself */
+	arg.value = MAX_I64;
+	significance.value = MAX_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	arg.value = MIN_I64;
+	significance.value = MIN_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MIN_I64, res.value);
+
+	/* Value is a multiple of significance, result should be value */
+	arg.value = MAX_I64;
+	significance.value = MIN_I64 + 1;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	/* Round 0 down to the nearest multiple of any number should return 0 */
+	arg.value = 0;
+	significance.value = MAX_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg.value = 0;
+	significance.value = MIN_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+/**
+ * bw_ceil2_test - KUnit test for bw_ceil2
+ * @test: represents a running instance of a test.
+ */
+static void bw_ceil2_test(struct kunit *test)
+{
+	struct bw_fixed arg;
+	struct bw_fixed significance;
+	struct bw_fixed res;
+
+	/* Round 10 up to the nearest multiple of 3 */
+	arg.value = 10;
+	significance.value = 3;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 12, res.value);
+
+	/* Round 10 up to the nearest multiple of 5 */
+	arg.value = 10;
+	significance.value = 5;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 10, res.value);
+
+	/* Round 100 up to the nearest multiple of 7 */
+	arg.value = 100;
+	significance.value = 7;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 105, res.value);
+
+	/* Round an integer up to its nearest multiple should return itself */
+	arg.value = MAX_I64;
+	significance.value = MAX_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	arg.value = MIN_I64 + 1;
+	significance.value = MIN_I64 + 1;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MIN_I64 + 1, res.value);
+
+	/* Value is a multiple of significance, result should be value */
+	arg.value = MAX_I64;
+	significance.value = MIN_I64 + 1;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	/* Round 0 up to the nearest multiple of any number should return 0 */
+	arg.value = 0;
+	significance.value = MAX_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg.value = 0;
+	significance.value = MIN_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+/**
+ * bw_mul_test - KUnit test for bw_mul
+ * @test: represents a running instance of a test.
+ */
+static void bw_mul_test(struct kunit *test)
+{
+	struct bw_fixed arg1;
+	struct bw_fixed arg2;
+	struct bw_fixed res;
+	struct bw_fixed expected;
+
+	/* Extreme scenario */
+	arg1.value = MAX_I64;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+	/* Testing multiplication property: x * 1 = x */
+	arg1.value = 1;
+	arg2.value = MAX_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+	arg1.value = 1;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MIN_I32, res.value);
+
+	/* Testing multiplication property: x * 0 = 0 */
+	arg1.value = 0;
+	arg2.value = 0;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg1.value = 0;
+	arg2.value = MAX_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg1.value = 0;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	/* Testing multiplication between integers */
+	res = bw_mul(bw_int_to_fixed(8), bw_int_to_fixed(10));
+	KUNIT_EXPECT_EQ(test, 1342177280LL, res.value); /* 0x50000000 */
+
+	res = bw_mul(bw_int_to_fixed(10), bw_int_to_fixed(5));
+	KUNIT_EXPECT_EQ(test, 838860800LL, res.value); /* 0x32000000 */
+
+	res = bw_mul(bw_int_to_fixed(-10), bw_int_to_fixed(7));
+	KUNIT_EXPECT_EQ(test, -1174405120LL, res.value); /* -0x46000000 */
+
+	/* Testing multiplication between fractions and integers */
+	res = bw_mul(bw_frc_to_fixed(4, 3), bw_int_to_fixed(3));
+	expected = bw_int_to_fixed(4);
+
+	/*
+	 * As bw_frc_to_fixed(4, 3) didn't round up the fixed-point representation,
+	 * the expected must be subtracted by 1.
+	 */
+	KUNIT_EXPECT_EQ(test, expected.value - 1, res.value);
+
+	res = bw_mul(bw_frc_to_fixed(5, 3), bw_int_to_fixed(3));
+	expected = bw_int_to_fixed(5);
+
+	/*
+	 * As bw_frc_to_fixed(5, 3) rounds up the fixed-point representation,
+	 * the expected must be added by 1.
+	 */
+	KUNIT_EXPECT_EQ(test, expected.value + 1, res.value);
+}
+
+static struct kunit_case bw_fixed_test_cases[] = {
+	KUNIT_CASE(abs_i64_test),
+	KUNIT_CASE(bw_int_to_fixed_nonconst_test),
+	KUNIT_CASE(bw_frc_to_fixed_test),
+	KUNIT_CASE(bw_floor2_test),
+	KUNIT_CASE(bw_ceil2_test),
+	KUNIT_CASE(bw_mul_test),
+	{  }
+};
+
+static struct kunit_suite bw_fixed_test_suite = {
+	.name = "dml_calcs_bw_fixed",
+	.test_cases = bw_fixed_test_cases,
+};
+
+kunit_test_suites(&bw_fixed_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 2/8] drm/amd/display: Introduce KUnit tests to the bw_fixed library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

KUnit unifies the test structure and provides helper tools that simplify
the development of tests. Basic use case allows running tests as regular
processes, which makes easier to run unit tests on a development machine
and to integrate the tests in a CI system.

This commit introduces a unit test to the bw_fixed library, which
performs a lot of the mathematical operations involving fixed-point
arithmetic and the conversion of integers to fixed-point representation
inside the Display Mode Library.

As fixed-point representation is the base foundation of the DML calcs
operations, this unit tests intend to assure the proper functioning of
the basic mathematical operations of fixed-point arithmetic, such as
multiplication, conversion from fractional to fixed-point number, and
more.  You can run it with: ./tools/testing/kunit/kunit.py run \
	--arch=x86_64 \
	--kunitconfig=drivers/gpu/drm/amd/display/tests/

Co-developed-by: Magali Lemes <magalilemes00@gmail.com>
Signed-off-by: Magali Lemes <magalilemes00@gmail.com>
Co-developed-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Tales Aparecida <tales.aparecida@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  12 +
 .../drm/amd/display/dc/dml/calcs/bw_fixed.c   |   3 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   3 +-
 .../tests/dc/dml/calcs/bw_fixed_test.c        | 323 ++++++++++++++++++
 4 files changed, 340 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index cc44cfe88607..ce882a8c24f5 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -54,6 +54,18 @@ config DRM_AMD_SECURE_DISPLAY
             of crc of specific region via debugfs.
             Cooperate with specific DMCU FW.
 
+config DCE_KUNIT_TEST
+	bool "Run all KUnit tests for DCE" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the Display Controller Engine. 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.
 
 config AMD_DC_BASICS_KUNIT_TEST
 	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
diff --git a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
index 3aa8dd0acd5e..79ef53ea2480 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/calcs/bw_fixed.c
@@ -187,3 +187,6 @@ struct bw_fixed bw_mul(const struct bw_fixed arg1, const struct bw_fixed arg2)
 	return res;
 }
 
+#if IS_ENABLED(CONFIG_DCE_KUNIT_TEST)
+#include "../../../tests/dc/dml/calcs/bw_fixed_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index 60f2ff8158f5..7a58f75a8dfc 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -3,4 +3,5 @@ CONFIG_PCI=y
 CONFIG_DRM=y
 CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
-CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
\ No newline at end of file
+CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+CONFIG_DCE_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
new file mode 100644
index 000000000000..1369da49f444
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/calcs/bw_fixed_test.c
@@ -0,0 +1,323 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/calcs/bw_fixed.h
+ *
+ * Copyright (C) 2022, Magali Lemes <magalilemes00@gmail.com>
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ * Copyright (C) 2022, Tales Aparecida <tales.aparecida@gmail.com>
+ */
+
+#include <kunit/test.h>
+#include <drm/drm_util.h>
+#include "bw_fixed.h"
+
+/**
+ * DOC: Unit tests for AMDGPU DML calcs/bw_fixed.h
+ *
+ * bw_fixed.h performs a lot of the mathematical operations involving
+ * fixed-point arithmetic and the conversion of integers to fixed-point
+ * representation.
+ *
+ * As fixed-point representation is the base foundation of the DML calcs
+ * operations, these tests intend to assure the proper functioning of the
+ * basic mathematical operations of fixed-point arithmetic, such as
+ * multiplication, conversion from fractional to fixed-point number, and more.
+ *
+ */
+
+/**
+ * abs_i64_test - KUnit test for abs_i64
+ * @test: represents a running instance of a test.
+ */
+static void abs_i64_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, 0ULL, abs_i64(0LL));
+
+	/* Argument type limits */
+	KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64, abs_i64(MAX_I64));
+	KUNIT_EXPECT_EQ(test, (uint64_t)MAX_I64 + 1, abs_i64(MIN_I64));
+}
+
+/**
+ * bw_int_to_fixed_nonconst_test - KUnit test for bw_int_to_fixed_nonconst
+ * @test: represents a running instance of a test.
+ */
+static void bw_int_to_fixed_nonconst_test(struct kunit *test)
+{
+	struct bw_fixed res;
+
+	/* Add BW_FIXED_BITS_PER_FRACTIONAL_PART trailing 0s to binary number */
+	res = bw_int_to_fixed_nonconst(1000);          /* 0x3E8 */
+	KUNIT_EXPECT_EQ(test, 16777216000, res.value); /* 0x3E8000000 */
+
+	res = bw_int_to_fixed_nonconst(-1000);          /* -0x3E8 */
+	KUNIT_EXPECT_EQ(test, -16777216000, res.value); /* -0x3E8000000 */
+
+	res = bw_int_to_fixed_nonconst(0LL);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	/**
+	 * Test corner cases, as the function's argument has to be an int64_t
+	 * between BW_FIXED_MIN_I32 and BW_FIXED_MAX_I32.
+	 */
+	res = bw_int_to_fixed_nonconst(BW_FIXED_MAX_I32 - 1);  /* 0x7FFFFFFFFE */
+	KUNIT_EXPECT_EQ(test, 9223372036821221376, res.value); /* 0x7FFFFFFFFE000000 */
+
+	res = bw_int_to_fixed_nonconst(BW_FIXED_MIN_I32 + 1);   /* -0x7FFFFFFFFF */
+	KUNIT_EXPECT_EQ(test, -9223372036837998592, res.value); /* -0x7FFFFFFFFF000000 */
+}
+
+/**
+ * bw_frc_to_fixed_test - KUnit test for bw_frc_to_fixed
+ * @test: represents a running instance of a test.
+ */
+static void bw_frc_to_fixed_test(struct kunit *test)
+{
+	struct bw_fixed res;
+
+	/* Extreme scenarios */
+
+	/* A fraction of N/N should result in "1.0" */
+	res = bw_frc_to_fixed(MAX_I64, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+	res = bw_frc_to_fixed(1, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+	res = bw_frc_to_fixed(0, MAX_I64);
+	KUNIT_EXPECT_EQ(test, 0LL, res.value);
+
+	/* Turn a repeating decimal to the fixed-point representation */
+
+	/* A repeating decimal that doesn't round up the LSB */
+	res = bw_frc_to_fixed(4, 3);
+	KUNIT_EXPECT_EQ(test, 22369621LL, res.value);     /* 0x1555555 */
+
+	res = bw_frc_to_fixed(-4, 3);
+	KUNIT_EXPECT_EQ(test, -22369621LL, res.value);    /* -0x1555555 */
+
+	res = bw_frc_to_fixed(99999997, 100000000);
+	KUNIT_EXPECT_EQ(test, 16777215LL, res.value);     /* 0x0FFFFFF */
+
+	/* A repeating decimal that rounds up the MSB */
+	res = bw_frc_to_fixed(5, 3);
+	KUNIT_EXPECT_EQ(test, 27962027LL, res.value);     /* 0x1AAAAAB */
+
+	res = bw_frc_to_fixed(-5, 3);
+	KUNIT_EXPECT_EQ(test, -27962027LL, res.value);    /* -0x1AAAAAB */
+
+	res = bw_frc_to_fixed(99999998, 100000000);
+	KUNIT_EXPECT_EQ(test, 1LL << BW_FIXED_BITS_PER_FRACTIONAL_PART, res.value);
+
+	/* Turn a terminating decimal to the fixed-point representation */
+	res = bw_frc_to_fixed(62609, 100);
+	KUNIT_EXPECT_EQ(test, 10504047165LL, res.value);  /* 0X272170A3D */
+
+	res = bw_frc_to_fixed(-62609, 100);
+	KUNIT_EXPECT_EQ(test, -10504047165LL, res.value); /* -0X272170A3D */
+}
+
+/**
+ * bw_floor2_test - KUnit test for bw_floor2
+ * @test: represents a running instance of a test.
+ */
+static void bw_floor2_test(struct kunit *test)
+{
+	struct bw_fixed arg;
+	struct bw_fixed significance;
+	struct bw_fixed res;
+
+	/* Round 10 down to the nearest multiple of 3 */
+	arg.value = 10;
+	significance.value = 3;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 9, res.value);
+
+	/* Round 10 down to the nearest multiple of 5 */
+	arg.value = 10;
+	significance.value = 5;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 10, res.value);
+
+	/* Round 100 down to the nearest multiple of 7 */
+	arg.value = 100;
+	significance.value = 7;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 98, res.value);
+
+	/* Round an integer down to its nearest multiple should return itself */
+	arg.value = MAX_I64;
+	significance.value = MAX_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	arg.value = MIN_I64;
+	significance.value = MIN_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MIN_I64, res.value);
+
+	/* Value is a multiple of significance, result should be value */
+	arg.value = MAX_I64;
+	significance.value = MIN_I64 + 1;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	/* Round 0 down to the nearest multiple of any number should return 0 */
+	arg.value = 0;
+	significance.value = MAX_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg.value = 0;
+	significance.value = MIN_I64;
+	res = bw_floor2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+/**
+ * bw_ceil2_test - KUnit test for bw_ceil2
+ * @test: represents a running instance of a test.
+ */
+static void bw_ceil2_test(struct kunit *test)
+{
+	struct bw_fixed arg;
+	struct bw_fixed significance;
+	struct bw_fixed res;
+
+	/* Round 10 up to the nearest multiple of 3 */
+	arg.value = 10;
+	significance.value = 3;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 12, res.value);
+
+	/* Round 10 up to the nearest multiple of 5 */
+	arg.value = 10;
+	significance.value = 5;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 10, res.value);
+
+	/* Round 100 up to the nearest multiple of 7 */
+	arg.value = 100;
+	significance.value = 7;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 105, res.value);
+
+	/* Round an integer up to its nearest multiple should return itself */
+	arg.value = MAX_I64;
+	significance.value = MAX_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	arg.value = MIN_I64 + 1;
+	significance.value = MIN_I64 + 1;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MIN_I64 + 1, res.value);
+
+	/* Value is a multiple of significance, result should be value */
+	arg.value = MAX_I64;
+	significance.value = MIN_I64 + 1;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, MAX_I64, res.value);
+
+	/* Round 0 up to the nearest multiple of any number should return 0 */
+	arg.value = 0;
+	significance.value = MAX_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg.value = 0;
+	significance.value = MIN_I64;
+	res = bw_ceil2(arg, significance);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+}
+
+/**
+ * bw_mul_test - KUnit test for bw_mul
+ * @test: represents a running instance of a test.
+ */
+static void bw_mul_test(struct kunit *test)
+{
+	struct bw_fixed arg1;
+	struct bw_fixed arg2;
+	struct bw_fixed res;
+	struct bw_fixed expected;
+
+	/* Extreme scenario */
+	arg1.value = MAX_I64;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+	/* Testing multiplication property: x * 1 = x */
+	arg1.value = 1;
+	arg2.value = MAX_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MAX_I32 + 1, res.value);
+
+	arg1.value = 1;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, BW_FIXED_MIN_I32, res.value);
+
+	/* Testing multiplication property: x * 0 = 0 */
+	arg1.value = 0;
+	arg2.value = 0;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg1.value = 0;
+	arg2.value = MAX_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	arg1.value = 0;
+	arg2.value = MIN_I64;
+	res = bw_mul(arg1, arg2);
+	KUNIT_EXPECT_EQ(test, 0, res.value);
+
+	/* Testing multiplication between integers */
+	res = bw_mul(bw_int_to_fixed(8), bw_int_to_fixed(10));
+	KUNIT_EXPECT_EQ(test, 1342177280LL, res.value); /* 0x50000000 */
+
+	res = bw_mul(bw_int_to_fixed(10), bw_int_to_fixed(5));
+	KUNIT_EXPECT_EQ(test, 838860800LL, res.value); /* 0x32000000 */
+
+	res = bw_mul(bw_int_to_fixed(-10), bw_int_to_fixed(7));
+	KUNIT_EXPECT_EQ(test, -1174405120LL, res.value); /* -0x46000000 */
+
+	/* Testing multiplication between fractions and integers */
+	res = bw_mul(bw_frc_to_fixed(4, 3), bw_int_to_fixed(3));
+	expected = bw_int_to_fixed(4);
+
+	/*
+	 * As bw_frc_to_fixed(4, 3) didn't round up the fixed-point representation,
+	 * the expected must be subtracted by 1.
+	 */
+	KUNIT_EXPECT_EQ(test, expected.value - 1, res.value);
+
+	res = bw_mul(bw_frc_to_fixed(5, 3), bw_int_to_fixed(3));
+	expected = bw_int_to_fixed(5);
+
+	/*
+	 * As bw_frc_to_fixed(5, 3) rounds up the fixed-point representation,
+	 * the expected must be added by 1.
+	 */
+	KUNIT_EXPECT_EQ(test, expected.value + 1, res.value);
+}
+
+static struct kunit_case bw_fixed_test_cases[] = {
+	KUNIT_CASE(abs_i64_test),
+	KUNIT_CASE(bw_int_to_fixed_nonconst_test),
+	KUNIT_CASE(bw_frc_to_fixed_test),
+	KUNIT_CASE(bw_floor2_test),
+	KUNIT_CASE(bw_ceil2_test),
+	KUNIT_CASE(bw_mul_test),
+	{  }
+};
+
+static struct kunit_suite bw_fixed_test_suite = {
+	.name = "dml_calcs_bw_fixed",
+	.test_cases = bw_fixed_test_cases,
+};
+
+kunit_test_suites(&bw_fixed_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 3/8] drm/amd/display: Introduce KUnit tests to display_rq_dlg_calc_20
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

From: Isabella Basso <isabbasso@riseup.net>

This adds tests to the bit encoding format verification functions on the
file. They're meant to be simpler so as to provide a proof of concept on
testing DML code.

Signed-off-by: Isabella Basso <isabbasso@riseup.net>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 ++
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c     |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   1 +
 .../dml/dcn20/display_rq_dlg_calc_20_test.c   | 124 ++++++++++++++++++
 4 files changed, 142 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index ce882a8c24f5..039227baedfa 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -67,6 +67,19 @@ config DCE_KUNIT_TEST
 
 		If unsure, say N.
 
+config DML_KUNIT_TEST
+	bool "Run all KUnit tests for DML" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC_DCN && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the Display Controller Engine. 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.
+
 config AMD_DC_BASICS_KUNIT_TEST
 	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
 	depends on DRM_AMD_DC && KUNIT
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 548cdef8a8ad..ab688c9ba0d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -1683,3 +1683,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
 		ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
 	}
 }
+
+#if IS_ENABLED(CONFIG_DML_KUNIT_TEST)
+#include "../../../tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index 7a58f75a8dfc..eb6f81601757 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -5,3 +5,4 @@ CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
 CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
 CONFIG_DCE_KUNIT_TEST=y
+CONFIG_DML_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
new file mode 100644
index 000000000000..e6d3e356205c
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/display_rq_dlg_calc_20.c
+ *
+ * Copyright (c) 2022, Isabella Basso <isabbasso@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_lib.h"
+
+/**
+ * get_bytes_per_element_test - KUnit test for get_bytes_per_element
+ * @test: represents a running instance of a test.
+ */
+static void get_bytes_per_element_test(struct kunit *test)
+{
+	/* last numbers should tell us the horizontal 4-element region binary
+	 * size N used for subsampling, thus giving us N/8 bytes per element
+	 */
+	/* note that 4:4:4 is not subsampled */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_16, false), 2);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_32, false), 4);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_64, false), 8);
+
+	/* dcn20 doesn't support bit depths over 10b */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_12, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_12, true), 0);
+
+	/* dm_444_XX are not dual plane */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_16, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_32, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_64, true), 0);
+
+	/* in the dm_42* values, last numbers specify bit depth, demanding we
+	 * treat chroma and luma channels separately
+	 */
+	/* thus we'll now have ceil(N/8) bytes for luma */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_8, false), 1);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_10, false), 2);
+	/* and double the luma value for accommodating blue and red chroma
+	 * channels
+	 */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_8, true), 2);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_10, true), 4);
+
+	/* monochrome encodings should mirror non-subsampled variants */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_8, false),
+			get_bytes_per_element(dm_444_8, false));
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_16, false),
+			get_bytes_per_element(dm_444_16, false));
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_16, true), 0);
+
+	/* dcn20 doesn't support 4:2:2 chroma subsampling */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_8, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_8, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_10, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_10, true), 0);
+
+	/* dcn20 doesn't support RGBE encodings */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe_alpha, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe_alpha, true), 0);
+
+	/* as in the first values, _8 here represents horizontal binary length */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_8, false), 1);
+	/* in a non-subsampled monochrome encoding chroma and luma should be the
+	 * same length
+	 */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_8, false),
+			get_bytes_per_element(dm_444_8, true));
+
+	/* as dm_mono_8 == dm_444_8, it must behave the same way */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_8, false),
+			get_bytes_per_element(dm_mono_8, true));
+}
+
+/**
+ * is_dual_plane_test - KUnit test for is_dual_plane
+ * @test: represents a running instance of a test.
+ */
+static void is_dual_plane_test(struct kunit *test)
+{
+	/* strictly speaking monochrome formats are not dual plane, but they're
+	 * included here for completeness
+	 */
+	int source_format_count = 11;
+
+	for (int i = 0; i < source_format_count; i++) {
+		/* dcn20 doesn't support other dual plane formats */
+		if (i == 3 || i == 4)
+			KUNIT_ASSERT_TRUE(test, is_dual_plane(i));
+		else
+			KUNIT_ASSERT_FALSE(test, is_dual_plane(i));
+	}
+}
+
+/**
+ * get_blk_size_bytes_test - KUnit test for get_blk_size_bytes
+ * @test: represents a running instance of a test.
+ */
+static void get_blk_size_bytes_test(struct kunit *test)
+{
+	/* corresponds to 4^4 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_256k_tile), 256 * 1024);
+	/* corresponds to 4^3 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_64k_tile), 64 * 1024);
+	/* corresponds to 4^1 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_4k_tile), 4 * 1024);
+}
+
+static struct kunit_case dcn20_rq_dlg_calc_20_test_cases[] = {
+	KUNIT_CASE(get_bytes_per_element_test),
+	KUNIT_CASE(is_dual_plane_test),
+	KUNIT_CASE(get_blk_size_bytes_test),
+	{  }
+};
+
+static struct kunit_suite dcn20_rq_dlg_calc_20_test_suite = {
+	.name = "display_rq_dlg_calc_20",
+	.test_cases = dcn20_rq_dlg_calc_20_test_cases,
+};
+
+kunit_test_suites(&dcn20_rq_dlg_calc_20_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 3/8] drm/amd/display: Introduce KUnit tests to display_rq_dlg_calc_20
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

From: Isabella Basso <isabbasso@riseup.net>

This adds tests to the bit encoding format verification functions on the
file. They're meant to be simpler so as to provide a proof of concept on
testing DML code.

Signed-off-by: Isabella Basso <isabbasso@riseup.net>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 ++
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c     |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   1 +
 .../dml/dcn20/display_rq_dlg_calc_20_test.c   | 124 ++++++++++++++++++
 4 files changed, 142 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index ce882a8c24f5..039227baedfa 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -67,6 +67,19 @@ config DCE_KUNIT_TEST
 
 		If unsure, say N.
 
+config DML_KUNIT_TEST
+	bool "Run all KUnit tests for DML" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC_DCN && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the Display Controller Engine. 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.
+
 config AMD_DC_BASICS_KUNIT_TEST
 	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
 	depends on DRM_AMD_DC && KUNIT
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 548cdef8a8ad..ab688c9ba0d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -1683,3 +1683,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
 		ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
 	}
 }
+
+#if IS_ENABLED(CONFIG_DML_KUNIT_TEST)
+#include "../../../tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index 7a58f75a8dfc..eb6f81601757 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -5,3 +5,4 @@ CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
 CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
 CONFIG_DCE_KUNIT_TEST=y
+CONFIG_DML_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
new file mode 100644
index 000000000000..e6d3e356205c
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/display_rq_dlg_calc_20.c
+ *
+ * Copyright (c) 2022, Isabella Basso <isabbasso@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_lib.h"
+
+/**
+ * get_bytes_per_element_test - KUnit test for get_bytes_per_element
+ * @test: represents a running instance of a test.
+ */
+static void get_bytes_per_element_test(struct kunit *test)
+{
+	/* last numbers should tell us the horizontal 4-element region binary
+	 * size N used for subsampling, thus giving us N/8 bytes per element
+	 */
+	/* note that 4:4:4 is not subsampled */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_16, false), 2);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_32, false), 4);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_64, false), 8);
+
+	/* dcn20 doesn't support bit depths over 10b */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_12, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_12, true), 0);
+
+	/* dm_444_XX are not dual plane */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_16, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_32, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_64, true), 0);
+
+	/* in the dm_42* values, last numbers specify bit depth, demanding we
+	 * treat chroma and luma channels separately
+	 */
+	/* thus we'll now have ceil(N/8) bytes for luma */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_8, false), 1);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_10, false), 2);
+	/* and double the luma value for accommodating blue and red chroma
+	 * channels
+	 */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_8, true), 2);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_10, true), 4);
+
+	/* monochrome encodings should mirror non-subsampled variants */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_8, false),
+			get_bytes_per_element(dm_444_8, false));
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_16, false),
+			get_bytes_per_element(dm_444_16, false));
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_16, true), 0);
+
+	/* dcn20 doesn't support 4:2:2 chroma subsampling */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_8, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_8, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_10, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_10, true), 0);
+
+	/* dcn20 doesn't support RGBE encodings */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe_alpha, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe_alpha, true), 0);
+
+	/* as in the first values, _8 here represents horizontal binary length */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_8, false), 1);
+	/* in a non-subsampled monochrome encoding chroma and luma should be the
+	 * same length
+	 */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_8, false),
+			get_bytes_per_element(dm_444_8, true));
+
+	/* as dm_mono_8 == dm_444_8, it must behave the same way */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_8, false),
+			get_bytes_per_element(dm_mono_8, true));
+}
+
+/**
+ * is_dual_plane_test - KUnit test for is_dual_plane
+ * @test: represents a running instance of a test.
+ */
+static void is_dual_plane_test(struct kunit *test)
+{
+	/* strictly speaking monochrome formats are not dual plane, but they're
+	 * included here for completeness
+	 */
+	int source_format_count = 11;
+
+	for (int i = 0; i < source_format_count; i++) {
+		/* dcn20 doesn't support other dual plane formats */
+		if (i == 3 || i == 4)
+			KUNIT_ASSERT_TRUE(test, is_dual_plane(i));
+		else
+			KUNIT_ASSERT_FALSE(test, is_dual_plane(i));
+	}
+}
+
+/**
+ * get_blk_size_bytes_test - KUnit test for get_blk_size_bytes
+ * @test: represents a running instance of a test.
+ */
+static void get_blk_size_bytes_test(struct kunit *test)
+{
+	/* corresponds to 4^4 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_256k_tile), 256 * 1024);
+	/* corresponds to 4^3 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_64k_tile), 64 * 1024);
+	/* corresponds to 4^1 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_4k_tile), 4 * 1024);
+}
+
+static struct kunit_case dcn20_rq_dlg_calc_20_test_cases[] = {
+	KUNIT_CASE(get_bytes_per_element_test),
+	KUNIT_CASE(is_dual_plane_test),
+	KUNIT_CASE(get_blk_size_bytes_test),
+	{  }
+};
+
+static struct kunit_suite dcn20_rq_dlg_calc_20_test_suite = {
+	.name = "display_rq_dlg_calc_20",
+	.test_cases = dcn20_rq_dlg_calc_20_test_cases,
+};
+
+kunit_test_suites(&dcn20_rq_dlg_calc_20_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 3/8] drm/amd/display: Introduce KUnit tests to display_rq_dlg_calc_20
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

From: Isabella Basso <isabbasso@riseup.net>

This adds tests to the bit encoding format verification functions on the
file. They're meant to be simpler so as to provide a proof of concept on
testing DML code.

Signed-off-by: Isabella Basso <isabbasso@riseup.net>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 ++
 .../dc/dml/dcn20/display_rq_dlg_calc_20.c     |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   1 +
 .../dml/dcn20/display_rq_dlg_calc_20_test.c   | 124 ++++++++++++++++++
 4 files changed, 142 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index ce882a8c24f5..039227baedfa 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -67,6 +67,19 @@ config DCE_KUNIT_TEST
 
 		If unsure, say N.
 
+config DML_KUNIT_TEST
+	bool "Run all KUnit tests for DML" if !KUNIT_ALL_TESTS
+	depends on DRM_AMD_DC_DCN && KUNIT
+	default KUNIT_ALL_TESTS
+	help
+		Enables unit tests for the Display Controller Engine. 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.
+
 config AMD_DC_BASICS_KUNIT_TEST
 	bool "Enable KUnit tests for the 'basics' sub-component of DAL" if !KUNIT_ALL_TESTS
 	depends on DRM_AMD_DC && KUNIT
diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
index 548cdef8a8ad..ab688c9ba0d1 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_rq_dlg_calc_20.c
@@ -1683,3 +1683,7 @@ static void calculate_ttu_cursor(struct display_mode_lib *mode_lib,
 		ASSERT(*refcyc_per_req_delivery_cur < dml_pow(2, 13));
 	}
 }
+
+#if IS_ENABLED(CONFIG_DML_KUNIT_TEST)
+#include "../../../tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index 7a58f75a8dfc..eb6f81601757 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -5,3 +5,4 @@ CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
 CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
 CONFIG_DCE_KUNIT_TEST=y
+CONFIG_DML_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
new file mode 100644
index 000000000000..e6d3e356205c
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_rq_dlg_calc_20_test.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/display_rq_dlg_calc_20.c
+ *
+ * Copyright (c) 2022, Isabella Basso <isabbasso@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_lib.h"
+
+/**
+ * get_bytes_per_element_test - KUnit test for get_bytes_per_element
+ * @test: represents a running instance of a test.
+ */
+static void get_bytes_per_element_test(struct kunit *test)
+{
+	/* last numbers should tell us the horizontal 4-element region binary
+	 * size N used for subsampling, thus giving us N/8 bytes per element
+	 */
+	/* note that 4:4:4 is not subsampled */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_16, false), 2);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_32, false), 4);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_64, false), 8);
+
+	/* dcn20 doesn't support bit depths over 10b */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_12, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_12, true), 0);
+
+	/* dm_444_XX are not dual plane */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_16, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_32, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_64, true), 0);
+
+	/* in the dm_42* values, last numbers specify bit depth, demanding we
+	 * treat chroma and luma channels separately
+	 */
+	/* thus we'll now have ceil(N/8) bytes for luma */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_8, false), 1);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_10, false), 2);
+	/* and double the luma value for accommodating blue and red chroma
+	 * channels
+	 */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_8, true), 2);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_420_10, true), 4);
+
+	/* monochrome encodings should mirror non-subsampled variants */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_8, false),
+			get_bytes_per_element(dm_444_8, false));
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_16, false),
+			get_bytes_per_element(dm_444_16, false));
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_16, true), 0);
+
+	/* dcn20 doesn't support 4:2:2 chroma subsampling */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_8, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_8, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_10, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_422_10, true), 0);
+
+	/* dcn20 doesn't support RGBE encodings */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe, true), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe_alpha, false), 0);
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_rgbe_alpha, true), 0);
+
+	/* as in the first values, _8 here represents horizontal binary length */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_8, false), 1);
+	/* in a non-subsampled monochrome encoding chroma and luma should be the
+	 * same length
+	 */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_444_8, false),
+			get_bytes_per_element(dm_444_8, true));
+
+	/* as dm_mono_8 == dm_444_8, it must behave the same way */
+	KUNIT_ASSERT_EQ(test, get_bytes_per_element(dm_mono_8, false),
+			get_bytes_per_element(dm_mono_8, true));
+}
+
+/**
+ * is_dual_plane_test - KUnit test for is_dual_plane
+ * @test: represents a running instance of a test.
+ */
+static void is_dual_plane_test(struct kunit *test)
+{
+	/* strictly speaking monochrome formats are not dual plane, but they're
+	 * included here for completeness
+	 */
+	int source_format_count = 11;
+
+	for (int i = 0; i < source_format_count; i++) {
+		/* dcn20 doesn't support other dual plane formats */
+		if (i == 3 || i == 4)
+			KUNIT_ASSERT_TRUE(test, is_dual_plane(i));
+		else
+			KUNIT_ASSERT_FALSE(test, is_dual_plane(i));
+	}
+}
+
+/**
+ * get_blk_size_bytes_test - KUnit test for get_blk_size_bytes
+ * @test: represents a running instance of a test.
+ */
+static void get_blk_size_bytes_test(struct kunit *test)
+{
+	/* corresponds to 4^4 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_256k_tile), 256 * 1024);
+	/* corresponds to 4^3 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_64k_tile), 64 * 1024);
+	/* corresponds to 4^1 kB tiles */
+	KUNIT_ASSERT_EQ(test, get_blk_size_bytes(dm_4k_tile), 4 * 1024);
+}
+
+static struct kunit_case dcn20_rq_dlg_calc_20_test_cases[] = {
+	KUNIT_CASE(get_bytes_per_element_test),
+	KUNIT_CASE(is_dual_plane_test),
+	KUNIT_CASE(get_blk_size_bytes_test),
+	{  }
+};
+
+static struct kunit_suite dcn20_rq_dlg_calc_20_test_suite = {
+	.name = "display_rq_dlg_calc_20",
+	.test_cases = dcn20_rq_dlg_calc_20_test_cases,
+};
+
+kunit_test_suites(&dcn20_rq_dlg_calc_20_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 4/8] drm/amd/display: Introduce KUnit tests to the display_mode_vba library
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

The display_mode_vba library deals with hundreds of display parameters
and sometimes does it in odd ways. The addition of unit tests intends to
assure the quality of the code delivered by HW engineers and, also make
it possible to refactor the code decreasing concerns about adding bugs
to the codebase.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/tests/Makefile    |   5 +
 .../tests/dc/dml/display_mode_vba_test.c      | 741 ++++++++++++++++++
 2 files changed, 746 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c

diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
index ef16497318e8..cc1e9edd38c3 100644
--- a/drivers/gpu/drm/amd/display/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -7,6 +7,11 @@ ifdef CONFIG_AMD_DC_BASICS_KUNIT_TEST
 	DC_TESTS += dc/basics/fixpt31_32_test.o
 endif
 
+ifdef CONFIG_DML_KUNIT_TEST
+	CFLAGS_$(AMDDALPATH)/tests/dc/dml/display_mode_vba_test.o := $(dml_ccflags)
+	DC_TESTS += dc/dml/display_mode_vba_test.o
+endif
+
 AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_DC_TESTS)
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c
new file mode 100644
index 000000000000..d3e3a9f50c3d
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c
@@ -0,0 +1,741 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/display_mode_vba.h
+ *
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_lib.h"
+
+struct pixel_clock_adjustment_for_progressive_to_interlace_unit_expected {
+	const double pixel_clock[DC__NUM_DPP__MAX];
+	const double pixel_clock_backend[DC__NUM_DPP__MAX];
+};
+
+struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case {
+	const char *desc;
+	const unsigned int number_of_active_planes;
+	const bool interlace[DC__NUM_DPP__MAX];
+	const bool progressive_to_interlace_unit_in_OPP;
+	const double pixel_clock[DC__NUM_DPP__MAX];
+	const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_expected expected;
+};
+
+struct calculate_256B_block_sizes_test_case {
+	const char *desc;
+	const enum source_format_class source_pixel_format;
+	const enum dm_swizzle_mode surface_tiling;
+	const unsigned int byte_per_pixel_Y;
+	const unsigned int byte_per_pixel_C;
+	const unsigned int block_height_256_bytes_Y;
+	const unsigned int block_height_256_bytes_C;
+	const unsigned int block_width_256_bytes_Y;
+	const unsigned int block_width_256_bytes_C;
+};
+
+struct calculate_write_back_DISPCLK_test_case {
+	const char *desc;
+	const enum source_format_class writeback_pixel_format;
+	const double pixel_clock;
+	const double writeback_HRatio;
+	const double writeback_VRatio;
+	const unsigned int writeback_luma_HTaps;
+	const unsigned int writeback_luma_VTaps;
+	const unsigned int writeback_chroma_HTaps;
+	const unsigned int writeback_chroma_VTaps;
+	const double writeback_destination_width;
+	const unsigned int HTotal;
+	const unsigned int writeback_chroma_line_buffer_width;
+	const double calculate_write_back_DISPCLK;
+};
+
+/**
+ * pclk_adjustment_for_progressive_to_interlace_unit_test - KUnit test
+ * for PixelClockAdjustmentForProgressiveToInterlaceUnit
+ * @test: represents a running instance of a test.
+ */
+static void pclk_adjustment_for_progressive_to_interlace_unit_test(struct kunit *test)
+{
+	const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case
+		*test_param = test->param_value;
+	struct display_mode_lib *mode_lib;
+	size_t pixel_clock_size = DC__NUM_DPP__MAX * sizeof(const double);
+	size_t interlace_size = DC__NUM_DPP__MAX * sizeof(const bool);
+
+	mode_lib = kunit_kzalloc(test, sizeof(struct display_mode_lib),
+				 GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode_lib);
+
+	mode_lib->vba.NumberOfActivePlanes = test_param->number_of_active_planes;
+	memcpy(mode_lib->vba.Interlace, test_param->interlace, interlace_size);
+	mode_lib->vba.ProgressiveToInterlaceUnitInOPP =
+		test_param->progressive_to_interlace_unit_in_OPP;
+	memcpy(mode_lib->vba.PixelClock, test_param->pixel_clock, pixel_clock_size);
+
+	PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
+
+	KUNIT_EXPECT_TRUE(test, !memcmp(mode_lib->vba.PixelClock,
+					test_param->expected.pixel_clock,
+					pixel_clock_size));
+	KUNIT_EXPECT_TRUE(test, !memcmp(mode_lib->vba.PixelClockBackEnd,
+					test_param->expected.pixel_clock_backend,
+					pixel_clock_size));
+}
+
+/**
+ * calculate_256B_block_sizes_test - KUnit test for Calculate256BBlockSizes
+ * @test: represents a running instance of a test.
+ */
+static void calculate_256B_block_sizes_test(struct kunit *test)
+{
+	const struct calculate_256B_block_sizes_test_case *test_param =
+		test->param_value;
+	unsigned int *block_height_256_bytes_Y, *block_height_256_bytes_C;
+	unsigned int *block_width_256_bytes_Y, *block_width_256_bytes_C;
+
+	block_height_256_bytes_Y = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_height_256_bytes_Y);
+
+	block_height_256_bytes_C = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_height_256_bytes_C);
+
+	block_width_256_bytes_Y = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_width_256_bytes_Y);
+
+	block_width_256_bytes_C = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_width_256_bytes_C);
+
+	Calculate256BBlockSizes(test_param->source_pixel_format,
+				test_param->surface_tiling,
+				test_param->byte_per_pixel_Y,
+				test_param->byte_per_pixel_C,
+				block_height_256_bytes_Y,
+				block_height_256_bytes_C,
+				block_width_256_bytes_Y,
+				block_width_256_bytes_C);
+
+	KUNIT_EXPECT_EQ(test, *block_height_256_bytes_Y,
+			test_param->block_height_256_bytes_Y);
+	KUNIT_EXPECT_EQ(test, *block_height_256_bytes_C,
+			test_param->block_height_256_bytes_C);
+	KUNIT_EXPECT_EQ(test, *block_width_256_bytes_Y,
+			test_param->block_width_256_bytes_Y);
+	KUNIT_EXPECT_EQ(test, *block_width_256_bytes_C,
+			test_param->block_width_256_bytes_C);
+}
+
+/**
+ * calculate_min_and_max_prefetch_mode_test - KUnit test for CalculateMinAndMaxPrefetchMode
+ * @test: represents a running instance of a test.
+ */
+static void calculate_min_and_max_prefetch_mode_test(struct kunit *test)
+{
+	unsigned int *min_prefetch_mode, *max_prefetch_mode;
+
+	min_prefetch_mode = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, min_prefetch_mode);
+
+	max_prefetch_mode = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, max_prefetch_mode);
+
+	/* Try to allow DRAM self-refresh and MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_try_to_allow_self_refresh_and_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+
+	/* Allow DRAM self-refresh and MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_allow_self_refresh_and_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 0);
+
+	/* Allow only DRAM self-refresh  */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_allow_self_refresh,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 1);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 1);
+
+	/* Allow neither DRAM self-refresh nor MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_neither_self_refresh_nor_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 2);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+
+	/* Invalid self-refresh affinity */
+	KUNIT_EXPECT_TRUE(test, CalculateMinAndMaxPrefetchMode(-1,
+							       min_prefetch_mode,
+							       max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+}
+
+/**
+ * calculate_write_back_DISPCLK_test - KUnit test for CalculateWriteBackDISPCLK
+ * @test: represents a running instance of a test.
+ */
+static void calculate_write_back_DISPCLK_test(struct kunit *test)
+{
+	const struct calculate_write_back_DISPCLK_test_case *test_param = test->param_value;
+	double calculate_write_back_DISPCLK;
+
+	DC_FP_START();
+	calculate_write_back_DISPCLK = CalculateWriteBackDISPCLK
+		(test_param->writeback_pixel_format,
+		 test_param->pixel_clock, test_param->writeback_HRatio,
+		 test_param->writeback_VRatio, test_param->writeback_luma_HTaps,
+		 test_param->writeback_luma_VTaps, test_param->writeback_chroma_HTaps,
+		 test_param->writeback_chroma_VTaps,
+		 test_param->writeback_destination_width, test_param->HTotal,
+		 test_param->writeback_chroma_line_buffer_width);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->calculate_write_back_DISPCLK,
+			calculate_write_back_DISPCLK);
+}
+
+static const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case
+pixel_clock_adjustment_for_progressive_to_interlace_unit_cases[] = {
+	{
+		.desc = "No active planes",
+		.number_of_active_planes = 0,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Two active planes with no interlaced output",
+		.number_of_active_planes = 2,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00,
+				0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Three active planes with one interlaced plane",
+		.number_of_active_planes = 3,
+		.interlace = {false, true, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 2720.00, 400.00, 0.00,
+				0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 0.00,
+				0.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Five active planes with three interlaced planes",
+		.number_of_active_planes = 5,
+		.interlace = {false, true, false, true, true, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 2720.00, 400.00, 680.00,
+				1360.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with five interlaced planes",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, false, true, true, false, true, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {6400.00, 2720.00, 400.00, 680.00,
+				1360.00, 1360.00, 5440.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.0},
+		},
+	},
+	{
+		.desc = "Eight active planes with all planes interlaced",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, true, true, true, true, true, true},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {6400.00, 2720.00, 800.0, 680.00,
+				1360.00, 2720.00, 5440.0, 680.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with no interlaced plane",
+		.number_of_active_planes = 8,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with no progressive_to_interlace_unit_in_OPP",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, true, true, true, true, true, true},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+};
+
+static const struct calculate_256B_block_sizes_test_case calculate_256B_block_sizes_cases[] = {
+	/*
+	 * Here 16-bit specifies the number of bits in the horizontal 4-element region
+	 * used for subsampling
+	 */
+	{
+		.desc = "4:4:4 16-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_16,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 128,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 16-bit encoding with 256B standard swizzle",
+		.source_pixel_format = dm_444_16,
+		.surface_tiling = dm_sw_256b_s,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	/*
+	 * Here 32-bit specifies the number of bits in the horizontal
+	 * 4-element region used for subsampling
+	 */
+	{
+		.desc = "4:4:4 32-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_32,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 4,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 64,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 32-bit encoding with 256B display swizzle",
+		.source_pixel_format = dm_444_32,
+		.surface_tiling = dm_sw_256b_d,
+		.byte_per_pixel_Y = 4,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 8,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	/*
+	 * Here 64-bit specifies the number of bits in the horizontal 4-element region
+	 * used for subsampling
+	 */
+	{
+		.desc = "4:4:4 64-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_64,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 8,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 32,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 64-bit encoding with 4KB standard swizzle",
+		.source_pixel_format = dm_444_64,
+		.surface_tiling = dm_sw_4kb_s,
+		.byte_per_pixel_Y = 8,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 4,
+		.block_width_256_bytes_Y = 8,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 8-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 8-bit encoding with 4KB display swizzle",
+		.source_pixel_format = dm_444_8,
+		.surface_tiling = dm_sw_4kb_d,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit mono encoding with linear swizzle",
+		.source_pixel_format = dm_mono_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit mono encoding with 64KB standard swizzle",
+		.source_pixel_format = dm_mono_8,
+		.surface_tiling = dm_sw_64kb_s,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "16-bit mono encoding with linear swizzle",
+		.source_pixel_format = dm_mono_16,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 128,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "16-bit mono encoding with 64KB display swizzle",
+		.source_pixel_format = dm_mono_16,
+		.surface_tiling = dm_sw_64kb_d,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit 4:2:0 encoding with linear swizzle",
+		.source_pixel_format = dm_420_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 2,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 1,
+		.block_width_256_bytes_C = 128,
+	},
+	{
+		.desc = "8-bit 4:2:0 encoding with VAR standard swizzle",
+		.source_pixel_format = dm_420_8,
+		.surface_tiling = dm_sw_var_s,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 2,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 8,
+		.block_width_256_bytes_C = 16,
+	},
+	{
+		.desc = "10-bit 4:2:0 encoding with linear swizzle",
+		.source_pixel_format = dm_420_10,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 4.0 / 3.0,
+		.byte_per_pixel_C = 8.0 / 3.0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 1,
+		.block_width_256_bytes_C = 128,
+	},
+	{
+		.desc = "10-bit 4:2:0 encoding with VAR display swizzle",
+		.source_pixel_format = dm_420_10,
+		.surface_tiling = dm_sw_var_d,
+		.byte_per_pixel_Y = 4.0 / 3.0,
+		.byte_per_pixel_C = 8.0 / 3.0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 32,
+		.block_height_256_bytes_C = 8,
+		.block_width_256_bytes_C = 16,
+	},
+};
+
+static const struct calculate_write_back_DISPCLK_test_case calculate_write_back_DISPCLK_cases[] = {
+	{
+		.desc = "Trivial test",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 0.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0,
+	},
+	{
+		.desc = "Simple Writeback Ratio",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1800.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.e7c6a11ep+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1360.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.5766666666666p+11,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 2720.72,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.ba5e02226985ep+12,
+	},
+	{
+		.desc = "No Writeback to Luma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1800.66,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.85b6dabefdfd9p+11,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing pixel clock",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 400.756,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.4bb8ddb60f598p+10,
+	},
+	{
+		.desc = "Increase numeric error by increasing pixel clock",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 3200.8,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 2,
+		.writeback_chroma_VTaps = 2,
+		.writeback_destination_width = 1686.7,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.847ced698147bp+12,
+	},
+	{
+		.desc = "Simple Writeback Ratio for 4:4:4 8-bit encoding",
+		.writeback_pixel_format = dm_444_8,
+		.pixel_clock = 1800.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.24aa62p+12,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps for 4:4:4 64-bit encoding",
+		.writeback_pixel_format = dm_444_64,
+		.pixel_clock = 1360.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.576666p+11,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps for 4:2:0 8-bit encoding",
+		.writeback_pixel_format = dm_420_8,
+		.pixel_clock = 2720.72,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 8,
+		.writeback_luma_VTaps = 8,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 1333.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 5,
+		.calculate_write_back_DISPCLK = 0x1.717f8p+12,
+	},
+	{
+		.desc = "No Writeback to Luma Taps for 4:2:0 10-bit encoding",
+		.writeback_pixel_format = dm_420_10,
+		.pixel_clock = 1800.66,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 996.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.43767ep+10,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing pixel clock for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.pixel_clock = 340.456,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1181,
+		.writeback_chroma_line_buffer_width = 3,
+		.calculate_write_back_DISPCLK = 0x1.067b3p+10,
+	},
+	{
+		.desc = "Increase numeric error by increasing pixel clock for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.pixel_clock = 4000.92,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 3,
+		.writeback_luma_VTaps = 3,
+		.writeback_chroma_HTaps = 2,
+		.writeback_chroma_VTaps = 2,
+		.writeback_destination_width = 1686.7,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.84b5b8p+12,
+	},
+};
+
+static void pixel_clock_adjustment_for_progressive_to_interlace_unit_test_to_desc
+(const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case *t,
+	char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(pixel_clock_adjustment_for_progressive_to_interlace_unit,
+		  pixel_clock_adjustment_for_progressive_to_interlace_unit_cases,
+		  pixel_clock_adjustment_for_progressive_to_interlace_unit_test_to_desc);
+
+static void calculate_256B_block_sizes_test_to_desc
+(const struct calculate_256B_block_sizes_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_256B_block_sizes, calculate_256B_block_sizes_cases,
+		  calculate_256B_block_sizes_test_to_desc);
+
+static void calculate_write_back_DISPCLK_test_to_desc(const struct
+		calculate_write_back_DISPCLK_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_write_back_DISPCLK, calculate_write_back_DISPCLK_cases,
+		  calculate_write_back_DISPCLK_test_to_desc);
+
+static struct kunit_case display_mode_vba_test_cases[] = {
+	KUNIT_CASE_PARAM(pclk_adjustment_for_progressive_to_interlace_unit_test,
+			 pixel_clock_adjustment_for_progressive_to_interlace_unit_gen_params),
+	KUNIT_CASE_PARAM(calculate_256B_block_sizes_test,
+			 calculate_256B_block_sizes_gen_params),
+	KUNIT_CASE(calculate_min_and_max_prefetch_mode_test),
+	KUNIT_CASE_PARAM(calculate_write_back_DISPCLK_test,
+			 calculate_write_back_DISPCLK_gen_params),
+	{}
+};
+
+static struct kunit_suite display_mode_vba_test_suite = {
+	.name = "dml_display_mode_vba",
+	.test_cases = display_mode_vba_test_cases,
+};
+
+kunit_test_suite(display_mode_vba_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 4/8] drm/amd/display: Introduce KUnit tests to the display_mode_vba library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

The display_mode_vba library deals with hundreds of display parameters
and sometimes does it in odd ways. The addition of unit tests intends to
assure the quality of the code delivered by HW engineers and, also make
it possible to refactor the code decreasing concerns about adding bugs
to the codebase.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/tests/Makefile    |   5 +
 .../tests/dc/dml/display_mode_vba_test.c      | 741 ++++++++++++++++++
 2 files changed, 746 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c

diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
index ef16497318e8..cc1e9edd38c3 100644
--- a/drivers/gpu/drm/amd/display/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -7,6 +7,11 @@ ifdef CONFIG_AMD_DC_BASICS_KUNIT_TEST
 	DC_TESTS += dc/basics/fixpt31_32_test.o
 endif
 
+ifdef CONFIG_DML_KUNIT_TEST
+	CFLAGS_$(AMDDALPATH)/tests/dc/dml/display_mode_vba_test.o := $(dml_ccflags)
+	DC_TESTS += dc/dml/display_mode_vba_test.o
+endif
+
 AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_DC_TESTS)
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c
new file mode 100644
index 000000000000..d3e3a9f50c3d
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c
@@ -0,0 +1,741 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/display_mode_vba.h
+ *
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_lib.h"
+
+struct pixel_clock_adjustment_for_progressive_to_interlace_unit_expected {
+	const double pixel_clock[DC__NUM_DPP__MAX];
+	const double pixel_clock_backend[DC__NUM_DPP__MAX];
+};
+
+struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case {
+	const char *desc;
+	const unsigned int number_of_active_planes;
+	const bool interlace[DC__NUM_DPP__MAX];
+	const bool progressive_to_interlace_unit_in_OPP;
+	const double pixel_clock[DC__NUM_DPP__MAX];
+	const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_expected expected;
+};
+
+struct calculate_256B_block_sizes_test_case {
+	const char *desc;
+	const enum source_format_class source_pixel_format;
+	const enum dm_swizzle_mode surface_tiling;
+	const unsigned int byte_per_pixel_Y;
+	const unsigned int byte_per_pixel_C;
+	const unsigned int block_height_256_bytes_Y;
+	const unsigned int block_height_256_bytes_C;
+	const unsigned int block_width_256_bytes_Y;
+	const unsigned int block_width_256_bytes_C;
+};
+
+struct calculate_write_back_DISPCLK_test_case {
+	const char *desc;
+	const enum source_format_class writeback_pixel_format;
+	const double pixel_clock;
+	const double writeback_HRatio;
+	const double writeback_VRatio;
+	const unsigned int writeback_luma_HTaps;
+	const unsigned int writeback_luma_VTaps;
+	const unsigned int writeback_chroma_HTaps;
+	const unsigned int writeback_chroma_VTaps;
+	const double writeback_destination_width;
+	const unsigned int HTotal;
+	const unsigned int writeback_chroma_line_buffer_width;
+	const double calculate_write_back_DISPCLK;
+};
+
+/**
+ * pclk_adjustment_for_progressive_to_interlace_unit_test - KUnit test
+ * for PixelClockAdjustmentForProgressiveToInterlaceUnit
+ * @test: represents a running instance of a test.
+ */
+static void pclk_adjustment_for_progressive_to_interlace_unit_test(struct kunit *test)
+{
+	const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case
+		*test_param = test->param_value;
+	struct display_mode_lib *mode_lib;
+	size_t pixel_clock_size = DC__NUM_DPP__MAX * sizeof(const double);
+	size_t interlace_size = DC__NUM_DPP__MAX * sizeof(const bool);
+
+	mode_lib = kunit_kzalloc(test, sizeof(struct display_mode_lib),
+				 GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode_lib);
+
+	mode_lib->vba.NumberOfActivePlanes = test_param->number_of_active_planes;
+	memcpy(mode_lib->vba.Interlace, test_param->interlace, interlace_size);
+	mode_lib->vba.ProgressiveToInterlaceUnitInOPP =
+		test_param->progressive_to_interlace_unit_in_OPP;
+	memcpy(mode_lib->vba.PixelClock, test_param->pixel_clock, pixel_clock_size);
+
+	PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
+
+	KUNIT_EXPECT_TRUE(test, !memcmp(mode_lib->vba.PixelClock,
+					test_param->expected.pixel_clock,
+					pixel_clock_size));
+	KUNIT_EXPECT_TRUE(test, !memcmp(mode_lib->vba.PixelClockBackEnd,
+					test_param->expected.pixel_clock_backend,
+					pixel_clock_size));
+}
+
+/**
+ * calculate_256B_block_sizes_test - KUnit test for Calculate256BBlockSizes
+ * @test: represents a running instance of a test.
+ */
+static void calculate_256B_block_sizes_test(struct kunit *test)
+{
+	const struct calculate_256B_block_sizes_test_case *test_param =
+		test->param_value;
+	unsigned int *block_height_256_bytes_Y, *block_height_256_bytes_C;
+	unsigned int *block_width_256_bytes_Y, *block_width_256_bytes_C;
+
+	block_height_256_bytes_Y = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_height_256_bytes_Y);
+
+	block_height_256_bytes_C = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_height_256_bytes_C);
+
+	block_width_256_bytes_Y = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_width_256_bytes_Y);
+
+	block_width_256_bytes_C = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_width_256_bytes_C);
+
+	Calculate256BBlockSizes(test_param->source_pixel_format,
+				test_param->surface_tiling,
+				test_param->byte_per_pixel_Y,
+				test_param->byte_per_pixel_C,
+				block_height_256_bytes_Y,
+				block_height_256_bytes_C,
+				block_width_256_bytes_Y,
+				block_width_256_bytes_C);
+
+	KUNIT_EXPECT_EQ(test, *block_height_256_bytes_Y,
+			test_param->block_height_256_bytes_Y);
+	KUNIT_EXPECT_EQ(test, *block_height_256_bytes_C,
+			test_param->block_height_256_bytes_C);
+	KUNIT_EXPECT_EQ(test, *block_width_256_bytes_Y,
+			test_param->block_width_256_bytes_Y);
+	KUNIT_EXPECT_EQ(test, *block_width_256_bytes_C,
+			test_param->block_width_256_bytes_C);
+}
+
+/**
+ * calculate_min_and_max_prefetch_mode_test - KUnit test for CalculateMinAndMaxPrefetchMode
+ * @test: represents a running instance of a test.
+ */
+static void calculate_min_and_max_prefetch_mode_test(struct kunit *test)
+{
+	unsigned int *min_prefetch_mode, *max_prefetch_mode;
+
+	min_prefetch_mode = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, min_prefetch_mode);
+
+	max_prefetch_mode = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, max_prefetch_mode);
+
+	/* Try to allow DRAM self-refresh and MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_try_to_allow_self_refresh_and_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+
+	/* Allow DRAM self-refresh and MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_allow_self_refresh_and_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 0);
+
+	/* Allow only DRAM self-refresh  */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_allow_self_refresh,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 1);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 1);
+
+	/* Allow neither DRAM self-refresh nor MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_neither_self_refresh_nor_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 2);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+
+	/* Invalid self-refresh affinity */
+	KUNIT_EXPECT_TRUE(test, CalculateMinAndMaxPrefetchMode(-1,
+							       min_prefetch_mode,
+							       max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+}
+
+/**
+ * calculate_write_back_DISPCLK_test - KUnit test for CalculateWriteBackDISPCLK
+ * @test: represents a running instance of a test.
+ */
+static void calculate_write_back_DISPCLK_test(struct kunit *test)
+{
+	const struct calculate_write_back_DISPCLK_test_case *test_param = test->param_value;
+	double calculate_write_back_DISPCLK;
+
+	DC_FP_START();
+	calculate_write_back_DISPCLK = CalculateWriteBackDISPCLK
+		(test_param->writeback_pixel_format,
+		 test_param->pixel_clock, test_param->writeback_HRatio,
+		 test_param->writeback_VRatio, test_param->writeback_luma_HTaps,
+		 test_param->writeback_luma_VTaps, test_param->writeback_chroma_HTaps,
+		 test_param->writeback_chroma_VTaps,
+		 test_param->writeback_destination_width, test_param->HTotal,
+		 test_param->writeback_chroma_line_buffer_width);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->calculate_write_back_DISPCLK,
+			calculate_write_back_DISPCLK);
+}
+
+static const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case
+pixel_clock_adjustment_for_progressive_to_interlace_unit_cases[] = {
+	{
+		.desc = "No active planes",
+		.number_of_active_planes = 0,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Two active planes with no interlaced output",
+		.number_of_active_planes = 2,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00,
+				0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Three active planes with one interlaced plane",
+		.number_of_active_planes = 3,
+		.interlace = {false, true, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 2720.00, 400.00, 0.00,
+				0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 0.00,
+				0.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Five active planes with three interlaced planes",
+		.number_of_active_planes = 5,
+		.interlace = {false, true, false, true, true, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 2720.00, 400.00, 680.00,
+				1360.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with five interlaced planes",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, false, true, true, false, true, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {6400.00, 2720.00, 400.00, 680.00,
+				1360.00, 1360.00, 5440.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.0},
+		},
+	},
+	{
+		.desc = "Eight active planes with all planes interlaced",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, true, true, true, true, true, true},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {6400.00, 2720.00, 800.0, 680.00,
+				1360.00, 2720.00, 5440.0, 680.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with no interlaced plane",
+		.number_of_active_planes = 8,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with no progressive_to_interlace_unit_in_OPP",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, true, true, true, true, true, true},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+};
+
+static const struct calculate_256B_block_sizes_test_case calculate_256B_block_sizes_cases[] = {
+	/*
+	 * Here 16-bit specifies the number of bits in the horizontal 4-element region
+	 * used for subsampling
+	 */
+	{
+		.desc = "4:4:4 16-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_16,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 128,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 16-bit encoding with 256B standard swizzle",
+		.source_pixel_format = dm_444_16,
+		.surface_tiling = dm_sw_256b_s,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	/*
+	 * Here 32-bit specifies the number of bits in the horizontal
+	 * 4-element region used for subsampling
+	 */
+	{
+		.desc = "4:4:4 32-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_32,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 4,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 64,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 32-bit encoding with 256B display swizzle",
+		.source_pixel_format = dm_444_32,
+		.surface_tiling = dm_sw_256b_d,
+		.byte_per_pixel_Y = 4,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 8,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	/*
+	 * Here 64-bit specifies the number of bits in the horizontal 4-element region
+	 * used for subsampling
+	 */
+	{
+		.desc = "4:4:4 64-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_64,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 8,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 32,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 64-bit encoding with 4KB standard swizzle",
+		.source_pixel_format = dm_444_64,
+		.surface_tiling = dm_sw_4kb_s,
+		.byte_per_pixel_Y = 8,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 4,
+		.block_width_256_bytes_Y = 8,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 8-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 8-bit encoding with 4KB display swizzle",
+		.source_pixel_format = dm_444_8,
+		.surface_tiling = dm_sw_4kb_d,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit mono encoding with linear swizzle",
+		.source_pixel_format = dm_mono_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit mono encoding with 64KB standard swizzle",
+		.source_pixel_format = dm_mono_8,
+		.surface_tiling = dm_sw_64kb_s,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "16-bit mono encoding with linear swizzle",
+		.source_pixel_format = dm_mono_16,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 128,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "16-bit mono encoding with 64KB display swizzle",
+		.source_pixel_format = dm_mono_16,
+		.surface_tiling = dm_sw_64kb_d,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit 4:2:0 encoding with linear swizzle",
+		.source_pixel_format = dm_420_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 2,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 1,
+		.block_width_256_bytes_C = 128,
+	},
+	{
+		.desc = "8-bit 4:2:0 encoding with VAR standard swizzle",
+		.source_pixel_format = dm_420_8,
+		.surface_tiling = dm_sw_var_s,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 2,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 8,
+		.block_width_256_bytes_C = 16,
+	},
+	{
+		.desc = "10-bit 4:2:0 encoding with linear swizzle",
+		.source_pixel_format = dm_420_10,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 4.0 / 3.0,
+		.byte_per_pixel_C = 8.0 / 3.0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 1,
+		.block_width_256_bytes_C = 128,
+	},
+	{
+		.desc = "10-bit 4:2:0 encoding with VAR display swizzle",
+		.source_pixel_format = dm_420_10,
+		.surface_tiling = dm_sw_var_d,
+		.byte_per_pixel_Y = 4.0 / 3.0,
+		.byte_per_pixel_C = 8.0 / 3.0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 32,
+		.block_height_256_bytes_C = 8,
+		.block_width_256_bytes_C = 16,
+	},
+};
+
+static const struct calculate_write_back_DISPCLK_test_case calculate_write_back_DISPCLK_cases[] = {
+	{
+		.desc = "Trivial test",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 0.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0,
+	},
+	{
+		.desc = "Simple Writeback Ratio",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1800.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.e7c6a11ep+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1360.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.5766666666666p+11,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 2720.72,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.ba5e02226985ep+12,
+	},
+	{
+		.desc = "No Writeback to Luma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1800.66,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.85b6dabefdfd9p+11,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing pixel clock",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 400.756,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.4bb8ddb60f598p+10,
+	},
+	{
+		.desc = "Increase numeric error by increasing pixel clock",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 3200.8,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 2,
+		.writeback_chroma_VTaps = 2,
+		.writeback_destination_width = 1686.7,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.847ced698147bp+12,
+	},
+	{
+		.desc = "Simple Writeback Ratio for 4:4:4 8-bit encoding",
+		.writeback_pixel_format = dm_444_8,
+		.pixel_clock = 1800.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.24aa62p+12,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps for 4:4:4 64-bit encoding",
+		.writeback_pixel_format = dm_444_64,
+		.pixel_clock = 1360.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.576666p+11,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps for 4:2:0 8-bit encoding",
+		.writeback_pixel_format = dm_420_8,
+		.pixel_clock = 2720.72,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 8,
+		.writeback_luma_VTaps = 8,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 1333.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 5,
+		.calculate_write_back_DISPCLK = 0x1.717f8p+12,
+	},
+	{
+		.desc = "No Writeback to Luma Taps for 4:2:0 10-bit encoding",
+		.writeback_pixel_format = dm_420_10,
+		.pixel_clock = 1800.66,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 996.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.43767ep+10,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing pixel clock for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.pixel_clock = 340.456,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1181,
+		.writeback_chroma_line_buffer_width = 3,
+		.calculate_write_back_DISPCLK = 0x1.067b3p+10,
+	},
+	{
+		.desc = "Increase numeric error by increasing pixel clock for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.pixel_clock = 4000.92,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 3,
+		.writeback_luma_VTaps = 3,
+		.writeback_chroma_HTaps = 2,
+		.writeback_chroma_VTaps = 2,
+		.writeback_destination_width = 1686.7,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.84b5b8p+12,
+	},
+};
+
+static void pixel_clock_adjustment_for_progressive_to_interlace_unit_test_to_desc
+(const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case *t,
+	char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(pixel_clock_adjustment_for_progressive_to_interlace_unit,
+		  pixel_clock_adjustment_for_progressive_to_interlace_unit_cases,
+		  pixel_clock_adjustment_for_progressive_to_interlace_unit_test_to_desc);
+
+static void calculate_256B_block_sizes_test_to_desc
+(const struct calculate_256B_block_sizes_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_256B_block_sizes, calculate_256B_block_sizes_cases,
+		  calculate_256B_block_sizes_test_to_desc);
+
+static void calculate_write_back_DISPCLK_test_to_desc(const struct
+		calculate_write_back_DISPCLK_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_write_back_DISPCLK, calculate_write_back_DISPCLK_cases,
+		  calculate_write_back_DISPCLK_test_to_desc);
+
+static struct kunit_case display_mode_vba_test_cases[] = {
+	KUNIT_CASE_PARAM(pclk_adjustment_for_progressive_to_interlace_unit_test,
+			 pixel_clock_adjustment_for_progressive_to_interlace_unit_gen_params),
+	KUNIT_CASE_PARAM(calculate_256B_block_sizes_test,
+			 calculate_256B_block_sizes_gen_params),
+	KUNIT_CASE(calculate_min_and_max_prefetch_mode_test),
+	KUNIT_CASE_PARAM(calculate_write_back_DISPCLK_test,
+			 calculate_write_back_DISPCLK_gen_params),
+	{}
+};
+
+static struct kunit_suite display_mode_vba_test_suite = {
+	.name = "dml_display_mode_vba",
+	.test_cases = display_mode_vba_test_cases,
+};
+
+kunit_test_suite(display_mode_vba_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 4/8] drm/amd/display: Introduce KUnit tests to the display_mode_vba library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

The display_mode_vba library deals with hundreds of display parameters
and sometimes does it in odd ways. The addition of unit tests intends to
assure the quality of the code delivered by HW engineers and, also make
it possible to refactor the code decreasing concerns about adding bugs
to the codebase.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/tests/Makefile    |   5 +
 .../tests/dc/dml/display_mode_vba_test.c      | 741 ++++++++++++++++++
 2 files changed, 746 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c

diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
index ef16497318e8..cc1e9edd38c3 100644
--- a/drivers/gpu/drm/amd/display/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -7,6 +7,11 @@ ifdef CONFIG_AMD_DC_BASICS_KUNIT_TEST
 	DC_TESTS += dc/basics/fixpt31_32_test.o
 endif
 
+ifdef CONFIG_DML_KUNIT_TEST
+	CFLAGS_$(AMDDALPATH)/tests/dc/dml/display_mode_vba_test.o := $(dml_ccflags)
+	DC_TESTS += dc/dml/display_mode_vba_test.o
+endif
+
 AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
 
 AMD_DISPLAY_FILES += $(AMD_DAL_DC_TESTS)
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c
new file mode 100644
index 000000000000..d3e3a9f50c3d
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/display_mode_vba_test.c
@@ -0,0 +1,741 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/display_mode_vba.h
+ *
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_lib.h"
+
+struct pixel_clock_adjustment_for_progressive_to_interlace_unit_expected {
+	const double pixel_clock[DC__NUM_DPP__MAX];
+	const double pixel_clock_backend[DC__NUM_DPP__MAX];
+};
+
+struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case {
+	const char *desc;
+	const unsigned int number_of_active_planes;
+	const bool interlace[DC__NUM_DPP__MAX];
+	const bool progressive_to_interlace_unit_in_OPP;
+	const double pixel_clock[DC__NUM_DPP__MAX];
+	const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_expected expected;
+};
+
+struct calculate_256B_block_sizes_test_case {
+	const char *desc;
+	const enum source_format_class source_pixel_format;
+	const enum dm_swizzle_mode surface_tiling;
+	const unsigned int byte_per_pixel_Y;
+	const unsigned int byte_per_pixel_C;
+	const unsigned int block_height_256_bytes_Y;
+	const unsigned int block_height_256_bytes_C;
+	const unsigned int block_width_256_bytes_Y;
+	const unsigned int block_width_256_bytes_C;
+};
+
+struct calculate_write_back_DISPCLK_test_case {
+	const char *desc;
+	const enum source_format_class writeback_pixel_format;
+	const double pixel_clock;
+	const double writeback_HRatio;
+	const double writeback_VRatio;
+	const unsigned int writeback_luma_HTaps;
+	const unsigned int writeback_luma_VTaps;
+	const unsigned int writeback_chroma_HTaps;
+	const unsigned int writeback_chroma_VTaps;
+	const double writeback_destination_width;
+	const unsigned int HTotal;
+	const unsigned int writeback_chroma_line_buffer_width;
+	const double calculate_write_back_DISPCLK;
+};
+
+/**
+ * pclk_adjustment_for_progressive_to_interlace_unit_test - KUnit test
+ * for PixelClockAdjustmentForProgressiveToInterlaceUnit
+ * @test: represents a running instance of a test.
+ */
+static void pclk_adjustment_for_progressive_to_interlace_unit_test(struct kunit *test)
+{
+	const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case
+		*test_param = test->param_value;
+	struct display_mode_lib *mode_lib;
+	size_t pixel_clock_size = DC__NUM_DPP__MAX * sizeof(const double);
+	size_t interlace_size = DC__NUM_DPP__MAX * sizeof(const bool);
+
+	mode_lib = kunit_kzalloc(test, sizeof(struct display_mode_lib),
+				 GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode_lib);
+
+	mode_lib->vba.NumberOfActivePlanes = test_param->number_of_active_planes;
+	memcpy(mode_lib->vba.Interlace, test_param->interlace, interlace_size);
+	mode_lib->vba.ProgressiveToInterlaceUnitInOPP =
+		test_param->progressive_to_interlace_unit_in_OPP;
+	memcpy(mode_lib->vba.PixelClock, test_param->pixel_clock, pixel_clock_size);
+
+	PixelClockAdjustmentForProgressiveToInterlaceUnit(mode_lib);
+
+	KUNIT_EXPECT_TRUE(test, !memcmp(mode_lib->vba.PixelClock,
+					test_param->expected.pixel_clock,
+					pixel_clock_size));
+	KUNIT_EXPECT_TRUE(test, !memcmp(mode_lib->vba.PixelClockBackEnd,
+					test_param->expected.pixel_clock_backend,
+					pixel_clock_size));
+}
+
+/**
+ * calculate_256B_block_sizes_test - KUnit test for Calculate256BBlockSizes
+ * @test: represents a running instance of a test.
+ */
+static void calculate_256B_block_sizes_test(struct kunit *test)
+{
+	const struct calculate_256B_block_sizes_test_case *test_param =
+		test->param_value;
+	unsigned int *block_height_256_bytes_Y, *block_height_256_bytes_C;
+	unsigned int *block_width_256_bytes_Y, *block_width_256_bytes_C;
+
+	block_height_256_bytes_Y = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_height_256_bytes_Y);
+
+	block_height_256_bytes_C = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_height_256_bytes_C);
+
+	block_width_256_bytes_Y = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_width_256_bytes_Y);
+
+	block_width_256_bytes_C = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, block_width_256_bytes_C);
+
+	Calculate256BBlockSizes(test_param->source_pixel_format,
+				test_param->surface_tiling,
+				test_param->byte_per_pixel_Y,
+				test_param->byte_per_pixel_C,
+				block_height_256_bytes_Y,
+				block_height_256_bytes_C,
+				block_width_256_bytes_Y,
+				block_width_256_bytes_C);
+
+	KUNIT_EXPECT_EQ(test, *block_height_256_bytes_Y,
+			test_param->block_height_256_bytes_Y);
+	KUNIT_EXPECT_EQ(test, *block_height_256_bytes_C,
+			test_param->block_height_256_bytes_C);
+	KUNIT_EXPECT_EQ(test, *block_width_256_bytes_Y,
+			test_param->block_width_256_bytes_Y);
+	KUNIT_EXPECT_EQ(test, *block_width_256_bytes_C,
+			test_param->block_width_256_bytes_C);
+}
+
+/**
+ * calculate_min_and_max_prefetch_mode_test - KUnit test for CalculateMinAndMaxPrefetchMode
+ * @test: represents a running instance of a test.
+ */
+static void calculate_min_and_max_prefetch_mode_test(struct kunit *test)
+{
+	unsigned int *min_prefetch_mode, *max_prefetch_mode;
+
+	min_prefetch_mode = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, min_prefetch_mode);
+
+	max_prefetch_mode = kunit_kzalloc(test, sizeof(unsigned int), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, max_prefetch_mode);
+
+	/* Try to allow DRAM self-refresh and MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_try_to_allow_self_refresh_and_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+
+	/* Allow DRAM self-refresh and MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_allow_self_refresh_and_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 0);
+
+	/* Allow only DRAM self-refresh  */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_allow_self_refresh,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 1);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 1);
+
+	/* Allow neither DRAM self-refresh nor MCLK switch */
+	KUNIT_EXPECT_FALSE(test, CalculateMinAndMaxPrefetchMode
+			  (dm_neither_self_refresh_nor_mclk_switch,
+			   min_prefetch_mode, max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 2);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+
+	/* Invalid self-refresh affinity */
+	KUNIT_EXPECT_TRUE(test, CalculateMinAndMaxPrefetchMode(-1,
+							       min_prefetch_mode,
+							       max_prefetch_mode));
+	KUNIT_EXPECT_EQ(test, *min_prefetch_mode, 0);
+	KUNIT_EXPECT_EQ(test, *max_prefetch_mode, 2);
+}
+
+/**
+ * calculate_write_back_DISPCLK_test - KUnit test for CalculateWriteBackDISPCLK
+ * @test: represents a running instance of a test.
+ */
+static void calculate_write_back_DISPCLK_test(struct kunit *test)
+{
+	const struct calculate_write_back_DISPCLK_test_case *test_param = test->param_value;
+	double calculate_write_back_DISPCLK;
+
+	DC_FP_START();
+	calculate_write_back_DISPCLK = CalculateWriteBackDISPCLK
+		(test_param->writeback_pixel_format,
+		 test_param->pixel_clock, test_param->writeback_HRatio,
+		 test_param->writeback_VRatio, test_param->writeback_luma_HTaps,
+		 test_param->writeback_luma_VTaps, test_param->writeback_chroma_HTaps,
+		 test_param->writeback_chroma_VTaps,
+		 test_param->writeback_destination_width, test_param->HTotal,
+		 test_param->writeback_chroma_line_buffer_width);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->calculate_write_back_DISPCLK,
+			calculate_write_back_DISPCLK);
+}
+
+static const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case
+pixel_clock_adjustment_for_progressive_to_interlace_unit_cases[] = {
+	{
+		.desc = "No active planes",
+		.number_of_active_planes = 0,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Two active planes with no interlaced output",
+		.number_of_active_planes = 2,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 0.00, 0.00, 0.00, 0.00,
+				0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Three active planes with one interlaced plane",
+		.number_of_active_planes = 3,
+		.interlace = {false, true, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 0.00, 0.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 2720.00, 400.00, 0.00,
+				0.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 0.00,
+				0.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Five active planes with three interlaced planes",
+		.number_of_active_planes = 5,
+		.interlace = {false, true, false, true, true, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 0.00, 0.00, 0.00},
+		.expected = {
+			.pixel_clock = {3200.00, 2720.00, 400.00, 680.00,
+				1360.00, 0.00, 0.00, 0.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 0.00, 0.00, 0.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with five interlaced planes",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, false, true, true, false, true, false},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {6400.00, 2720.00, 400.00, 680.00,
+				1360.00, 1360.00, 5440.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.0},
+		},
+	},
+	{
+		.desc = "Eight active planes with all planes interlaced",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, true, true, true, true, true, true},
+		.progressive_to_interlace_unit_in_OPP = true,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {6400.00, 2720.00, 800.0, 680.00,
+				1360.00, 2720.00, 5440.0, 680.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with no interlaced plane",
+		.number_of_active_planes = 8,
+		.interlace = {false, false, false, false, false, false, false, false},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+	{
+		.desc = "Eight active planes with no progressive_to_interlace_unit_in_OPP",
+		.number_of_active_planes = 8,
+		.interlace = {true, true, true, true, true, true, true, true},
+		.progressive_to_interlace_unit_in_OPP = false,
+		.pixel_clock = {3200.00, 1360.00, 400.00, 340.00, 680.00, 1360.00, 2720.00, 340.00},
+		.expected = {
+			.pixel_clock = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+			.pixel_clock_backend = {3200.00, 1360.00, 400.00, 340.00,
+				680.00, 1360.00, 2720.00, 340.00},
+		},
+	},
+};
+
+static const struct calculate_256B_block_sizes_test_case calculate_256B_block_sizes_cases[] = {
+	/*
+	 * Here 16-bit specifies the number of bits in the horizontal 4-element region
+	 * used for subsampling
+	 */
+	{
+		.desc = "4:4:4 16-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_16,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 128,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 16-bit encoding with 256B standard swizzle",
+		.source_pixel_format = dm_444_16,
+		.surface_tiling = dm_sw_256b_s,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	/*
+	 * Here 32-bit specifies the number of bits in the horizontal
+	 * 4-element region used for subsampling
+	 */
+	{
+		.desc = "4:4:4 32-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_32,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 4,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 64,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 32-bit encoding with 256B display swizzle",
+		.source_pixel_format = dm_444_32,
+		.surface_tiling = dm_sw_256b_d,
+		.byte_per_pixel_Y = 4,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 8,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	/*
+	 * Here 64-bit specifies the number of bits in the horizontal 4-element region
+	 * used for subsampling
+	 */
+	{
+		.desc = "4:4:4 64-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_64,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 8,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 32,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 64-bit encoding with 4KB standard swizzle",
+		.source_pixel_format = dm_444_64,
+		.surface_tiling = dm_sw_4kb_s,
+		.byte_per_pixel_Y = 8,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 4,
+		.block_width_256_bytes_Y = 8,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 8-bit encoding with linear swizzle",
+		.source_pixel_format = dm_444_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "4:4:4 8-bit encoding with 4KB display swizzle",
+		.source_pixel_format = dm_444_8,
+		.surface_tiling = dm_sw_4kb_d,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit mono encoding with linear swizzle",
+		.source_pixel_format = dm_mono_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit mono encoding with 64KB standard swizzle",
+		.source_pixel_format = dm_mono_8,
+		.surface_tiling = dm_sw_64kb_s,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "16-bit mono encoding with linear swizzle",
+		.source_pixel_format = dm_mono_16,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 128,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "16-bit mono encoding with 64KB display swizzle",
+		.source_pixel_format = dm_mono_16,
+		.surface_tiling = dm_sw_64kb_d,
+		.byte_per_pixel_Y = 2,
+		.byte_per_pixel_C = 0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 0,
+		.block_width_256_bytes_C = 0,
+	},
+	{
+		.desc = "8-bit 4:2:0 encoding with linear swizzle",
+		.source_pixel_format = dm_420_8,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 2,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 1,
+		.block_width_256_bytes_C = 128,
+	},
+	{
+		.desc = "8-bit 4:2:0 encoding with VAR standard swizzle",
+		.source_pixel_format = dm_420_8,
+		.surface_tiling = dm_sw_var_s,
+		.byte_per_pixel_Y = 1,
+		.byte_per_pixel_C = 2,
+		.block_height_256_bytes_Y = 16,
+		.block_width_256_bytes_Y = 16,
+		.block_height_256_bytes_C = 8,
+		.block_width_256_bytes_C = 16,
+	},
+	{
+		.desc = "10-bit 4:2:0 encoding with linear swizzle",
+		.source_pixel_format = dm_420_10,
+		.surface_tiling = dm_sw_linear,
+		.byte_per_pixel_Y = 4.0 / 3.0,
+		.byte_per_pixel_C = 8.0 / 3.0,
+		.block_height_256_bytes_Y = 1,
+		.block_width_256_bytes_Y = 256,
+		.block_height_256_bytes_C = 1,
+		.block_width_256_bytes_C = 128,
+	},
+	{
+		.desc = "10-bit 4:2:0 encoding with VAR display swizzle",
+		.source_pixel_format = dm_420_10,
+		.surface_tiling = dm_sw_var_d,
+		.byte_per_pixel_Y = 4.0 / 3.0,
+		.byte_per_pixel_C = 8.0 / 3.0,
+		.block_height_256_bytes_Y = 8,
+		.block_width_256_bytes_Y = 32,
+		.block_height_256_bytes_C = 8,
+		.block_width_256_bytes_C = 16,
+	},
+};
+
+static const struct calculate_write_back_DISPCLK_test_case calculate_write_back_DISPCLK_cases[] = {
+	{
+		.desc = "Trivial test",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 0.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0,
+	},
+	{
+		.desc = "Simple Writeback Ratio",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1800.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.e7c6a11ep+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1360.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.5766666666666p+11,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 2720.72,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.ba5e02226985ep+12,
+	},
+	{
+		.desc = "No Writeback to Luma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 1800.66,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.85b6dabefdfd9p+11,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing pixel clock",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 400.756,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.4bb8ddb60f598p+10,
+	},
+	{
+		.desc = "Increase numeric error by increasing pixel clock",
+		.writeback_pixel_format = dm_444_32,
+		.pixel_clock = 3200.8,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 2,
+		.writeback_chroma_VTaps = 2,
+		.writeback_destination_width = 1686.7,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.847ced698147bp+12,
+	},
+	{
+		.desc = "Simple Writeback Ratio for 4:4:4 8-bit encoding",
+		.writeback_pixel_format = dm_444_8,
+		.pixel_clock = 1800.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.24aa62p+12,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps for 4:4:4 64-bit encoding",
+		.writeback_pixel_format = dm_444_64,
+		.pixel_clock = 1360.00,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.576666p+11,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps for 4:2:0 8-bit encoding",
+		.writeback_pixel_format = dm_420_8,
+		.pixel_clock = 2720.72,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 8,
+		.writeback_luma_VTaps = 8,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 1333.56,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 5,
+		.calculate_write_back_DISPCLK = 0x1.717f8p+12,
+	},
+	{
+		.desc = "No Writeback to Luma Taps for 4:2:0 10-bit encoding",
+		.writeback_pixel_format = dm_420_10,
+		.pixel_clock = 1800.66,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 996.0,
+		.HTotal = 1400,
+		.writeback_chroma_line_buffer_width = 4,
+		.calculate_write_back_DISPCLK = 0x1.43767ep+10,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing pixel clock for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.pixel_clock = 340.456,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.HTotal = 1181,
+		.writeback_chroma_line_buffer_width = 3,
+		.calculate_write_back_DISPCLK = 0x1.067b3p+10,
+	},
+	{
+		.desc = "Increase numeric error by increasing pixel clock for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.pixel_clock = 4000.92,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 3,
+		.writeback_luma_VTaps = 3,
+		.writeback_chroma_HTaps = 2,
+		.writeback_chroma_VTaps = 2,
+		.writeback_destination_width = 1686.7,
+		.HTotal = 1100,
+		.writeback_chroma_line_buffer_width = 2,
+		.calculate_write_back_DISPCLK = 0x1.84b5b8p+12,
+	},
+};
+
+static void pixel_clock_adjustment_for_progressive_to_interlace_unit_test_to_desc
+(const struct pixel_clock_adjustment_for_progressive_to_interlace_unit_test_case *t,
+	char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(pixel_clock_adjustment_for_progressive_to_interlace_unit,
+		  pixel_clock_adjustment_for_progressive_to_interlace_unit_cases,
+		  pixel_clock_adjustment_for_progressive_to_interlace_unit_test_to_desc);
+
+static void calculate_256B_block_sizes_test_to_desc
+(const struct calculate_256B_block_sizes_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_256B_block_sizes, calculate_256B_block_sizes_cases,
+		  calculate_256B_block_sizes_test_to_desc);
+
+static void calculate_write_back_DISPCLK_test_to_desc(const struct
+		calculate_write_back_DISPCLK_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_write_back_DISPCLK, calculate_write_back_DISPCLK_cases,
+		  calculate_write_back_DISPCLK_test_to_desc);
+
+static struct kunit_case display_mode_vba_test_cases[] = {
+	KUNIT_CASE_PARAM(pclk_adjustment_for_progressive_to_interlace_unit_test,
+			 pixel_clock_adjustment_for_progressive_to_interlace_unit_gen_params),
+	KUNIT_CASE_PARAM(calculate_256B_block_sizes_test,
+			 calculate_256B_block_sizes_gen_params),
+	KUNIT_CASE(calculate_min_and_max_prefetch_mode_test),
+	KUNIT_CASE_PARAM(calculate_write_back_DISPCLK_test,
+			 calculate_write_back_DISPCLK_gen_params),
+	{}
+};
+
+static struct kunit_suite display_mode_vba_test_suite = {
+	.name = "dml_display_mode_vba",
+	.test_cases = display_mode_vba_test_cases,
+};
+
+kunit_test_suite(display_mode_vba_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 5/8] drm/amd/display: Introduce KUnit to dcn20/display_mode_vba_20 library
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

The display_mode_vba_20 deals with hundreds of display parameters for
the DCN20 and sometimes does it in odd ways. The addition of unit tests
intends to assure the quality of the code delivered by HW engineers and,
also make it possible to refactor the code decreasing concerns about adding
bugs to the codebase.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 .../dc/dml/dcn20/display_mode_vba_20.c        |   4 +
 .../dc/dml/dcn20/display_mode_vba_20_test.c   | 888 ++++++++++++++++++
 2 files changed, 892 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
index d3b5b6fedf04..738d8c1f5def 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
@@ -5112,3 +5112,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 				locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
 	}
 }
+
+#if IS_ENABLED(CONFIG_DML_KUNIT_TEST)
+#include "../../tests/dc/dml/dcn20/display_mode_vba_20_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
new file mode 100644
index 000000000000..eeeacc2758a3
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
@@ -0,0 +1,888 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/display_mode_vba_20.c
+ *
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_enums.h"
+
+struct calculate_write_back_delay_test_case {
+	const char *desc;
+	const enum source_format_class writeback_pixel_format;
+	const double writeback_HRatio;
+	const double writeback_VRatio;
+	const unsigned int writeback_luma_HTaps;
+	const unsigned int writeback_luma_VTaps;
+	const unsigned int writeback_chroma_HTaps;
+	const unsigned int writeback_chroma_VTaps;
+	const unsigned int writeback_destination_width;
+	const double calculate_write_back_delay;
+};
+
+struct calculate_active_row_bandwidth_test_case {
+	const char *desc;
+	const bool GPUVM_enable;
+	const enum source_format_class source_pixel_format;
+	const double VRatio;
+	const bool DCC_enable;
+	const double line_time;
+	const unsigned int meta_row_byte_luma;
+	const unsigned int meta_row_byte_chroma;
+	const unsigned int meta_row_height_luma;
+	const unsigned int meta_row_height_chroma;
+	const unsigned int pixel_PTE_bytes_per_row_luma;
+	const unsigned int pixel_PTE_bytes_per_row_chroma;
+	const unsigned int dpte_row_height_luma;
+	const unsigned int dpte_row_height_chroma;
+	const double meta_row_bw;
+	const double dpte_row_bw;
+	const double qual_row_bw;
+};
+
+/**
+ * dscce_compute_delay_test - KUnit test for dscceComputeDelay
+ * @test: represents a running instance of a test.
+ */
+static void dscce_compute_delay_test(struct kunit *test)
+{
+	/* Testing all the valid values for bits per color (bpc): {8, 10, 12} */
+	/* Testing all the valid values for number of slices: {1, 2, 3, 4} */
+
+	/*
+	 * For 4:4:4 encoding, the minimum bpp value is 8 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 5184/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 8.0, 1, 1, dm_444), 2004);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 8.0625, 5184, 1, dm_444), 885);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 8.125, 2592, 2, dm_444), 3495);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 8.1875, 1728, 3, dm_444), 4356);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 8.25, 864, 3, dm_444), 4425);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 8.3125, 1296, 4, dm_444), 4854);
+
+	/*
+	 * For 4:2:0 encoding, the minimum bpp value is 6 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 4096/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 6.0, 2, 1, dm_420), 2982);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 6.0625, 4096, 1, dm_420), 1428);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 6.125, 2048, 2, dm_420), 3522);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 6.1875, 1365, 3, dm_420), 4200);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 6.25, 682, 3, dm_420), 5706);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 6.3125, 1024, 4, dm_420), 7746);
+
+	/*
+	 * For 4:2:2 encoding, the minimum bpp value is 7 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 5184/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on n-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0, 2, 1, dm_n422), 2694);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0625, 5184, 1, dm_n422), 1332);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.125, 2592, 2, dm_n422), 3966);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.1875, 1728, 3, dm_n422), 4824);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.25, 864, 3, dm_n422), 4962);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.3125, 1296, 4, dm_n422), 9282);
+
+	/* Minimum sliceWidth value on s-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0, 1, 1, dm_s422), 2226);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0625, 5184, 1, dm_s422), 960);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.125, 2592, 2, dm_s422), 3570);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.1875, 1728, 3, dm_s422), 4428);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.25, 864, 3, dm_s422), 4497);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.3125, 1296, 4, dm_s422), 4923);
+}
+
+/**
+ * DSC_compute_delay_test - KUnit test for dscComputeDelay
+ * @test: represents a running instance of a test.
+ */
+static void DSC_compute_delay_test(struct kunit *test)
+{
+	/* 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_444), 30);
+
+	/* 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_420), 48);
+
+	/* 4:2:2 n-encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_n422), 49);
+
+	/* 4:2:2 s-encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_s422), 30);
+}
+
+/**
+ * calculate_TWait_test - KUnit test for CalculateTWait
+ * @test: represents a running instance of a test.
+ */
+static void calculate_TWait_test(struct kunit *test)
+{
+	/* Zeroed Prefetch Mode */
+
+	/* DRAMClockChangeLatency > UrgentLatencyPixelDataOnly > SREnterPlusExitTime*/
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1300000, 1200000, 1000000), 2500000);
+
+	/* DRAMClockChangeLatency > SREnterPlusExitTime > UrgentLatencyPixelDataOnly */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1300000, 900000, 1200000), 2200000);
+
+	/* UrgentLatencyPixelDataOnly > DRAMClockChangeLatency > SREnterPlusExitTime */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 2000000, 900000), 3000000);
+
+	/* UrgentLatencyPixelDataOnly > SREnterPlusExitTime > DRAMClockChangeLatency */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 1200000, 1100000), 2200000);
+
+	/* SREnterPlusExitTime > DRAMClockChangeLatency > UrgentLatencyPixelDataOnly */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 900000, 2000000), 2000000);
+
+	/* SREnterPlusExitTime > UrgentLatencyPixelDataOnly > DRAMClockChangeLatency */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 1200000, 1300000), 2200000);
+
+	/* Prefetch Mode equals 1 */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 2500000, 2000000, 900000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1300000, 900000, 1200000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1100000, 1200000, 1000000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 1200000, 1100000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 900000, 2000000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 1200000, 1300000), 1300000);
+
+	/* Prefetch Mode greater than 1 */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 2500000, 2000000, 900000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(2, 2500000, 900000, 2000000), 900000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(5, 1100000, 1200000, 1000000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(4, 1000000, 1300000, 1200000), 1300000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(6, 1000000, 900000, 2000000), 900000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(3, 1000000, 1200000, 1300000), 1200000);
+}
+
+/**
+ * calculate_write_back_delay_test - KUnit test for CalculateWriteBackDelay
+ * @test: represents a running instance of a test.
+ */
+static void calculate_write_back_delay_test(struct kunit *test)
+{
+	const struct calculate_write_back_delay_test_case *test_param = test->param_value;
+	double calculate_write_back_delay;
+
+	DC_FP_START();
+	calculate_write_back_delay = CalculateWriteBackDelay
+		(test_param->writeback_pixel_format,
+		 test_param->writeback_HRatio,
+		 test_param->writeback_VRatio,
+		 test_param->writeback_luma_HTaps,
+		 test_param->writeback_luma_VTaps,
+		 test_param->writeback_chroma_HTaps,
+		 test_param->writeback_chroma_VTaps,
+		 test_param->writeback_destination_width);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->calculate_write_back_delay,
+			calculate_write_back_delay);
+}
+
+/**
+ * calculate_active_row_bandwidth_test - KUnit test for CalculateActiveRowBandwidth
+ * @test: represents a running instance of a test.
+ */
+static void calculate_active_row_bandwidth_test(struct kunit *test)
+{
+	const struct calculate_active_row_bandwidth_test_case *test_param = test->param_value;
+	double *meta_row_bw, *dpte_row_bw, *qual_row_bw;
+
+	meta_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, meta_row_bw);
+
+	dpte_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dpte_row_bw);
+
+	qual_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, qual_row_bw);
+
+	DC_FP_START();
+	CalculateActiveRowBandwidth(test_param->GPUVM_enable,
+				    test_param->source_pixel_format,
+				    test_param->VRatio,
+				    test_param->DCC_enable,
+				    test_param->line_time,
+				    test_param->meta_row_byte_luma,
+				    test_param->meta_row_byte_chroma,
+				    test_param->meta_row_height_luma,
+				    test_param->meta_row_height_chroma,
+				    test_param->pixel_PTE_bytes_per_row_luma,
+				    test_param->pixel_PTE_bytes_per_row_chroma,
+				    test_param->dpte_row_height_luma,
+				    test_param->dpte_row_height_chroma,
+				    meta_row_bw,
+				    dpte_row_bw,
+				    qual_row_bw);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->meta_row_bw, *meta_row_bw);
+	KUNIT_EXPECT_EQ(test, test_param->dpte_row_bw, *dpte_row_bw);
+	KUNIT_EXPECT_EQ(test, test_param->qual_row_bw, *qual_row_bw);
+}
+
+/**
+ * trunc_to_valid_BPP_test - KUnit test for TruncToValidBPP
+ * @test: represents a running instance of a test.
+ */
+static void trunc_to_valid_BPP_test(struct kunit *test)
+{
+	/* HDMI output for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, true, dm_hdmi, dm_420, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_hdmi, dm_420, 10), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.01, false, dm_hdmi, dm_420, 0), 15);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15, false, dm_hdmi, dm_420, 8), 15);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12.01, true, dm_hdmi, dm_420, 0), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, true, dm_hdmi, dm_420, 5), 12);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.99, false, dm_hdmi, dm_420, 5), BPP_INVALID);
+
+	/* HDMI output for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, true, dm_hdmi, dm_444, 0), 36);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, true, dm_hdmi, dm_444, 10), 36);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_hdmi, dm_444, 0), 30);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_hdmi, dm_444, 8), 30);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, true, dm_hdmi, dm_444, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, true, dm_hdmi, dm_444, 5), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, true, dm_hdmi, dm_444, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_hdmi, dm_444, 5), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.99, false, dm_hdmi, dm_444, 5), BPP_INVALID);
+
+	/* HDMI output for different encoding types */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, true, dm_hdmi, dm_n422, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, true, dm_hdmi, dm_s422, 10), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_hdmi, dm_n422, 0), 20);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_hdmi, dm_s422, 8), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, true, dm_hdmi, dm_n422, 0), 16);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, true, dm_hdmi, dm_s422, 5), 16);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.99, false, dm_hdmi, dm_n422, 5), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_hdmi, dm_s422, 0), BPP_INVALID);
+
+	/* Display Port output with DSC enabled and 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(5.99, true, dm_dp, dm_420, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_dp, dm_420, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, true, dm_dp, dm_420, 8), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(1.5 * 8 - 1 / (double)16, true, dm_dp,
+					      dm_420, 8), 11);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7, true, dm_dp, dm_420, 3), 4);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(1.5 * 9 - 1 / (double)16, true, dm_dp,
+					      dm_420, 9), 13);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.25, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6 + 1 / (double)3, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.50, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.75, true, dm_dp, dm_420, 8), 6);
+
+	/* Embedded Display Port output with DSC enabled and n-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.99, true, dm_edp, dm_n422, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_edp, dm_n422, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16, true, dm_edp, dm_n422, 7), 14);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(2 * 7 - 1 / (double)16, true, dm_edp,
+					      dm_n422, 7), 13);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7, true, dm_edp, dm_n422, 3), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(2 * 9 - 1 / (double)16, true, dm_edp,
+					      dm_n422, 9), 17);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11 + 1 / (double)3, true, dm_edp,
+					      dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.40, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.50, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.75, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.95, true, dm_edp, dm_n422, 8), 11);
+
+	/* Display Port 2.0 output with DSC enabled and 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7.99, true, dm_dp2p0, dm_444, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_dp2p0, dm_444, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(22, true, dm_dp2p0, dm_444, 11), 22);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 7 - 1 / (double)16, true, dm_dp2p0,
+					      dm_444, 7), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(14, true, dm_dp2p0, dm_444, 3), 9);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 9 - 1 / (double)16, true, dm_dp2p0,
+					      dm_444, 9), 26);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17 + 1 / (double)3, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.40, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.50, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.75, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.95, true, dm_dp2p0, dm_444, 7), 17);
+
+	/* WB output with DSC enabled and 4:2:2 s-encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7.99, true, dm_wb, dm_s422, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_wb, dm_s422, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(22, true, dm_wb, dm_s422, 11), 22);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 7 - 1 / (double)16, true, dm_wb, dm_s422, 7), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_wb, dm_s422, 3), 9);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 9 - 1 / (double)16, true, dm_wb, dm_s422, 9), 26);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17 + 1 / (double)3, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.40, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.50, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.75, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.95, true, dm_wb, dm_s422, 7), 17);
+
+	/* Display Port output with DSC disabled for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, false, dm_dp, dm_420, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, false, dm_dp, dm_420, 10), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.01, false, dm_dp, dm_420, 0), 15);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15, false, dm_dp, dm_420, 8), 15);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12.01, false, dm_dp, dm_420, 0), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, false, dm_dp, dm_420, 5), 12);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.99, false, dm_dp, dm_420, 5), BPP_INVALID);
+
+	/* Embedded Display Port output with DSC disabled for 4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, false, dm_edp, dm_s422, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, false, dm_edp, dm_n422, 10), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(20.01, false, dm_edp, dm_s422, 0), 20);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(20, false, dm_edp, dm_n422, 8), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16.01, false, dm_edp, dm_s422, 0), 16);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16, false, dm_edp, dm_n422, 5), 16);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.99, false, dm_edp, dm_s422, 5), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, false, dm_edp, dm_n422, 5), BPP_INVALID);
+
+	/* WB output with DSC disabled for 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, false, dm_wb, dm_444, 0), 36);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, false, dm_wb, dm_444, 10), 36);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_wb, dm_444, 0), 30);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_wb, dm_444, 8), 30);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, false, dm_wb, dm_444, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, false, dm_wb, dm_444, 5), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, false, dm_wb, dm_444, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, false, dm_wb, dm_444, 5), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.99, false, dm_wb, dm_444, 5), BPP_INVALID);
+}
+
+static const struct calculate_write_back_delay_test_case calculate_write_back_delay_cases[] = {
+	{
+		.desc = "Trivial test",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 0,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "High Writeback HRatio and VRatio and zeroed taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2400.0,
+		.writeback_VRatio = 2500.0,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 0,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "Simple Writeback Ratio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.2cap+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 2567.56,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400,
+		.calculate_write_back_delay = 0x1.61p+9,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+	{
+		.desc = "No Writeback to Luma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 3700,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "High Writeback HRatio and VRatio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2500000.0,
+		.writeback_VRatio = 2000000.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 3400,
+		.calculate_write_back_delay = 0x1.be4cd8p-10,
+	},
+	{
+		.desc = "Increase numeric error by increasing taps' Writeback",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 3000.0,
+		.writeback_VRatio = 2450.0,
+		.writeback_luma_HTaps = 100,
+		.writeback_luma_VTaps = 100,
+		.writeback_chroma_HTaps = 200,
+		.writeback_chroma_VTaps = 200,
+		.writeback_destination_width = 1687,
+		.calculate_write_back_delay = 0x1.49eap+15,
+	},
+	{
+		.desc = "Turning point of the Writeback HRatio and VRatio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 100000.0,
+		.writeback_VRatio = 100000.0,
+		.writeback_luma_HTaps = 100,
+		.writeback_luma_VTaps = 100,
+		.writeback_chroma_HTaps = 200,
+		.writeback_chroma_VTaps = 200,
+		.writeback_destination_width = 1687,
+		.calculate_write_back_delay = 0x1.b06ccap-2,
+	},
+	{
+		.desc = "Simple Writeback Ratio for 4:4:4 8-bit encoding",
+		.writeback_pixel_format = dm_444_8,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps for 4:4:4 64-bit encoding",
+		.writeback_pixel_format = dm_444_64,
+		.writeback_HRatio = 100000.0,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400,
+		.calculate_write_back_delay = 0x1.ceae7cp-8,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps for 4:2:0 8-bit encoding",
+		.writeback_pixel_format = dm_420_8,
+		.writeback_HRatio = 100000.00,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 8,
+		.writeback_luma_VTaps = 8,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 1333,
+		.calculate_write_back_delay = 0x1.b6c2d6p-6,
+	},
+	{
+		.desc = "No Writeback to Luma Taps for 4:2:0 10-bit encoding",
+		.writeback_pixel_format = dm_420_10,
+		.writeback_HRatio = 200000.0,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 996,
+		.calculate_write_back_delay = 0x1.ecd3f6p-9,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing Writeback HRatio and VRatio for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+};
+
+static const struct calculate_active_row_bandwidth_test_case calculate_active_row_bandwidth_cases[] = {
+	{
+		.desc = "Trivial Test",
+		.GPUVM_enable = false,
+		.source_pixel_format = -1,
+		.VRatio = 0.00,
+		.DCC_enable = false,
+		.line_time = 0.00,
+		.meta_row_byte_luma = 0,
+		.meta_row_byte_chroma = 0,
+		.meta_row_height_luma = 0,
+		.meta_row_height_chroma = 0,
+		.pixel_PTE_bytes_per_row_luma = 0,
+		.pixel_PTE_bytes_per_row_chroma = 0,
+		.dpte_row_height_luma = 0,
+		.dpte_row_height_chroma = 0,
+		.meta_row_bw = 0.00,
+		.dpte_row_bw = 0.00,
+		.qual_row_bw = 0.00,
+	},
+	{
+		.desc = "Zeroed Bandwidth with non-zeroed values",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0.00,
+		.dpte_row_bw = 0.00,
+		.qual_row_bw = 0.00,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.eb851eb851eb8p-4,
+		.qual_row_bw = 0x1.eb851eb851eb8p-4,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.0cb3a88722f67p-4,
+		.qual_row_bw = 0x1.0cb3a88722f67p-4,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 12-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_12,
+		.VRatio = 100.00,
+		.DCC_enable = false,
+		.line_time = 100.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 2,
+		.pixel_PTE_bytes_per_row_chroma = 2,
+		.dpte_row_height_luma = 10,
+		.dpte_row_height_chroma = 10,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.999999999999ap-3,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:4:4 16-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_16,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.408e78356d141p-5,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.f333333333333p-1,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x1.f333333333333p-1,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.4888888888889p-1,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x1.4888888888889p-1,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:2 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_422_8,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.3873873873874p-2,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:4:4 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_444_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 2000.00,
+		.meta_row_byte_luma = 190,
+		.meta_row_byte_chroma = 333,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 210,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x1.e666666666666p-2,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 2000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.f333333333333p-2,
+		.dpte_row_bw = 0x1.eb851eb851eb8p-5,
+		.qual_row_bw = 0x1.1851eb851eb85p-1,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 7000.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.9aaaaaaaaaaaap+2,
+		.dpte_row_bw = 0x1.4ad4ad4ad4ad5p-1,
+		.qual_row_bw = 0x1.c405405405405p+2,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:4:4 16-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_16,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 70,
+		.meta_row_byte_chroma = 550,
+		.meta_row_height_luma = 310,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 7,
+		.pixel_PTE_bytes_per_row_chroma = 7,
+		.dpte_row_height_luma = 190,
+		.dpte_row_height_chroma = 340,
+		.meta_row_bw = 0x1.f2065a3416de5p-4,
+		.dpte_row_bw = 0x1.4506d72a14507p-6,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:4:4 32-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_32,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.3873873873874p-2,
+		.dpte_row_bw = 0x1.60e2dafa7c749p-5,
+		.qual_row_bw = 0x0p+0,
+	},
+};
+
+static void calculate_write_back_delay_test_to_desc(const struct
+		calculate_write_back_delay_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_write_back_delay, calculate_write_back_delay_cases,
+		  calculate_write_back_delay_test_to_desc);
+
+static void calculate_active_row_bandwidth_test_to_desc(const struct
+		calculate_active_row_bandwidth_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_active_row_bandwidth, calculate_active_row_bandwidth_cases,
+		  calculate_active_row_bandwidth_test_to_desc);
+
+static struct kunit_case display_mode_vba_20_cases[] = {
+	KUNIT_CASE(dscce_compute_delay_test),
+	KUNIT_CASE(DSC_compute_delay_test),
+	KUNIT_CASE(calculate_TWait_test),
+	KUNIT_CASE_PARAM(calculate_write_back_delay_test, calculate_write_back_delay_gen_params),
+	KUNIT_CASE_PARAM(calculate_active_row_bandwidth_test,
+			 calculate_active_row_bandwidth_gen_params),
+	KUNIT_CASE(trunc_to_valid_BPP_test),
+	{  }
+};
+
+static struct kunit_suite display_mode_vba_20_suite = {
+	.name = "display_mode_vba_20",
+	.test_cases = display_mode_vba_20_cases,
+};
+
+kunit_test_suite(display_mode_vba_20_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 5/8] drm/amd/display: Introduce KUnit to dcn20/display_mode_vba_20 library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

The display_mode_vba_20 deals with hundreds of display parameters for
the DCN20 and sometimes does it in odd ways. The addition of unit tests
intends to assure the quality of the code delivered by HW engineers and,
also make it possible to refactor the code decreasing concerns about adding
bugs to the codebase.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 .../dc/dml/dcn20/display_mode_vba_20.c        |   4 +
 .../dc/dml/dcn20/display_mode_vba_20_test.c   | 888 ++++++++++++++++++
 2 files changed, 892 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
index d3b5b6fedf04..738d8c1f5def 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
@@ -5112,3 +5112,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 				locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
 	}
 }
+
+#if IS_ENABLED(CONFIG_DML_KUNIT_TEST)
+#include "../../tests/dc/dml/dcn20/display_mode_vba_20_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
new file mode 100644
index 000000000000..eeeacc2758a3
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
@@ -0,0 +1,888 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/display_mode_vba_20.c
+ *
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_enums.h"
+
+struct calculate_write_back_delay_test_case {
+	const char *desc;
+	const enum source_format_class writeback_pixel_format;
+	const double writeback_HRatio;
+	const double writeback_VRatio;
+	const unsigned int writeback_luma_HTaps;
+	const unsigned int writeback_luma_VTaps;
+	const unsigned int writeback_chroma_HTaps;
+	const unsigned int writeback_chroma_VTaps;
+	const unsigned int writeback_destination_width;
+	const double calculate_write_back_delay;
+};
+
+struct calculate_active_row_bandwidth_test_case {
+	const char *desc;
+	const bool GPUVM_enable;
+	const enum source_format_class source_pixel_format;
+	const double VRatio;
+	const bool DCC_enable;
+	const double line_time;
+	const unsigned int meta_row_byte_luma;
+	const unsigned int meta_row_byte_chroma;
+	const unsigned int meta_row_height_luma;
+	const unsigned int meta_row_height_chroma;
+	const unsigned int pixel_PTE_bytes_per_row_luma;
+	const unsigned int pixel_PTE_bytes_per_row_chroma;
+	const unsigned int dpte_row_height_luma;
+	const unsigned int dpte_row_height_chroma;
+	const double meta_row_bw;
+	const double dpte_row_bw;
+	const double qual_row_bw;
+};
+
+/**
+ * dscce_compute_delay_test - KUnit test for dscceComputeDelay
+ * @test: represents a running instance of a test.
+ */
+static void dscce_compute_delay_test(struct kunit *test)
+{
+	/* Testing all the valid values for bits per color (bpc): {8, 10, 12} */
+	/* Testing all the valid values for number of slices: {1, 2, 3, 4} */
+
+	/*
+	 * For 4:4:4 encoding, the minimum bpp value is 8 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 5184/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 8.0, 1, 1, dm_444), 2004);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 8.0625, 5184, 1, dm_444), 885);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 8.125, 2592, 2, dm_444), 3495);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 8.1875, 1728, 3, dm_444), 4356);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 8.25, 864, 3, dm_444), 4425);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 8.3125, 1296, 4, dm_444), 4854);
+
+	/*
+	 * For 4:2:0 encoding, the minimum bpp value is 6 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 4096/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 6.0, 2, 1, dm_420), 2982);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 6.0625, 4096, 1, dm_420), 1428);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 6.125, 2048, 2, dm_420), 3522);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 6.1875, 1365, 3, dm_420), 4200);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 6.25, 682, 3, dm_420), 5706);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 6.3125, 1024, 4, dm_420), 7746);
+
+	/*
+	 * For 4:2:2 encoding, the minimum bpp value is 7 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 5184/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on n-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0, 2, 1, dm_n422), 2694);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0625, 5184, 1, dm_n422), 1332);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.125, 2592, 2, dm_n422), 3966);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.1875, 1728, 3, dm_n422), 4824);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.25, 864, 3, dm_n422), 4962);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.3125, 1296, 4, dm_n422), 9282);
+
+	/* Minimum sliceWidth value on s-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0, 1, 1, dm_s422), 2226);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0625, 5184, 1, dm_s422), 960);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.125, 2592, 2, dm_s422), 3570);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.1875, 1728, 3, dm_s422), 4428);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.25, 864, 3, dm_s422), 4497);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.3125, 1296, 4, dm_s422), 4923);
+}
+
+/**
+ * DSC_compute_delay_test - KUnit test for dscComputeDelay
+ * @test: represents a running instance of a test.
+ */
+static void DSC_compute_delay_test(struct kunit *test)
+{
+	/* 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_444), 30);
+
+	/* 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_420), 48);
+
+	/* 4:2:2 n-encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_n422), 49);
+
+	/* 4:2:2 s-encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_s422), 30);
+}
+
+/**
+ * calculate_TWait_test - KUnit test for CalculateTWait
+ * @test: represents a running instance of a test.
+ */
+static void calculate_TWait_test(struct kunit *test)
+{
+	/* Zeroed Prefetch Mode */
+
+	/* DRAMClockChangeLatency > UrgentLatencyPixelDataOnly > SREnterPlusExitTime*/
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1300000, 1200000, 1000000), 2500000);
+
+	/* DRAMClockChangeLatency > SREnterPlusExitTime > UrgentLatencyPixelDataOnly */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1300000, 900000, 1200000), 2200000);
+
+	/* UrgentLatencyPixelDataOnly > DRAMClockChangeLatency > SREnterPlusExitTime */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 2000000, 900000), 3000000);
+
+	/* UrgentLatencyPixelDataOnly > SREnterPlusExitTime > DRAMClockChangeLatency */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 1200000, 1100000), 2200000);
+
+	/* SREnterPlusExitTime > DRAMClockChangeLatency > UrgentLatencyPixelDataOnly */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 900000, 2000000), 2000000);
+
+	/* SREnterPlusExitTime > UrgentLatencyPixelDataOnly > DRAMClockChangeLatency */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 1200000, 1300000), 2200000);
+
+	/* Prefetch Mode equals 1 */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 2500000, 2000000, 900000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1300000, 900000, 1200000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1100000, 1200000, 1000000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 1200000, 1100000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 900000, 2000000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 1200000, 1300000), 1300000);
+
+	/* Prefetch Mode greater than 1 */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 2500000, 2000000, 900000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(2, 2500000, 900000, 2000000), 900000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(5, 1100000, 1200000, 1000000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(4, 1000000, 1300000, 1200000), 1300000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(6, 1000000, 900000, 2000000), 900000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(3, 1000000, 1200000, 1300000), 1200000);
+}
+
+/**
+ * calculate_write_back_delay_test - KUnit test for CalculateWriteBackDelay
+ * @test: represents a running instance of a test.
+ */
+static void calculate_write_back_delay_test(struct kunit *test)
+{
+	const struct calculate_write_back_delay_test_case *test_param = test->param_value;
+	double calculate_write_back_delay;
+
+	DC_FP_START();
+	calculate_write_back_delay = CalculateWriteBackDelay
+		(test_param->writeback_pixel_format,
+		 test_param->writeback_HRatio,
+		 test_param->writeback_VRatio,
+		 test_param->writeback_luma_HTaps,
+		 test_param->writeback_luma_VTaps,
+		 test_param->writeback_chroma_HTaps,
+		 test_param->writeback_chroma_VTaps,
+		 test_param->writeback_destination_width);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->calculate_write_back_delay,
+			calculate_write_back_delay);
+}
+
+/**
+ * calculate_active_row_bandwidth_test - KUnit test for CalculateActiveRowBandwidth
+ * @test: represents a running instance of a test.
+ */
+static void calculate_active_row_bandwidth_test(struct kunit *test)
+{
+	const struct calculate_active_row_bandwidth_test_case *test_param = test->param_value;
+	double *meta_row_bw, *dpte_row_bw, *qual_row_bw;
+
+	meta_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, meta_row_bw);
+
+	dpte_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dpte_row_bw);
+
+	qual_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, qual_row_bw);
+
+	DC_FP_START();
+	CalculateActiveRowBandwidth(test_param->GPUVM_enable,
+				    test_param->source_pixel_format,
+				    test_param->VRatio,
+				    test_param->DCC_enable,
+				    test_param->line_time,
+				    test_param->meta_row_byte_luma,
+				    test_param->meta_row_byte_chroma,
+				    test_param->meta_row_height_luma,
+				    test_param->meta_row_height_chroma,
+				    test_param->pixel_PTE_bytes_per_row_luma,
+				    test_param->pixel_PTE_bytes_per_row_chroma,
+				    test_param->dpte_row_height_luma,
+				    test_param->dpte_row_height_chroma,
+				    meta_row_bw,
+				    dpte_row_bw,
+				    qual_row_bw);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->meta_row_bw, *meta_row_bw);
+	KUNIT_EXPECT_EQ(test, test_param->dpte_row_bw, *dpte_row_bw);
+	KUNIT_EXPECT_EQ(test, test_param->qual_row_bw, *qual_row_bw);
+}
+
+/**
+ * trunc_to_valid_BPP_test - KUnit test for TruncToValidBPP
+ * @test: represents a running instance of a test.
+ */
+static void trunc_to_valid_BPP_test(struct kunit *test)
+{
+	/* HDMI output for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, true, dm_hdmi, dm_420, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_hdmi, dm_420, 10), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.01, false, dm_hdmi, dm_420, 0), 15);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15, false, dm_hdmi, dm_420, 8), 15);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12.01, true, dm_hdmi, dm_420, 0), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, true, dm_hdmi, dm_420, 5), 12);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.99, false, dm_hdmi, dm_420, 5), BPP_INVALID);
+
+	/* HDMI output for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, true, dm_hdmi, dm_444, 0), 36);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, true, dm_hdmi, dm_444, 10), 36);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_hdmi, dm_444, 0), 30);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_hdmi, dm_444, 8), 30);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, true, dm_hdmi, dm_444, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, true, dm_hdmi, dm_444, 5), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, true, dm_hdmi, dm_444, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_hdmi, dm_444, 5), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.99, false, dm_hdmi, dm_444, 5), BPP_INVALID);
+
+	/* HDMI output for different encoding types */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, true, dm_hdmi, dm_n422, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, true, dm_hdmi, dm_s422, 10), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_hdmi, dm_n422, 0), 20);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_hdmi, dm_s422, 8), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, true, dm_hdmi, dm_n422, 0), 16);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, true, dm_hdmi, dm_s422, 5), 16);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.99, false, dm_hdmi, dm_n422, 5), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_hdmi, dm_s422, 0), BPP_INVALID);
+
+	/* Display Port output with DSC enabled and 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(5.99, true, dm_dp, dm_420, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_dp, dm_420, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, true, dm_dp, dm_420, 8), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(1.5 * 8 - 1 / (double)16, true, dm_dp,
+					      dm_420, 8), 11);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7, true, dm_dp, dm_420, 3), 4);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(1.5 * 9 - 1 / (double)16, true, dm_dp,
+					      dm_420, 9), 13);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.25, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6 + 1 / (double)3, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.50, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.75, true, dm_dp, dm_420, 8), 6);
+
+	/* Embedded Display Port output with DSC enabled and n-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.99, true, dm_edp, dm_n422, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_edp, dm_n422, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16, true, dm_edp, dm_n422, 7), 14);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(2 * 7 - 1 / (double)16, true, dm_edp,
+					      dm_n422, 7), 13);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7, true, dm_edp, dm_n422, 3), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(2 * 9 - 1 / (double)16, true, dm_edp,
+					      dm_n422, 9), 17);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11 + 1 / (double)3, true, dm_edp,
+					      dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.40, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.50, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.75, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.95, true, dm_edp, dm_n422, 8), 11);
+
+	/* Display Port 2.0 output with DSC enabled and 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7.99, true, dm_dp2p0, dm_444, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_dp2p0, dm_444, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(22, true, dm_dp2p0, dm_444, 11), 22);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 7 - 1 / (double)16, true, dm_dp2p0,
+					      dm_444, 7), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(14, true, dm_dp2p0, dm_444, 3), 9);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 9 - 1 / (double)16, true, dm_dp2p0,
+					      dm_444, 9), 26);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17 + 1 / (double)3, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.40, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.50, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.75, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.95, true, dm_dp2p0, dm_444, 7), 17);
+
+	/* WB output with DSC enabled and 4:2:2 s-encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7.99, true, dm_wb, dm_s422, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_wb, dm_s422, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(22, true, dm_wb, dm_s422, 11), 22);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 7 - 1 / (double)16, true, dm_wb, dm_s422, 7), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_wb, dm_s422, 3), 9);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 9 - 1 / (double)16, true, dm_wb, dm_s422, 9), 26);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17 + 1 / (double)3, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.40, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.50, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.75, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.95, true, dm_wb, dm_s422, 7), 17);
+
+	/* Display Port output with DSC disabled for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, false, dm_dp, dm_420, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, false, dm_dp, dm_420, 10), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.01, false, dm_dp, dm_420, 0), 15);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15, false, dm_dp, dm_420, 8), 15);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12.01, false, dm_dp, dm_420, 0), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, false, dm_dp, dm_420, 5), 12);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.99, false, dm_dp, dm_420, 5), BPP_INVALID);
+
+	/* Embedded Display Port output with DSC disabled for 4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, false, dm_edp, dm_s422, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, false, dm_edp, dm_n422, 10), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(20.01, false, dm_edp, dm_s422, 0), 20);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(20, false, dm_edp, dm_n422, 8), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16.01, false, dm_edp, dm_s422, 0), 16);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16, false, dm_edp, dm_n422, 5), 16);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.99, false, dm_edp, dm_s422, 5), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, false, dm_edp, dm_n422, 5), BPP_INVALID);
+
+	/* WB output with DSC disabled for 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, false, dm_wb, dm_444, 0), 36);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, false, dm_wb, dm_444, 10), 36);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_wb, dm_444, 0), 30);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_wb, dm_444, 8), 30);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, false, dm_wb, dm_444, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, false, dm_wb, dm_444, 5), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, false, dm_wb, dm_444, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, false, dm_wb, dm_444, 5), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.99, false, dm_wb, dm_444, 5), BPP_INVALID);
+}
+
+static const struct calculate_write_back_delay_test_case calculate_write_back_delay_cases[] = {
+	{
+		.desc = "Trivial test",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 0,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "High Writeback HRatio and VRatio and zeroed taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2400.0,
+		.writeback_VRatio = 2500.0,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 0,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "Simple Writeback Ratio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.2cap+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 2567.56,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400,
+		.calculate_write_back_delay = 0x1.61p+9,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+	{
+		.desc = "No Writeback to Luma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 3700,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "High Writeback HRatio and VRatio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2500000.0,
+		.writeback_VRatio = 2000000.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 3400,
+		.calculate_write_back_delay = 0x1.be4cd8p-10,
+	},
+	{
+		.desc = "Increase numeric error by increasing taps' Writeback",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 3000.0,
+		.writeback_VRatio = 2450.0,
+		.writeback_luma_HTaps = 100,
+		.writeback_luma_VTaps = 100,
+		.writeback_chroma_HTaps = 200,
+		.writeback_chroma_VTaps = 200,
+		.writeback_destination_width = 1687,
+		.calculate_write_back_delay = 0x1.49eap+15,
+	},
+	{
+		.desc = "Turning point of the Writeback HRatio and VRatio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 100000.0,
+		.writeback_VRatio = 100000.0,
+		.writeback_luma_HTaps = 100,
+		.writeback_luma_VTaps = 100,
+		.writeback_chroma_HTaps = 200,
+		.writeback_chroma_VTaps = 200,
+		.writeback_destination_width = 1687,
+		.calculate_write_back_delay = 0x1.b06ccap-2,
+	},
+	{
+		.desc = "Simple Writeback Ratio for 4:4:4 8-bit encoding",
+		.writeback_pixel_format = dm_444_8,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps for 4:4:4 64-bit encoding",
+		.writeback_pixel_format = dm_444_64,
+		.writeback_HRatio = 100000.0,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400,
+		.calculate_write_back_delay = 0x1.ceae7cp-8,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps for 4:2:0 8-bit encoding",
+		.writeback_pixel_format = dm_420_8,
+		.writeback_HRatio = 100000.00,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 8,
+		.writeback_luma_VTaps = 8,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 1333,
+		.calculate_write_back_delay = 0x1.b6c2d6p-6,
+	},
+	{
+		.desc = "No Writeback to Luma Taps for 4:2:0 10-bit encoding",
+		.writeback_pixel_format = dm_420_10,
+		.writeback_HRatio = 200000.0,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 996,
+		.calculate_write_back_delay = 0x1.ecd3f6p-9,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing Writeback HRatio and VRatio for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+};
+
+static const struct calculate_active_row_bandwidth_test_case calculate_active_row_bandwidth_cases[] = {
+	{
+		.desc = "Trivial Test",
+		.GPUVM_enable = false,
+		.source_pixel_format = -1,
+		.VRatio = 0.00,
+		.DCC_enable = false,
+		.line_time = 0.00,
+		.meta_row_byte_luma = 0,
+		.meta_row_byte_chroma = 0,
+		.meta_row_height_luma = 0,
+		.meta_row_height_chroma = 0,
+		.pixel_PTE_bytes_per_row_luma = 0,
+		.pixel_PTE_bytes_per_row_chroma = 0,
+		.dpte_row_height_luma = 0,
+		.dpte_row_height_chroma = 0,
+		.meta_row_bw = 0.00,
+		.dpte_row_bw = 0.00,
+		.qual_row_bw = 0.00,
+	},
+	{
+		.desc = "Zeroed Bandwidth with non-zeroed values",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0.00,
+		.dpte_row_bw = 0.00,
+		.qual_row_bw = 0.00,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.eb851eb851eb8p-4,
+		.qual_row_bw = 0x1.eb851eb851eb8p-4,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.0cb3a88722f67p-4,
+		.qual_row_bw = 0x1.0cb3a88722f67p-4,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 12-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_12,
+		.VRatio = 100.00,
+		.DCC_enable = false,
+		.line_time = 100.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 2,
+		.pixel_PTE_bytes_per_row_chroma = 2,
+		.dpte_row_height_luma = 10,
+		.dpte_row_height_chroma = 10,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.999999999999ap-3,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:4:4 16-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_16,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.408e78356d141p-5,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.f333333333333p-1,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x1.f333333333333p-1,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.4888888888889p-1,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x1.4888888888889p-1,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:2 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_422_8,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.3873873873874p-2,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:4:4 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_444_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 2000.00,
+		.meta_row_byte_luma = 190,
+		.meta_row_byte_chroma = 333,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 210,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x1.e666666666666p-2,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 2000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.f333333333333p-2,
+		.dpte_row_bw = 0x1.eb851eb851eb8p-5,
+		.qual_row_bw = 0x1.1851eb851eb85p-1,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 7000.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.9aaaaaaaaaaaap+2,
+		.dpte_row_bw = 0x1.4ad4ad4ad4ad5p-1,
+		.qual_row_bw = 0x1.c405405405405p+2,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:4:4 16-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_16,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 70,
+		.meta_row_byte_chroma = 550,
+		.meta_row_height_luma = 310,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 7,
+		.pixel_PTE_bytes_per_row_chroma = 7,
+		.dpte_row_height_luma = 190,
+		.dpte_row_height_chroma = 340,
+		.meta_row_bw = 0x1.f2065a3416de5p-4,
+		.dpte_row_bw = 0x1.4506d72a14507p-6,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:4:4 32-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_32,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.3873873873874p-2,
+		.dpte_row_bw = 0x1.60e2dafa7c749p-5,
+		.qual_row_bw = 0x0p+0,
+	},
+};
+
+static void calculate_write_back_delay_test_to_desc(const struct
+		calculate_write_back_delay_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_write_back_delay, calculate_write_back_delay_cases,
+		  calculate_write_back_delay_test_to_desc);
+
+static void calculate_active_row_bandwidth_test_to_desc(const struct
+		calculate_active_row_bandwidth_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_active_row_bandwidth, calculate_active_row_bandwidth_cases,
+		  calculate_active_row_bandwidth_test_to_desc);
+
+static struct kunit_case display_mode_vba_20_cases[] = {
+	KUNIT_CASE(dscce_compute_delay_test),
+	KUNIT_CASE(DSC_compute_delay_test),
+	KUNIT_CASE(calculate_TWait_test),
+	KUNIT_CASE_PARAM(calculate_write_back_delay_test, calculate_write_back_delay_gen_params),
+	KUNIT_CASE_PARAM(calculate_active_row_bandwidth_test,
+			 calculate_active_row_bandwidth_gen_params),
+	KUNIT_CASE(trunc_to_valid_BPP_test),
+	{  }
+};
+
+static struct kunit_suite display_mode_vba_20_suite = {
+	.name = "display_mode_vba_20",
+	.test_cases = display_mode_vba_20_cases,
+};
+
+kunit_test_suite(display_mode_vba_20_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 5/8] drm/amd/display: Introduce KUnit to dcn20/display_mode_vba_20 library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

The display_mode_vba_20 deals with hundreds of display parameters for
the DCN20 and sometimes does it in odd ways. The addition of unit tests
intends to assure the quality of the code delivered by HW engineers and,
also make it possible to refactor the code decreasing concerns about adding
bugs to the codebase.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 .../dc/dml/dcn20/display_mode_vba_20.c        |   4 +
 .../dc/dml/dcn20/display_mode_vba_20_test.c   | 888 ++++++++++++++++++
 2 files changed, 892 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c

diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
index d3b5b6fedf04..738d8c1f5def 100644
--- a/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
+++ b/drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
@@ -5112,3 +5112,7 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
 				locals->OutputBppPerState[mode_lib->vba.VoltageLevel][k];
 	}
 }
+
+#if IS_ENABLED(CONFIG_DML_KUNIT_TEST)
+#include "../../tests/dc/dml/dcn20/display_mode_vba_20_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
new file mode 100644
index 000000000000..eeeacc2758a3
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/display_mode_vba_20_test.c
@@ -0,0 +1,888 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/display_mode_vba_20.c
+ *
+ * Copyright (C) 2022, Maíra Canal <mairacanal@riseup.net>
+ */
+
+#include <kunit/test.h>
+#include "dml/display_mode_enums.h"
+
+struct calculate_write_back_delay_test_case {
+	const char *desc;
+	const enum source_format_class writeback_pixel_format;
+	const double writeback_HRatio;
+	const double writeback_VRatio;
+	const unsigned int writeback_luma_HTaps;
+	const unsigned int writeback_luma_VTaps;
+	const unsigned int writeback_chroma_HTaps;
+	const unsigned int writeback_chroma_VTaps;
+	const unsigned int writeback_destination_width;
+	const double calculate_write_back_delay;
+};
+
+struct calculate_active_row_bandwidth_test_case {
+	const char *desc;
+	const bool GPUVM_enable;
+	const enum source_format_class source_pixel_format;
+	const double VRatio;
+	const bool DCC_enable;
+	const double line_time;
+	const unsigned int meta_row_byte_luma;
+	const unsigned int meta_row_byte_chroma;
+	const unsigned int meta_row_height_luma;
+	const unsigned int meta_row_height_chroma;
+	const unsigned int pixel_PTE_bytes_per_row_luma;
+	const unsigned int pixel_PTE_bytes_per_row_chroma;
+	const unsigned int dpte_row_height_luma;
+	const unsigned int dpte_row_height_chroma;
+	const double meta_row_bw;
+	const double dpte_row_bw;
+	const double qual_row_bw;
+};
+
+/**
+ * dscce_compute_delay_test - KUnit test for dscceComputeDelay
+ * @test: represents a running instance of a test.
+ */
+static void dscce_compute_delay_test(struct kunit *test)
+{
+	/* Testing all the valid values for bits per color (bpc): {8, 10, 12} */
+	/* Testing all the valid values for number of slices: {1, 2, 3, 4} */
+
+	/*
+	 * For 4:4:4 encoding, the minimum bpp value is 8 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 5184/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 8.0, 1, 1, dm_444), 2004);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 8.0625, 5184, 1, dm_444), 885);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 8.125, 2592, 2, dm_444), 3495);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 8.1875, 1728, 3, dm_444), 4356);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 8.25, 864, 3, dm_444), 4425);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 8.3125, 1296, 4, dm_444), 4854);
+
+	/*
+	 * For 4:2:0 encoding, the minimum bpp value is 6 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 4096/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 6.0, 2, 1, dm_420), 2982);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 6.0625, 4096, 1, dm_420), 1428);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 6.125, 2048, 2, dm_420), 3522);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 6.1875, 1365, 3, dm_420), 4200);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 6.25, 682, 3, dm_420), 5706);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 6.3125, 1024, 4, dm_420), 7746);
+
+	/*
+	 * For 4:2:2 encoding, the minimum bpp value is 7 and is incremented by
+	 * 1/16 of a bit. Moreover, the sliceWidth must be less than or equal to
+	 * 5184/numSlices.
+	 */
+
+	/* Minimum sliceWidth value on n-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0, 2, 1, dm_n422), 2694);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0625, 5184, 1, dm_n422), 1332);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.125, 2592, 2, dm_n422), 3966);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.1875, 1728, 3, dm_n422), 4824);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.25, 864, 3, dm_n422), 4962);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.3125, 1296, 4, dm_n422), 9282);
+
+	/* Minimum sliceWidth value on s-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0, 1, 1, dm_s422), 2226);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(8, 7.0625, 5184, 1, dm_s422), 960);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.125, 2592, 2, dm_s422), 3570);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(10, 7.1875, 1728, 3, dm_s422), 4428);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.25, 864, 3, dm_s422), 4497);
+
+	KUNIT_EXPECT_EQ(test, dscceComputeDelay(12, 7.3125, 1296, 4, dm_s422), 4923);
+}
+
+/**
+ * DSC_compute_delay_test - KUnit test for dscComputeDelay
+ * @test: represents a running instance of a test.
+ */
+static void DSC_compute_delay_test(struct kunit *test)
+{
+	/* 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_444), 30);
+
+	/* 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_420), 48);
+
+	/* 4:2:2 n-encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_n422), 49);
+
+	/* 4:2:2 s-encoding */
+	KUNIT_EXPECT_EQ(test, dscComputeDelay(dm_s422), 30);
+}
+
+/**
+ * calculate_TWait_test - KUnit test for CalculateTWait
+ * @test: represents a running instance of a test.
+ */
+static void calculate_TWait_test(struct kunit *test)
+{
+	/* Zeroed Prefetch Mode */
+
+	/* DRAMClockChangeLatency > UrgentLatencyPixelDataOnly > SREnterPlusExitTime*/
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1300000, 1200000, 1000000), 2500000);
+
+	/* DRAMClockChangeLatency > SREnterPlusExitTime > UrgentLatencyPixelDataOnly */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1300000, 900000, 1200000), 2200000);
+
+	/* UrgentLatencyPixelDataOnly > DRAMClockChangeLatency > SREnterPlusExitTime */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 2000000, 900000), 3000000);
+
+	/* UrgentLatencyPixelDataOnly > SREnterPlusExitTime > DRAMClockChangeLatency */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 1200000, 1100000), 2200000);
+
+	/* SREnterPlusExitTime > DRAMClockChangeLatency > UrgentLatencyPixelDataOnly */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 900000, 2000000), 2000000);
+
+	/* SREnterPlusExitTime > UrgentLatencyPixelDataOnly > DRAMClockChangeLatency */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(0, 1000000, 1200000, 1300000), 2200000);
+
+	/* Prefetch Mode equals 1 */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 2500000, 2000000, 900000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1300000, 900000, 1200000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1100000, 1200000, 1000000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 1200000, 1100000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 900000, 2000000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 1000000, 1200000, 1300000), 1300000);
+
+	/* Prefetch Mode greater than 1 */
+	KUNIT_EXPECT_EQ(test, CalculateTWait(1, 2500000, 2000000, 900000), 2000000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(2, 2500000, 900000, 2000000), 900000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(5, 1100000, 1200000, 1000000), 1200000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(4, 1000000, 1300000, 1200000), 1300000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(6, 1000000, 900000, 2000000), 900000);
+	KUNIT_EXPECT_EQ(test, CalculateTWait(3, 1000000, 1200000, 1300000), 1200000);
+}
+
+/**
+ * calculate_write_back_delay_test - KUnit test for CalculateWriteBackDelay
+ * @test: represents a running instance of a test.
+ */
+static void calculate_write_back_delay_test(struct kunit *test)
+{
+	const struct calculate_write_back_delay_test_case *test_param = test->param_value;
+	double calculate_write_back_delay;
+
+	DC_FP_START();
+	calculate_write_back_delay = CalculateWriteBackDelay
+		(test_param->writeback_pixel_format,
+		 test_param->writeback_HRatio,
+		 test_param->writeback_VRatio,
+		 test_param->writeback_luma_HTaps,
+		 test_param->writeback_luma_VTaps,
+		 test_param->writeback_chroma_HTaps,
+		 test_param->writeback_chroma_VTaps,
+		 test_param->writeback_destination_width);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->calculate_write_back_delay,
+			calculate_write_back_delay);
+}
+
+/**
+ * calculate_active_row_bandwidth_test - KUnit test for CalculateActiveRowBandwidth
+ * @test: represents a running instance of a test.
+ */
+static void calculate_active_row_bandwidth_test(struct kunit *test)
+{
+	const struct calculate_active_row_bandwidth_test_case *test_param = test->param_value;
+	double *meta_row_bw, *dpte_row_bw, *qual_row_bw;
+
+	meta_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, meta_row_bw);
+
+	dpte_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dpte_row_bw);
+
+	qual_row_bw = kunit_kzalloc(test, sizeof(double), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, qual_row_bw);
+
+	DC_FP_START();
+	CalculateActiveRowBandwidth(test_param->GPUVM_enable,
+				    test_param->source_pixel_format,
+				    test_param->VRatio,
+				    test_param->DCC_enable,
+				    test_param->line_time,
+				    test_param->meta_row_byte_luma,
+				    test_param->meta_row_byte_chroma,
+				    test_param->meta_row_height_luma,
+				    test_param->meta_row_height_chroma,
+				    test_param->pixel_PTE_bytes_per_row_luma,
+				    test_param->pixel_PTE_bytes_per_row_chroma,
+				    test_param->dpte_row_height_luma,
+				    test_param->dpte_row_height_chroma,
+				    meta_row_bw,
+				    dpte_row_bw,
+				    qual_row_bw);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->meta_row_bw, *meta_row_bw);
+	KUNIT_EXPECT_EQ(test, test_param->dpte_row_bw, *dpte_row_bw);
+	KUNIT_EXPECT_EQ(test, test_param->qual_row_bw, *qual_row_bw);
+}
+
+/**
+ * trunc_to_valid_BPP_test - KUnit test for TruncToValidBPP
+ * @test: represents a running instance of a test.
+ */
+static void trunc_to_valid_BPP_test(struct kunit *test)
+{
+	/* HDMI output for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, true, dm_hdmi, dm_420, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_hdmi, dm_420, 10), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.01, false, dm_hdmi, dm_420, 0), 15);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15, false, dm_hdmi, dm_420, 8), 15);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12.01, true, dm_hdmi, dm_420, 0), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, true, dm_hdmi, dm_420, 5), 12);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.99, false, dm_hdmi, dm_420, 5), BPP_INVALID);
+
+	/* HDMI output for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, true, dm_hdmi, dm_444, 0), 36);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, true, dm_hdmi, dm_444, 10), 36);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_hdmi, dm_444, 0), 30);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_hdmi, dm_444, 8), 30);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, true, dm_hdmi, dm_444, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, true, dm_hdmi, dm_444, 5), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, true, dm_hdmi, dm_444, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_hdmi, dm_444, 5), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.99, false, dm_hdmi, dm_444, 5), BPP_INVALID);
+
+	/* HDMI output for different encoding types */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, true, dm_hdmi, dm_n422, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, true, dm_hdmi, dm_s422, 10), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_hdmi, dm_n422, 0), 20);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_hdmi, dm_s422, 8), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, true, dm_hdmi, dm_n422, 0), 16);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, true, dm_hdmi, dm_s422, 5), 16);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.99, false, dm_hdmi, dm_n422, 5), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_hdmi, dm_s422, 0), BPP_INVALID);
+
+	/* Display Port output with DSC enabled and 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(5.99, true, dm_dp, dm_420, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_dp, dm_420, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, true, dm_dp, dm_420, 8), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(1.5 * 8 - 1 / (double)16, true, dm_dp,
+					      dm_420, 8), 11);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7, true, dm_dp, dm_420, 3), 4);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(1.5 * 9 - 1 / (double)16, true, dm_dp,
+					      dm_420, 9), 13);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.25, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6 + 1 / (double)3, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.50, true, dm_dp, dm_420, 8), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.75, true, dm_dp, dm_420, 8), 6);
+
+	/* Embedded Display Port output with DSC enabled and n-4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(6.99, true, dm_edp, dm_n422, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_edp, dm_n422, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16, true, dm_edp, dm_n422, 7), 14);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(2 * 7 - 1 / (double)16, true, dm_edp,
+					      dm_n422, 7), 13);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7, true, dm_edp, dm_n422, 3), 6);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(2 * 9 - 1 / (double)16, true, dm_edp,
+					      dm_n422, 9), 17);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11 + 1 / (double)3, true, dm_edp,
+					      dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.40, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.50, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.75, true, dm_edp, dm_n422, 8), 11);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.95, true, dm_edp, dm_n422, 8), 11);
+
+	/* Display Port 2.0 output with DSC enabled and 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7.99, true, dm_dp2p0, dm_444, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_dp2p0, dm_444, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(22, true, dm_dp2p0, dm_444, 11), 22);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 7 - 1 / (double)16, true, dm_dp2p0,
+					      dm_444, 7), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(14, true, dm_dp2p0, dm_444, 3), 9);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 9 - 1 / (double)16, true, dm_dp2p0,
+					      dm_444, 9), 26);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17 + 1 / (double)3, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.40, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.50, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.75, true, dm_dp2p0, dm_444, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.95, true, dm_dp2p0, dm_444, 7), 17);
+
+	/* WB output with DSC enabled and 4:2:2 s-encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(7.99, true, dm_wb, dm_s422, 0), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, true, dm_wb, dm_s422, 0), BPP_INVALID);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(22, true, dm_wb, dm_s422, 11), 22);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 7 - 1 / (double)16, true, dm_wb, dm_s422, 7), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, true, dm_wb, dm_s422, 3), 9);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(3 * 9 - 1 / (double)16, true, dm_wb, dm_s422, 9), 26);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17 + 1 / (double)3, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.40, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.50, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.75, true, dm_wb, dm_s422, 7), 17);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.95, true, dm_wb, dm_s422, 7), 17);
+
+	/* Display Port output with DSC disabled for 4:2:0 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, false, dm_dp, dm_420, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, false, dm_dp, dm_420, 10), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.01, false, dm_dp, dm_420, 0), 15);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15, false, dm_dp, dm_420, 8), 15);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12.01, false, dm_dp, dm_420, 0), 12);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(12, false, dm_dp, dm_420, 5), 12);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(11.99, false, dm_dp, dm_420, 5), BPP_INVALID);
+
+	/* Embedded Display Port output with DSC disabled for 4:2:2 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, false, dm_edp, dm_s422, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, false, dm_edp, dm_n422, 10), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(20.01, false, dm_edp, dm_s422, 0), 20);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(20, false, dm_edp, dm_n422, 8), 20);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16.01, false, dm_edp, dm_s422, 0), 16);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(16, false, dm_edp, dm_n422, 5), 16);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(15.99, false, dm_edp, dm_s422, 5), BPP_INVALID);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(-1, false, dm_edp, dm_n422, 5), BPP_INVALID);
+
+	/* WB output with DSC disabled for 4:4:4 encoding */
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36.01, false, dm_wb, dm_444, 0), 36);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(36, false, dm_wb, dm_444, 10), 36);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30.01, false, dm_wb, dm_444, 0), 30);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(30, false, dm_wb, dm_444, 8), 30);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24.01, false, dm_wb, dm_444, 0), 24);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(24, false, dm_wb, dm_444, 5), 24);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18.01, false, dm_wb, dm_444, 0), 18);
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(18, false, dm_wb, dm_444, 5), 18);
+
+	KUNIT_EXPECT_EQ(test, TruncToValidBPP(17.99, false, dm_wb, dm_444, 5), BPP_INVALID);
+}
+
+static const struct calculate_write_back_delay_test_case calculate_write_back_delay_cases[] = {
+	{
+		.desc = "Trivial test",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 0,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "High Writeback HRatio and VRatio and zeroed taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2400.0,
+		.writeback_VRatio = 2500.0,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 0,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "Simple Writeback Ratio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.2cap+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 2567.56,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400,
+		.calculate_write_back_delay = 0x1.61p+9,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+	{
+		.desc = "No Writeback to Luma Taps",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.5,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 3700,
+		.calculate_write_back_delay = 0x1p+2,
+	},
+	{
+		.desc = "High Writeback HRatio and VRatio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 2500000.0,
+		.writeback_VRatio = 2000000.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 3400,
+		.calculate_write_back_delay = 0x1.be4cd8p-10,
+	},
+	{
+		.desc = "Increase numeric error by increasing taps' Writeback",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 3000.0,
+		.writeback_VRatio = 2450.0,
+		.writeback_luma_HTaps = 100,
+		.writeback_luma_VTaps = 100,
+		.writeback_chroma_HTaps = 200,
+		.writeback_chroma_VTaps = 200,
+		.writeback_destination_width = 1687,
+		.calculate_write_back_delay = 0x1.49eap+15,
+	},
+	{
+		.desc = "Turning point of the Writeback HRatio and VRatio",
+		.writeback_pixel_format = dm_444_32,
+		.writeback_HRatio = 100000.0,
+		.writeback_VRatio = 100000.0,
+		.writeback_luma_HTaps = 100,
+		.writeback_luma_VTaps = 100,
+		.writeback_chroma_HTaps = 200,
+		.writeback_chroma_VTaps = 200,
+		.writeback_destination_width = 1687,
+		.calculate_write_back_delay = 0x1.b06ccap-2,
+	},
+	{
+		.desc = "Simple Writeback Ratio for 4:4:4 8-bit encoding",
+		.writeback_pixel_format = dm_444_8,
+		.writeback_HRatio = 1.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 4,
+		.writeback_luma_VTaps = 4,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+	{
+		.desc = "Non-integer WritebackVRatio with same number of Luma and Chroma taps for 4:4:4 64-bit encoding",
+		.writeback_pixel_format = dm_444_64,
+		.writeback_HRatio = 100000.0,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 7,
+		.writeback_luma_VTaps = 7,
+		.writeback_chroma_HTaps = 7,
+		.writeback_chroma_VTaps = 7,
+		.writeback_destination_width = 400,
+		.calculate_write_back_delay = 0x1.ceae7cp-8,
+	},
+	{
+		.desc = "No Writeback to Chroma Taps for 4:2:0 8-bit encoding",
+		.writeback_pixel_format = dm_420_8,
+		.writeback_HRatio = 100000.00,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 8,
+		.writeback_luma_VTaps = 8,
+		.writeback_chroma_HTaps = 0,
+		.writeback_chroma_VTaps = 0,
+		.writeback_destination_width = 1333,
+		.calculate_write_back_delay = 0x1.b6c2d6p-6,
+	},
+	{
+		.desc = "No Writeback to Luma Taps for 4:2:0 10-bit encoding",
+		.writeback_pixel_format = dm_420_10,
+		.writeback_HRatio = 200000.0,
+		.writeback_VRatio = 100000.56,
+		.writeback_luma_HTaps = 0,
+		.writeback_luma_VTaps = 0,
+		.writeback_chroma_HTaps = 3,
+		.writeback_chroma_VTaps = 3,
+		.writeback_destination_width = 996,
+		.calculate_write_back_delay = 0x1.ecd3f6p-9,
+	},
+	{
+		.desc = "Reduce numeric error by decreasing Writeback HRatio and VRatio for 4:4:4 16-bit encoding",
+		.writeback_pixel_format = dm_444_16,
+		.writeback_HRatio = 2.0,
+		.writeback_VRatio = 1.0,
+		.writeback_luma_HTaps = 5,
+		.writeback_luma_VTaps = 5,
+		.writeback_chroma_HTaps = 5,
+		.writeback_chroma_VTaps = 5,
+		.writeback_destination_width = 2400.0,
+		.calculate_write_back_delay = 0x1.77cp+11,
+	},
+};
+
+static const struct calculate_active_row_bandwidth_test_case calculate_active_row_bandwidth_cases[] = {
+	{
+		.desc = "Trivial Test",
+		.GPUVM_enable = false,
+		.source_pixel_format = -1,
+		.VRatio = 0.00,
+		.DCC_enable = false,
+		.line_time = 0.00,
+		.meta_row_byte_luma = 0,
+		.meta_row_byte_chroma = 0,
+		.meta_row_height_luma = 0,
+		.meta_row_height_chroma = 0,
+		.pixel_PTE_bytes_per_row_luma = 0,
+		.pixel_PTE_bytes_per_row_chroma = 0,
+		.dpte_row_height_luma = 0,
+		.dpte_row_height_chroma = 0,
+		.meta_row_bw = 0.00,
+		.dpte_row_bw = 0.00,
+		.qual_row_bw = 0.00,
+	},
+	{
+		.desc = "Zeroed Bandwidth with non-zeroed values",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0.00,
+		.dpte_row_bw = 0.00,
+		.qual_row_bw = 0.00,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.eb851eb851eb8p-4,
+		.qual_row_bw = 0x1.eb851eb851eb8p-4,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.0cb3a88722f67p-4,
+		.qual_row_bw = 0x1.0cb3a88722f67p-4,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:2:0 12-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_12,
+		.VRatio = 100.00,
+		.DCC_enable = false,
+		.line_time = 100.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 2,
+		.pixel_PTE_bytes_per_row_chroma = 2,
+		.dpte_row_height_luma = 10,
+		.dpte_row_height_chroma = 10,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.999999999999ap-3,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC not enabled with 4:4:4 16-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_16,
+		.VRatio = 1000.00,
+		.DCC_enable = false,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x0p+0,
+		.dpte_row_bw = 0x1.408e78356d141p-5,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 1000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.f333333333333p-1,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x1.f333333333333p-1,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.4888888888889p-1,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x1.4888888888889p-1,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:2:2 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_422_8,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.3873873873874p-2,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM not enabled and DCC enabled with 4:4:4 8-bit encoding",
+		.GPUVM_enable = false,
+		.source_pixel_format = dm_444_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 2000.00,
+		.meta_row_byte_luma = 190,
+		.meta_row_byte_chroma = 333,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 210,
+		.pixel_PTE_bytes_per_row_luma = 9,
+		.pixel_PTE_bytes_per_row_chroma = 9,
+		.dpte_row_height_luma = 230,
+		.dpte_row_height_chroma = 170,
+		.meta_row_bw = 0x1.e666666666666p-2,
+		.dpte_row_bw = 0x0p+0,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:2:0 8-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_8,
+		.VRatio = 1000.00,
+		.DCC_enable = true,
+		.line_time = 2000.00,
+		.meta_row_byte_luma = 120,
+		.meta_row_byte_chroma = 150,
+		.meta_row_height_luma = 200,
+		.meta_row_height_chroma = 200,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.f333333333333p-2,
+		.dpte_row_bw = 0x1.eb851eb851eb8p-5,
+		.qual_row_bw = 0x1.1851eb851eb85p-1,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:2:0 10-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_420_10,
+		.VRatio = 7000.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.9aaaaaaaaaaaap+2,
+		.dpte_row_bw = 0x1.4ad4ad4ad4ad5p-1,
+		.qual_row_bw = 0x1.c405405405405p+2,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:4:4 16-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_16,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 70,
+		.meta_row_byte_chroma = 550,
+		.meta_row_height_luma = 310,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 7,
+		.pixel_PTE_bytes_per_row_chroma = 7,
+		.dpte_row_height_luma = 190,
+		.dpte_row_height_chroma = 340,
+		.meta_row_bw = 0x1.f2065a3416de5p-4,
+		.dpte_row_bw = 0x1.4506d72a14507p-6,
+		.qual_row_bw = 0x0p+0,
+	},
+	{
+		.desc = "GPUVM enabled and DCC enabled with 4:4:4 32-bit encoding",
+		.GPUVM_enable = true,
+		.source_pixel_format = dm_444_32,
+		.VRatio = 700.00,
+		.DCC_enable = true,
+		.line_time = 1300.00,
+		.meta_row_byte_luma = 170,
+		.meta_row_byte_chroma = 350,
+		.meta_row_height_luma = 300,
+		.meta_row_height_chroma = 280,
+		.pixel_PTE_bytes_per_row_luma = 8,
+		.pixel_PTE_bytes_per_row_chroma = 8,
+		.dpte_row_height_luma = 100,
+		.dpte_row_height_chroma = 100,
+		.meta_row_bw = 0x1.3873873873874p-2,
+		.dpte_row_bw = 0x1.60e2dafa7c749p-5,
+		.qual_row_bw = 0x0p+0,
+	},
+};
+
+static void calculate_write_back_delay_test_to_desc(const struct
+		calculate_write_back_delay_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_write_back_delay, calculate_write_back_delay_cases,
+		  calculate_write_back_delay_test_to_desc);
+
+static void calculate_active_row_bandwidth_test_to_desc(const struct
+		calculate_active_row_bandwidth_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(calculate_active_row_bandwidth, calculate_active_row_bandwidth_cases,
+		  calculate_active_row_bandwidth_test_to_desc);
+
+static struct kunit_case display_mode_vba_20_cases[] = {
+	KUNIT_CASE(dscce_compute_delay_test),
+	KUNIT_CASE(DSC_compute_delay_test),
+	KUNIT_CASE(calculate_TWait_test),
+	KUNIT_CASE_PARAM(calculate_write_back_delay_test, calculate_write_back_delay_gen_params),
+	KUNIT_CASE_PARAM(calculate_active_row_bandwidth_test,
+			 calculate_active_row_bandwidth_gen_params),
+	KUNIT_CASE(trunc_to_valid_BPP_test),
+	{  }
+};
+
+static struct kunit_suite display_mode_vba_20_suite = {
+	.name = "display_mode_vba_20",
+	.test_cases = display_mode_vba_20_cases,
+};
+
+kunit_test_suite(display_mode_vba_20_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 6/8] drm/amd/display: Introduce KUnit tests for dcn20_fpu
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

From: Magali Lemes <magalilemes00@gmail.com>

This commit adds unit tests to the functions dcn20_cap_soc_clocks and
dcn21_update_bw_bounding_box from dcn20/dcn20_fpu.

Signed-off-by: Magali Lemes <magalilemes00@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/tests/Makefile    |   3 +-
 .../tests/dc/dml/dcn20/dcn20_fpu_test.c       | 561 ++++++++++++++++++
 2 files changed, 563 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c

diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
index cc1e9edd38c3..a34677808e48 100644
--- a/drivers/gpu/drm/amd/display/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -9,7 +9,8 @@ endif
 
 ifdef CONFIG_DML_KUNIT_TEST
 	CFLAGS_$(AMDDALPATH)/tests/dc/dml/display_mode_vba_test.o := $(dml_ccflags)
-	DC_TESTS += dc/dml/display_mode_vba_test.o
+	CFLAGS_$(AMDDALPATH)/tests/dc/dml/dcn20/dcn20_fpu_test.o := $(dml_ccflags)
+	DC_TESTS += dc/dml/display_mode_vba_test.o dc/dml/dcn20/dcn20_fpu_test.o
 endif
 
 AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
new file mode 100644
index 000000000000..6b7ebb78fec9
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/dcn20_fpu.h
+ *
+ * Copyright (C) 2022, Magali Lemes <magalilemes00@gmail.com>
+ */
+
+#include <kunit/test.h>
+
+#include "dc/inc/resource.h"
+#include "dc/inc/hw/clk_mgr.h"
+#include "dc/dcn21/dcn21_resource.h"
+
+#include "dml/dcn20/dcn20_fpu.h"
+
+/**
+ * DOC: Unit tests for AMDGPU DML dcn20/dcn20_fpu.h
+ */
+
+struct dcn20_cap_soc_clocks_test_case {
+	const char *desc;
+	struct _vcs_dpi_soc_bounding_box_st bb;
+	struct pp_smu_nv_clock_table max_clocks;
+	const int clock_states;
+	const struct _vcs_dpi_voltage_scaling_st expected_clock_limits[DC__VOLTAGE_STATES];
+};
+
+struct dcn21_update_bw_bounding_box_test_case {
+	const char *desc;
+	struct dc dc;
+	struct clk_bw_params bw_params;
+	const int clocks_to_compare;
+	const struct _vcs_dpi_voltage_scaling_st expected_clock_limits[DC__VOLTAGE_STATES];
+};
+
+struct dcn20_cap_soc_clocks_test_case dcn20_cap_soc_clocks_test_cases[] = {
+	{
+		.desc = "4-state bounding box clock limits ",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+				{
+					.dcfclk_mhz = 540.0,
+					.fabricclk_mhz = 540.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 540.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 8000.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 1265.0,
+					.fabricclk_mhz = 1266.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 1266.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 15000.0,
+				},
+			},
+			.num_states = 4,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 1265000,
+			.uClockInKhz = 875000,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 1284000,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 810000,
+			.socClockInKhz = 1266000,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 4,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.dcfclk_mhz = 540.0,
+				.fabricclk_mhz = 540.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 540.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 8000.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+			{
+				.dcfclk_mhz = 1265.0,
+				.fabricclk_mhz = 1266.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 1266.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 14000.0,
+			},
+		},
+	},
+	{
+		.desc = "One duplicate clock state",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 1265.0,
+					.fabricclk_mhz = 1266.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 1266.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 15000.0,
+				},
+			},
+			.num_states = 4,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 1265000,
+			.uClockInKhz = 875000,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 1284000,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 810000,
+			.socClockInKhz = 1266000,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 3,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+		},
+	},
+	{
+		.desc = "Zeroed max clocks",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+			},
+			.num_states = 1,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 0,
+			.uClockInKhz = 0,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 0,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 0,
+			.socClockInKhz = 0,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 1,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+		},
+	},
+};
+
+struct dcn21_update_bw_bounding_box_test_case dcn21_update_bw_bounding_box_test_data[] = {
+	{
+		.desc = "5-entry bounding box clocks table",
+		.dc = {
+			.res_pool = &(struct resource_pool) {
+				.pipe_count = 2,
+				.res_cap = &(struct resource_caps) {
+					.num_timing_generator = 3
+				},
+			},
+		},
+		.bw_params = {
+			.num_channels = 1,
+			.clk_table = {
+				.entries = {
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 200,
+						.fclk_mhz = 400,
+						.memclk_mhz = 800,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 201,
+						.fclk_mhz = 800,
+						.memclk_mhz = 1600,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 553,
+						.fclk_mhz = 1067,
+						.memclk_mhz = 1067,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 602,
+						.fclk_mhz = 1333,
+						.memclk_mhz = 1600,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dispclk_mhz = 1372,
+						.dppclk_mhz = 1372,
+						.phyclk_mhz = 810,
+						.phyclk_d18_mhz = 667,
+						.dtbclk_mhz = 600,
+					},
+				},
+
+				.num_entries = 5,
+			},
+		},
+		.expected_clock_limits = {
+			{
+				.state = 0,
+				.dcfclk_mhz = 200.0,
+				.fabricclk_mhz = 400.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.state = 1,
+				.dcfclk_mhz = 200.0,
+				.fabricclk_mhz = 400.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.state = 2,
+				.dcfclk_mhz = 201,
+				.fabricclk_mhz = 800.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 3200.0,
+			},
+			{
+				.state = 3,
+				.dcfclk_mhz = 553.0,
+				.fabricclk_mhz = 1067.0,
+				.dispclk_mhz = 757.89,
+				.dppclk_mhz = 685.71,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 287.67,
+				.dram_speed_mts = 2134.0,
+			},
+			{
+				.state = 4,
+				.dcfclk_mhz = 602.0,
+				.fabricclk_mhz = 1333.0,
+				.dispclk_mhz = 847.06,
+				.dppclk_mhz = 757.89,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 318.334,
+				.dram_speed_mts = 3200.0,
+			},
+			{
+				.state = 5,
+				.dcfclk_mhz = 0.0,
+				.fabricclk_mhz = 0.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 0.0,
+			},
+			{
+				.state = 6,
+				.dcfclk_mhz = 0.0,
+				.fabricclk_mhz = 0.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 0.0,
+			},
+		},
+		.clocks_to_compare = 6,
+	},
+};
+
+/**
+ * dcn20_cap_soc_clocks_test - KUnit test for dcn20_cap_soc_clocks
+ * @test: represents a running instance of a test.
+ */
+static void dcn20_cap_soc_clocks_test(struct kunit *test)
+{
+	struct dcn20_cap_soc_clocks_test_case *test_param =
+		(struct dcn20_cap_soc_clocks_test_case *)test->param_value;
+	int i;
+
+	DC_FP_START();
+	dcn20_cap_soc_clocks(&test_param->bb, test_param->max_clocks);
+	DC_FP_END();
+
+	/* Check if no clock limit is higher than the specified maximum */
+	for (i = 0; i < test_param->bb.num_states; i++) {
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dcfclk_mhz,
+				test_param->expected_clock_limits[i].dcfclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].fabricclk_mhz,
+				test_param->expected_clock_limits[i].fabricclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dispclk_mhz,
+				test_param->expected_clock_limits[i].dispclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dppclk_mhz,
+				test_param->expected_clock_limits[i].dppclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].phyclk_mhz,
+				test_param->expected_clock_limits[i].phyclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].socclk_mhz,
+				test_param->expected_clock_limits[i].socclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dscclk_mhz,
+				test_param->expected_clock_limits[i].dscclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dram_speed_mts,
+				test_param->expected_clock_limits[i].dram_speed_mts);
+	}
+
+	KUNIT_EXPECT_EQ(test, test_param->clock_states, test_param->bb.num_states);
+}
+
+static struct _vcs_dpi_soc_bounding_box_st original_dcn2_1_soc;
+static struct _vcs_dpi_ip_params_st original_dcn2_1_ip;
+
+/**
+ * dcn20_fpu_dcn21_update_bw_bounding_box_test_init - Store backup copies of DCN global structures
+ * @test: represents a running instance of a test.
+ */
+int dcn20_fpu_dcn21_update_bw_bounding_box_test_init(struct kunit *test)
+{
+	memcpy(&original_dcn2_1_soc, &dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
+	memcpy(&original_dcn2_1_ip, &dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
+
+	return 0;
+}
+
+/**
+ * dcn20_fpu_dcn21_update_bw_bounding_box_test_exit - Restore original values
+ * of DCN global structures
+ * @test: represents a running instance of a test.
+ */
+static void dcn20_fpu_dcn21_update_bw_bounding_box_test_exit(struct kunit *test)
+{
+	memcpy(&dcn2_1_soc, &original_dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
+	memcpy(&dcn2_1_ip, &original_dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
+}
+
+/**
+ * dcn21_update_bw_bounding_box_test - KUnit test for dcn21_update_bw_bounding_box
+ * @test: represents a running instance of a test.
+ */
+static void dcn21_update_bw_bounding_box_test(struct kunit *test)
+{
+	struct dcn21_update_bw_bounding_box_test_case *test_param =
+		(struct dcn21_update_bw_bounding_box_test_case *)test->param_value;
+	int i;
+
+	DC_FP_START();
+	dcn21_update_bw_bounding_box(&test_param->dc, &test_param->bw_params);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->dc.res_pool->res_cap->num_timing_generator,
+			dcn2_1_ip.max_num_otg);
+	KUNIT_EXPECT_EQ(test, test_param->dc.res_pool->pipe_count, dcn2_1_ip.max_num_dpp);
+	KUNIT_EXPECT_EQ(test, test_param->bw_params.num_channels, dcn2_1_soc.num_chans);
+
+	for (i = 0; i <= test_param->clocks_to_compare; i++) {
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].state,
+				dcn2_1_soc.clock_limits[i].state);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dcfclk_mhz,
+				dcn2_1_soc.clock_limits[i].dcfclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].fabricclk_mhz,
+				dcn2_1_soc.clock_limits[i].fabricclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dispclk_mhz,
+				dcn2_1_soc.clock_limits[i].dispclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dppclk_mhz,
+				dcn2_1_soc.clock_limits[i].dppclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].phyclk_mhz,
+				dcn2_1_soc.clock_limits[i].phyclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].socclk_mhz,
+				dcn2_1_soc.clock_limits[i].socclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dscclk_mhz,
+				dcn2_1_soc.clock_limits[i].dscclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dram_speed_mts,
+				dcn2_1_soc.clock_limits[i].dram_speed_mts);
+	}
+
+	if (test_param->bw_params.clk_table.num_entries)
+		KUNIT_EXPECT_EQ(test, test_param->bw_params.clk_table.num_entries,
+				dcn2_1_soc.num_states);
+}
+
+static void dcn20_cap_soc_clocks_test_to_desc(struct dcn20_cap_soc_clocks_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+static void dcn21_update_bw_bounding_box_test_to_desc
+(struct dcn21_update_bw_bounding_box_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(dcn20_cap_soc_clocks,
+		  dcn20_cap_soc_clocks_test_cases,
+		  dcn20_cap_soc_clocks_test_to_desc);
+
+static struct kunit_case dcn20_fpu_test_cases[] = {
+	KUNIT_CASE_PARAM(dcn20_cap_soc_clocks_test, dcn20_cap_soc_clocks_gen_params),
+	{  }
+};
+
+static struct kunit_suite dcn20_fpu_test_suite = {
+	.name = "dml_dcn20_fpu",
+	.test_cases = dcn20_fpu_test_cases,
+};
+
+KUNIT_ARRAY_PARAM(dcn21_update_bw_bounding_box,
+		  dcn21_update_bw_bounding_box_test_data,
+		  dcn21_update_bw_bounding_box_test_to_desc);
+
+static struct kunit_case dcn20_fpu_dcn21_update_bw_bounding_box_test_cases[] = {
+	KUNIT_CASE_PARAM(dcn21_update_bw_bounding_box_test,
+			 dcn21_update_bw_bounding_box_gen_params),
+	{  }
+};
+
+static struct kunit_suite dcn21_update_bw_bounding_box_test_suite = {
+	.name = "dml_dcn20_fpu_dcn21_update_bw_bounding_box_test",
+	.init = dcn20_fpu_dcn21_update_bw_bounding_box_test_init,
+	.exit = dcn20_fpu_dcn21_update_bw_bounding_box_test_exit,
+	.test_cases = dcn20_fpu_dcn21_update_bw_bounding_box_test_cases,
+};
+
+kunit_test_suites(&dcn20_fpu_test_suite, &dcn21_update_bw_bounding_box_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 6/8] drm/amd/display: Introduce KUnit tests for dcn20_fpu
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

From: Magali Lemes <magalilemes00@gmail.com>

This commit adds unit tests to the functions dcn20_cap_soc_clocks and
dcn21_update_bw_bounding_box from dcn20/dcn20_fpu.

Signed-off-by: Magali Lemes <magalilemes00@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/tests/Makefile    |   3 +-
 .../tests/dc/dml/dcn20/dcn20_fpu_test.c       | 561 ++++++++++++++++++
 2 files changed, 563 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c

diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
index cc1e9edd38c3..a34677808e48 100644
--- a/drivers/gpu/drm/amd/display/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -9,7 +9,8 @@ endif
 
 ifdef CONFIG_DML_KUNIT_TEST
 	CFLAGS_$(AMDDALPATH)/tests/dc/dml/display_mode_vba_test.o := $(dml_ccflags)
-	DC_TESTS += dc/dml/display_mode_vba_test.o
+	CFLAGS_$(AMDDALPATH)/tests/dc/dml/dcn20/dcn20_fpu_test.o := $(dml_ccflags)
+	DC_TESTS += dc/dml/display_mode_vba_test.o dc/dml/dcn20/dcn20_fpu_test.o
 endif
 
 AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
new file mode 100644
index 000000000000..6b7ebb78fec9
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/dcn20_fpu.h
+ *
+ * Copyright (C) 2022, Magali Lemes <magalilemes00@gmail.com>
+ */
+
+#include <kunit/test.h>
+
+#include "dc/inc/resource.h"
+#include "dc/inc/hw/clk_mgr.h"
+#include "dc/dcn21/dcn21_resource.h"
+
+#include "dml/dcn20/dcn20_fpu.h"
+
+/**
+ * DOC: Unit tests for AMDGPU DML dcn20/dcn20_fpu.h
+ */
+
+struct dcn20_cap_soc_clocks_test_case {
+	const char *desc;
+	struct _vcs_dpi_soc_bounding_box_st bb;
+	struct pp_smu_nv_clock_table max_clocks;
+	const int clock_states;
+	const struct _vcs_dpi_voltage_scaling_st expected_clock_limits[DC__VOLTAGE_STATES];
+};
+
+struct dcn21_update_bw_bounding_box_test_case {
+	const char *desc;
+	struct dc dc;
+	struct clk_bw_params bw_params;
+	const int clocks_to_compare;
+	const struct _vcs_dpi_voltage_scaling_st expected_clock_limits[DC__VOLTAGE_STATES];
+};
+
+struct dcn20_cap_soc_clocks_test_case dcn20_cap_soc_clocks_test_cases[] = {
+	{
+		.desc = "4-state bounding box clock limits ",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+				{
+					.dcfclk_mhz = 540.0,
+					.fabricclk_mhz = 540.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 540.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 8000.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 1265.0,
+					.fabricclk_mhz = 1266.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 1266.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 15000.0,
+				},
+			},
+			.num_states = 4,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 1265000,
+			.uClockInKhz = 875000,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 1284000,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 810000,
+			.socClockInKhz = 1266000,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 4,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.dcfclk_mhz = 540.0,
+				.fabricclk_mhz = 540.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 540.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 8000.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+			{
+				.dcfclk_mhz = 1265.0,
+				.fabricclk_mhz = 1266.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 1266.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 14000.0,
+			},
+		},
+	},
+	{
+		.desc = "One duplicate clock state",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 1265.0,
+					.fabricclk_mhz = 1266.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 1266.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 15000.0,
+				},
+			},
+			.num_states = 4,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 1265000,
+			.uClockInKhz = 875000,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 1284000,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 810000,
+			.socClockInKhz = 1266000,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 3,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+		},
+	},
+	{
+		.desc = "Zeroed max clocks",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+			},
+			.num_states = 1,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 0,
+			.uClockInKhz = 0,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 0,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 0,
+			.socClockInKhz = 0,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 1,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+		},
+	},
+};
+
+struct dcn21_update_bw_bounding_box_test_case dcn21_update_bw_bounding_box_test_data[] = {
+	{
+		.desc = "5-entry bounding box clocks table",
+		.dc = {
+			.res_pool = &(struct resource_pool) {
+				.pipe_count = 2,
+				.res_cap = &(struct resource_caps) {
+					.num_timing_generator = 3
+				},
+			},
+		},
+		.bw_params = {
+			.num_channels = 1,
+			.clk_table = {
+				.entries = {
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 200,
+						.fclk_mhz = 400,
+						.memclk_mhz = 800,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 201,
+						.fclk_mhz = 800,
+						.memclk_mhz = 1600,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 553,
+						.fclk_mhz = 1067,
+						.memclk_mhz = 1067,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 602,
+						.fclk_mhz = 1333,
+						.memclk_mhz = 1600,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dispclk_mhz = 1372,
+						.dppclk_mhz = 1372,
+						.phyclk_mhz = 810,
+						.phyclk_d18_mhz = 667,
+						.dtbclk_mhz = 600,
+					},
+				},
+
+				.num_entries = 5,
+			},
+		},
+		.expected_clock_limits = {
+			{
+				.state = 0,
+				.dcfclk_mhz = 200.0,
+				.fabricclk_mhz = 400.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.state = 1,
+				.dcfclk_mhz = 200.0,
+				.fabricclk_mhz = 400.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.state = 2,
+				.dcfclk_mhz = 201,
+				.fabricclk_mhz = 800.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 3200.0,
+			},
+			{
+				.state = 3,
+				.dcfclk_mhz = 553.0,
+				.fabricclk_mhz = 1067.0,
+				.dispclk_mhz = 757.89,
+				.dppclk_mhz = 685.71,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 287.67,
+				.dram_speed_mts = 2134.0,
+			},
+			{
+				.state = 4,
+				.dcfclk_mhz = 602.0,
+				.fabricclk_mhz = 1333.0,
+				.dispclk_mhz = 847.06,
+				.dppclk_mhz = 757.89,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 318.334,
+				.dram_speed_mts = 3200.0,
+			},
+			{
+				.state = 5,
+				.dcfclk_mhz = 0.0,
+				.fabricclk_mhz = 0.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 0.0,
+			},
+			{
+				.state = 6,
+				.dcfclk_mhz = 0.0,
+				.fabricclk_mhz = 0.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 0.0,
+			},
+		},
+		.clocks_to_compare = 6,
+	},
+};
+
+/**
+ * dcn20_cap_soc_clocks_test - KUnit test for dcn20_cap_soc_clocks
+ * @test: represents a running instance of a test.
+ */
+static void dcn20_cap_soc_clocks_test(struct kunit *test)
+{
+	struct dcn20_cap_soc_clocks_test_case *test_param =
+		(struct dcn20_cap_soc_clocks_test_case *)test->param_value;
+	int i;
+
+	DC_FP_START();
+	dcn20_cap_soc_clocks(&test_param->bb, test_param->max_clocks);
+	DC_FP_END();
+
+	/* Check if no clock limit is higher than the specified maximum */
+	for (i = 0; i < test_param->bb.num_states; i++) {
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dcfclk_mhz,
+				test_param->expected_clock_limits[i].dcfclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].fabricclk_mhz,
+				test_param->expected_clock_limits[i].fabricclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dispclk_mhz,
+				test_param->expected_clock_limits[i].dispclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dppclk_mhz,
+				test_param->expected_clock_limits[i].dppclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].phyclk_mhz,
+				test_param->expected_clock_limits[i].phyclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].socclk_mhz,
+				test_param->expected_clock_limits[i].socclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dscclk_mhz,
+				test_param->expected_clock_limits[i].dscclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dram_speed_mts,
+				test_param->expected_clock_limits[i].dram_speed_mts);
+	}
+
+	KUNIT_EXPECT_EQ(test, test_param->clock_states, test_param->bb.num_states);
+}
+
+static struct _vcs_dpi_soc_bounding_box_st original_dcn2_1_soc;
+static struct _vcs_dpi_ip_params_st original_dcn2_1_ip;
+
+/**
+ * dcn20_fpu_dcn21_update_bw_bounding_box_test_init - Store backup copies of DCN global structures
+ * @test: represents a running instance of a test.
+ */
+int dcn20_fpu_dcn21_update_bw_bounding_box_test_init(struct kunit *test)
+{
+	memcpy(&original_dcn2_1_soc, &dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
+	memcpy(&original_dcn2_1_ip, &dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
+
+	return 0;
+}
+
+/**
+ * dcn20_fpu_dcn21_update_bw_bounding_box_test_exit - Restore original values
+ * of DCN global structures
+ * @test: represents a running instance of a test.
+ */
+static void dcn20_fpu_dcn21_update_bw_bounding_box_test_exit(struct kunit *test)
+{
+	memcpy(&dcn2_1_soc, &original_dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
+	memcpy(&dcn2_1_ip, &original_dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
+}
+
+/**
+ * dcn21_update_bw_bounding_box_test - KUnit test for dcn21_update_bw_bounding_box
+ * @test: represents a running instance of a test.
+ */
+static void dcn21_update_bw_bounding_box_test(struct kunit *test)
+{
+	struct dcn21_update_bw_bounding_box_test_case *test_param =
+		(struct dcn21_update_bw_bounding_box_test_case *)test->param_value;
+	int i;
+
+	DC_FP_START();
+	dcn21_update_bw_bounding_box(&test_param->dc, &test_param->bw_params);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->dc.res_pool->res_cap->num_timing_generator,
+			dcn2_1_ip.max_num_otg);
+	KUNIT_EXPECT_EQ(test, test_param->dc.res_pool->pipe_count, dcn2_1_ip.max_num_dpp);
+	KUNIT_EXPECT_EQ(test, test_param->bw_params.num_channels, dcn2_1_soc.num_chans);
+
+	for (i = 0; i <= test_param->clocks_to_compare; i++) {
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].state,
+				dcn2_1_soc.clock_limits[i].state);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dcfclk_mhz,
+				dcn2_1_soc.clock_limits[i].dcfclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].fabricclk_mhz,
+				dcn2_1_soc.clock_limits[i].fabricclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dispclk_mhz,
+				dcn2_1_soc.clock_limits[i].dispclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dppclk_mhz,
+				dcn2_1_soc.clock_limits[i].dppclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].phyclk_mhz,
+				dcn2_1_soc.clock_limits[i].phyclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].socclk_mhz,
+				dcn2_1_soc.clock_limits[i].socclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dscclk_mhz,
+				dcn2_1_soc.clock_limits[i].dscclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dram_speed_mts,
+				dcn2_1_soc.clock_limits[i].dram_speed_mts);
+	}
+
+	if (test_param->bw_params.clk_table.num_entries)
+		KUNIT_EXPECT_EQ(test, test_param->bw_params.clk_table.num_entries,
+				dcn2_1_soc.num_states);
+}
+
+static void dcn20_cap_soc_clocks_test_to_desc(struct dcn20_cap_soc_clocks_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+static void dcn21_update_bw_bounding_box_test_to_desc
+(struct dcn21_update_bw_bounding_box_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(dcn20_cap_soc_clocks,
+		  dcn20_cap_soc_clocks_test_cases,
+		  dcn20_cap_soc_clocks_test_to_desc);
+
+static struct kunit_case dcn20_fpu_test_cases[] = {
+	KUNIT_CASE_PARAM(dcn20_cap_soc_clocks_test, dcn20_cap_soc_clocks_gen_params),
+	{  }
+};
+
+static struct kunit_suite dcn20_fpu_test_suite = {
+	.name = "dml_dcn20_fpu",
+	.test_cases = dcn20_fpu_test_cases,
+};
+
+KUNIT_ARRAY_PARAM(dcn21_update_bw_bounding_box,
+		  dcn21_update_bw_bounding_box_test_data,
+		  dcn21_update_bw_bounding_box_test_to_desc);
+
+static struct kunit_case dcn20_fpu_dcn21_update_bw_bounding_box_test_cases[] = {
+	KUNIT_CASE_PARAM(dcn21_update_bw_bounding_box_test,
+			 dcn21_update_bw_bounding_box_gen_params),
+	{  }
+};
+
+static struct kunit_suite dcn21_update_bw_bounding_box_test_suite = {
+	.name = "dml_dcn20_fpu_dcn21_update_bw_bounding_box_test",
+	.init = dcn20_fpu_dcn21_update_bw_bounding_box_test_init,
+	.exit = dcn20_fpu_dcn21_update_bw_bounding_box_test_exit,
+	.test_cases = dcn20_fpu_dcn21_update_bw_bounding_box_test_cases,
+};
+
+kunit_test_suites(&dcn20_fpu_test_suite, &dcn21_update_bw_bounding_box_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 6/8] drm/amd/display: Introduce KUnit tests for dcn20_fpu
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

From: Magali Lemes <magalilemes00@gmail.com>

This commit adds unit tests to the functions dcn20_cap_soc_clocks and
dcn21_update_bw_bounding_box from dcn20/dcn20_fpu.

Signed-off-by: Magali Lemes <magalilemes00@gmail.com>
Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/tests/Makefile    |   3 +-
 .../tests/dc/dml/dcn20/dcn20_fpu_test.c       | 561 ++++++++++++++++++
 2 files changed, 563 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c

diff --git a/drivers/gpu/drm/amd/display/tests/Makefile b/drivers/gpu/drm/amd/display/tests/Makefile
index cc1e9edd38c3..a34677808e48 100644
--- a/drivers/gpu/drm/amd/display/tests/Makefile
+++ b/drivers/gpu/drm/amd/display/tests/Makefile
@@ -9,7 +9,8 @@ endif
 
 ifdef CONFIG_DML_KUNIT_TEST
 	CFLAGS_$(AMDDALPATH)/tests/dc/dml/display_mode_vba_test.o := $(dml_ccflags)
-	DC_TESTS += dc/dml/display_mode_vba_test.o
+	CFLAGS_$(AMDDALPATH)/tests/dc/dml/dcn20/dcn20_fpu_test.o := $(dml_ccflags)
+	DC_TESTS += dc/dml/display_mode_vba_test.o dc/dml/dcn20/dcn20_fpu_test.o
 endif
 
 AMD_DAL_DC_TESTS = $(addprefix $(AMDDALPATH)/tests/,$(DC_TESTS))
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
new file mode 100644
index 000000000000..6b7ebb78fec9
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dml/dcn20/dcn20_fpu_test.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: MIT
+/*
+ * KUnit tests for dml/dcn20/dcn20_fpu.h
+ *
+ * Copyright (C) 2022, Magali Lemes <magalilemes00@gmail.com>
+ */
+
+#include <kunit/test.h>
+
+#include "dc/inc/resource.h"
+#include "dc/inc/hw/clk_mgr.h"
+#include "dc/dcn21/dcn21_resource.h"
+
+#include "dml/dcn20/dcn20_fpu.h"
+
+/**
+ * DOC: Unit tests for AMDGPU DML dcn20/dcn20_fpu.h
+ */
+
+struct dcn20_cap_soc_clocks_test_case {
+	const char *desc;
+	struct _vcs_dpi_soc_bounding_box_st bb;
+	struct pp_smu_nv_clock_table max_clocks;
+	const int clock_states;
+	const struct _vcs_dpi_voltage_scaling_st expected_clock_limits[DC__VOLTAGE_STATES];
+};
+
+struct dcn21_update_bw_bounding_box_test_case {
+	const char *desc;
+	struct dc dc;
+	struct clk_bw_params bw_params;
+	const int clocks_to_compare;
+	const struct _vcs_dpi_voltage_scaling_st expected_clock_limits[DC__VOLTAGE_STATES];
+};
+
+struct dcn20_cap_soc_clocks_test_case dcn20_cap_soc_clocks_test_cases[] = {
+	{
+		.desc = "4-state bounding box clock limits ",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+				{
+					.dcfclk_mhz = 540.0,
+					.fabricclk_mhz = 540.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 540.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 8000.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 1265.0,
+					.fabricclk_mhz = 1266.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 1266.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 15000.0,
+				},
+			},
+			.num_states = 4,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 1265000,
+			.uClockInKhz = 875000,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 1284000,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 810000,
+			.socClockInKhz = 1266000,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 4,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.dcfclk_mhz = 540.0,
+				.fabricclk_mhz = 540.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 540.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 8000.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+			{
+				.dcfclk_mhz = 1265.0,
+				.fabricclk_mhz = 1266.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 1266.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 14000.0,
+			},
+		},
+	},
+	{
+		.desc = "One duplicate clock state",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 675.0,
+					.fabricclk_mhz = 675.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 675.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 10000.0,
+				},
+				{
+					.dcfclk_mhz = 1265.0,
+					.fabricclk_mhz = 1266.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 1284.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 1266.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 15000.0,
+				},
+			},
+			.num_states = 4,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 1265000,
+			.uClockInKhz = 875000,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 1284000,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 810000,
+			.socClockInKhz = 1266000,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 3,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+			{
+				.dcfclk_mhz = 675.0,
+				.fabricclk_mhz = 675.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 1284.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 675.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 10000.0,
+			},
+		},
+	},
+	{
+		.desc = "Zeroed max clocks",
+		.bb = {
+			.clock_limits = {
+				{
+					.dcfclk_mhz = 506.0,
+					.fabricclk_mhz = 506.0,
+					.dispclk_mhz = 1284.0,
+					.dppclk_mhz = 400.0,
+					.phyclk_mhz = 810.0,
+					.socclk_mhz = 506.0,
+					.dscclk_mhz = 428.0,
+					.dram_speed_mts = 1600.0,
+				},
+			},
+			.num_states = 1,
+		},
+		.max_clocks = {
+			.dcfClockInKhz = 0,
+			.uClockInKhz = 0,
+			.fabricClockInKhz = 0,
+			.displayClockInKhz = 0,
+			.dppClockInKhz = 0,
+			.phyClockInKhz = 0,
+			.socClockInKhz = 0,
+			.dscClockInKhz = 0,
+		},
+		.clock_states = 1,
+		.expected_clock_limits = {
+			{
+				.dcfclk_mhz = 506.0,
+				.fabricclk_mhz = 506.0,
+				.dispclk_mhz = 1284.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 810.0,
+				.socclk_mhz = 506.0,
+				.dscclk_mhz = 428.0,
+				.dram_speed_mts = 1600.0,
+			},
+		},
+	},
+};
+
+struct dcn21_update_bw_bounding_box_test_case dcn21_update_bw_bounding_box_test_data[] = {
+	{
+		.desc = "5-entry bounding box clocks table",
+		.dc = {
+			.res_pool = &(struct resource_pool) {
+				.pipe_count = 2,
+				.res_cap = &(struct resource_caps) {
+					.num_timing_generator = 3
+				},
+			},
+		},
+		.bw_params = {
+			.num_channels = 1,
+			.clk_table = {
+				.entries = {
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 200,
+						.fclk_mhz = 400,
+						.memclk_mhz = 800,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 201,
+						.fclk_mhz = 800,
+						.memclk_mhz = 1600,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 553,
+						.fclk_mhz = 1067,
+						.memclk_mhz = 1067,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dcfclk_mhz = 602,
+						.fclk_mhz = 1333,
+						.memclk_mhz = 1600,
+						.socclk_mhz = 0,
+					},
+					{
+						.voltage = 0,
+						.dispclk_mhz = 1372,
+						.dppclk_mhz = 1372,
+						.phyclk_mhz = 810,
+						.phyclk_d18_mhz = 667,
+						.dtbclk_mhz = 600,
+					},
+				},
+
+				.num_entries = 5,
+			},
+		},
+		.expected_clock_limits = {
+			{
+				.state = 0,
+				.dcfclk_mhz = 200.0,
+				.fabricclk_mhz = 400.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.state = 1,
+				.dcfclk_mhz = 200.0,
+				.fabricclk_mhz = 400.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 1600.0,
+			},
+			{
+				.state = 2,
+				.dcfclk_mhz = 201,
+				.fabricclk_mhz = 800.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 3200.0,
+			},
+			{
+				.state = 3,
+				.dcfclk_mhz = 553.0,
+				.fabricclk_mhz = 1067.0,
+				.dispclk_mhz = 757.89,
+				.dppclk_mhz = 685.71,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 287.67,
+				.dram_speed_mts = 2134.0,
+			},
+			{
+				.state = 4,
+				.dcfclk_mhz = 602.0,
+				.fabricclk_mhz = 1333.0,
+				.dispclk_mhz = 847.06,
+				.dppclk_mhz = 757.89,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 318.334,
+				.dram_speed_mts = 3200.0,
+			},
+			{
+				.state = 5,
+				.dcfclk_mhz = 0.0,
+				.fabricclk_mhz = 0.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 0.0,
+			},
+			{
+				.state = 6,
+				.dcfclk_mhz = 0.0,
+				.fabricclk_mhz = 0.0,
+				.dispclk_mhz = 600.0,
+				.dppclk_mhz = 400.0,
+				.phyclk_mhz = 600.0,
+				.socclk_mhz = 0.0,
+				.dscclk_mhz = 205.67,
+				.dram_speed_mts = 0.0,
+			},
+		},
+		.clocks_to_compare = 6,
+	},
+};
+
+/**
+ * dcn20_cap_soc_clocks_test - KUnit test for dcn20_cap_soc_clocks
+ * @test: represents a running instance of a test.
+ */
+static void dcn20_cap_soc_clocks_test(struct kunit *test)
+{
+	struct dcn20_cap_soc_clocks_test_case *test_param =
+		(struct dcn20_cap_soc_clocks_test_case *)test->param_value;
+	int i;
+
+	DC_FP_START();
+	dcn20_cap_soc_clocks(&test_param->bb, test_param->max_clocks);
+	DC_FP_END();
+
+	/* Check if no clock limit is higher than the specified maximum */
+	for (i = 0; i < test_param->bb.num_states; i++) {
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dcfclk_mhz,
+				test_param->expected_clock_limits[i].dcfclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].fabricclk_mhz,
+				test_param->expected_clock_limits[i].fabricclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dispclk_mhz,
+				test_param->expected_clock_limits[i].dispclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dppclk_mhz,
+				test_param->expected_clock_limits[i].dppclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].phyclk_mhz,
+				test_param->expected_clock_limits[i].phyclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].socclk_mhz,
+				test_param->expected_clock_limits[i].socclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dscclk_mhz,
+				test_param->expected_clock_limits[i].dscclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->bb.clock_limits[i].dram_speed_mts,
+				test_param->expected_clock_limits[i].dram_speed_mts);
+	}
+
+	KUNIT_EXPECT_EQ(test, test_param->clock_states, test_param->bb.num_states);
+}
+
+static struct _vcs_dpi_soc_bounding_box_st original_dcn2_1_soc;
+static struct _vcs_dpi_ip_params_st original_dcn2_1_ip;
+
+/**
+ * dcn20_fpu_dcn21_update_bw_bounding_box_test_init - Store backup copies of DCN global structures
+ * @test: represents a running instance of a test.
+ */
+int dcn20_fpu_dcn21_update_bw_bounding_box_test_init(struct kunit *test)
+{
+	memcpy(&original_dcn2_1_soc, &dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
+	memcpy(&original_dcn2_1_ip, &dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
+
+	return 0;
+}
+
+/**
+ * dcn20_fpu_dcn21_update_bw_bounding_box_test_exit - Restore original values
+ * of DCN global structures
+ * @test: represents a running instance of a test.
+ */
+static void dcn20_fpu_dcn21_update_bw_bounding_box_test_exit(struct kunit *test)
+{
+	memcpy(&dcn2_1_soc, &original_dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
+	memcpy(&dcn2_1_ip, &original_dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
+}
+
+/**
+ * dcn21_update_bw_bounding_box_test - KUnit test for dcn21_update_bw_bounding_box
+ * @test: represents a running instance of a test.
+ */
+static void dcn21_update_bw_bounding_box_test(struct kunit *test)
+{
+	struct dcn21_update_bw_bounding_box_test_case *test_param =
+		(struct dcn21_update_bw_bounding_box_test_case *)test->param_value;
+	int i;
+
+	DC_FP_START();
+	dcn21_update_bw_bounding_box(&test_param->dc, &test_param->bw_params);
+	DC_FP_END();
+
+	KUNIT_EXPECT_EQ(test, test_param->dc.res_pool->res_cap->num_timing_generator,
+			dcn2_1_ip.max_num_otg);
+	KUNIT_EXPECT_EQ(test, test_param->dc.res_pool->pipe_count, dcn2_1_ip.max_num_dpp);
+	KUNIT_EXPECT_EQ(test, test_param->bw_params.num_channels, dcn2_1_soc.num_chans);
+
+	for (i = 0; i <= test_param->clocks_to_compare; i++) {
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].state,
+				dcn2_1_soc.clock_limits[i].state);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dcfclk_mhz,
+				dcn2_1_soc.clock_limits[i].dcfclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].fabricclk_mhz,
+				dcn2_1_soc.clock_limits[i].fabricclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dispclk_mhz,
+				dcn2_1_soc.clock_limits[i].dispclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dppclk_mhz,
+				dcn2_1_soc.clock_limits[i].dppclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].phyclk_mhz,
+				dcn2_1_soc.clock_limits[i].phyclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].socclk_mhz,
+				dcn2_1_soc.clock_limits[i].socclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dscclk_mhz,
+				dcn2_1_soc.clock_limits[i].dscclk_mhz);
+		KUNIT_EXPECT_EQ(test, test_param->expected_clock_limits[i].dram_speed_mts,
+				dcn2_1_soc.clock_limits[i].dram_speed_mts);
+	}
+
+	if (test_param->bw_params.clk_table.num_entries)
+		KUNIT_EXPECT_EQ(test, test_param->bw_params.clk_table.num_entries,
+				dcn2_1_soc.num_states);
+}
+
+static void dcn20_cap_soc_clocks_test_to_desc(struct dcn20_cap_soc_clocks_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+static void dcn21_update_bw_bounding_box_test_to_desc
+(struct dcn21_update_bw_bounding_box_test_case *t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(dcn20_cap_soc_clocks,
+		  dcn20_cap_soc_clocks_test_cases,
+		  dcn20_cap_soc_clocks_test_to_desc);
+
+static struct kunit_case dcn20_fpu_test_cases[] = {
+	KUNIT_CASE_PARAM(dcn20_cap_soc_clocks_test, dcn20_cap_soc_clocks_gen_params),
+	{  }
+};
+
+static struct kunit_suite dcn20_fpu_test_suite = {
+	.name = "dml_dcn20_fpu",
+	.test_cases = dcn20_fpu_test_cases,
+};
+
+KUNIT_ARRAY_PARAM(dcn21_update_bw_bounding_box,
+		  dcn21_update_bw_bounding_box_test_data,
+		  dcn21_update_bw_bounding_box_test_to_desc);
+
+static struct kunit_case dcn20_fpu_dcn21_update_bw_bounding_box_test_cases[] = {
+	KUNIT_CASE_PARAM(dcn21_update_bw_bounding_box_test,
+			 dcn21_update_bw_bounding_box_gen_params),
+	{  }
+};
+
+static struct kunit_suite dcn21_update_bw_bounding_box_test_suite = {
+	.name = "dml_dcn20_fpu_dcn21_update_bw_bounding_box_test",
+	.init = dcn20_fpu_dcn21_update_bw_bounding_box_test_init,
+	.exit = dcn20_fpu_dcn21_update_bw_bounding_box_test_exit,
+	.test_cases = dcn20_fpu_dcn21_update_bw_bounding_box_test_cases,
+};
+
+kunit_test_suites(&dcn20_fpu_test_suite, &dcn21_update_bw_bounding_box_test_suite);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 7/8] drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

Add unit test to the SubVP feature in order to avoid possible
regressions and assure the code robustness.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 +
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   1 +
 .../amd/display/tests/dc/dc_dmub_srv_test.c   | 285 ++++++++++++++++++
 4 files changed, 303 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 039227baedfa..f667b954f89f 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -93,4 +93,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
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index cd7225d98b3d..86f78fe017a6 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -819,3 +819,7 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
 		diag_data.is_cw0_enabled,
 		diag_data.is_cw6_enabled);
 }
+
+#if IS_ENABLED(CONFIG_AMD_DC_KUNIT_TEST)
+#include "../tests/dc/dc_dmub_srv_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index eb6f81601757..4c5861ad58bd 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -4,5 +4,6 @@ CONFIG_DRM=y
 CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
 CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+CONFIG_AMD_DC_KUNIT_TEST=y
 CONFIG_DCE_KUNIT_TEST=y
 CONFIG_DML_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c b/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
new file mode 100644
index 000000000000..3f1f15397090
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
@@ -0,0 +1,285 @@
+// 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"
+
+struct populate_subvp_cmd_drr_info_test_case {
+	const char *desc;
+	struct dc *dc;
+	struct pipe_ctx *subvp_pipe;
+	struct pipe_ctx *vblank_pipe;
+	const u8 drr_in_use;
+	const u8 drr_window_size_ms;
+	const u16 min_vtotal_supported;
+	const u16 max_vtotal_supported;
+	const u8 use_ramping;
+};
+
+struct populate_subvp_cmd_drr_info_test_case populate_subvp_cmd_drr_info_cases[] = {
+	{
+		.desc = "Same Clock Frequency",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 1111,
+							.v_addressable = 1080,
+							.v_front_porch = 3,
+							.pix_clk_100hz = 1855800,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_total = 1111,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 63709,
+		.max_vtotal_supported = 363,
+	},
+	{
+		.desc = "Same Clock Frequency with Prefetch End to Mall Start",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 500,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 1111,
+							.v_addressable = 1080,
+							.v_front_porch = 3,
+							.pix_clk_100hz = 1855800,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_total = 1111,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 63709,
+		.max_vtotal_supported = 346,
+	},
+	{
+		.desc = "Same Clock Frequency Not Multiple of 2",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1866743,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 2400,
+							.v_addressable = 2360,
+							.v_front_porch = 4,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 3600,
+					.v_total = 2400,
+					.v_addressable = 2360,
+					.pix_clk_100hz = 1866743,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 1387,
+		.max_vtotal_supported = 399,
+	},
+	{
+		.desc = "Different Clock Frequency for smaller h_total and v_total",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 300,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_addressable = 600,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 1280,
+							.v_total = 720,
+							.v_addressable = 600,
+							.v_front_porch = 4,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_total = 720,
+					.v_addressable = 600,
+					.pix_clk_100hz = 2100800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 1477,
+		.max_vtotal_supported = 212,
+	},
+	{
+		.desc = "Different Clock Frequency for approximately 1920x1080",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1920,
+					.v_addressable = 1000,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 1911,
+							.v_total = 1080,
+							.v_addressable = 1000,
+							.v_front_porch = 7,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_total = 720,
+					.v_addressable = 600,
+					.pix_clk_100hz = 2100800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 2482,
+		.max_vtotal_supported = 247,
+	},
+};
+
+static void populate_subvp_cmd_drr_info_test_to_desc(struct
+		populate_subvp_cmd_drr_info_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(populate_subvp_cmd_drr_info, populate_subvp_cmd_drr_info_cases,
+		  populate_subvp_cmd_drr_info_test_to_desc);
+
+static void populate_subvp_cmd_drr_info_test(struct kunit *test)
+{
+	const struct populate_subvp_cmd_drr_info_test_case *test_param =
+		test->param_value;
+	struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data;
+
+	pipe_data = kunit_kzalloc(test,
+				  sizeof(struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2),
+				  GFP_KERNEL);
+
+	populate_subvp_cmd_drr_info(test_param->dc, test_param->subvp_pipe,
+				    test_param->vblank_pipe, pipe_data);
+
+	KUNIT_EXPECT_EQ(test, test_param->drr_in_use,
+			pipe_data->pipe_config.vblank_data.drr_info.drr_in_use);
+	KUNIT_EXPECT_EQ(test, test_param->drr_window_size_ms,
+			pipe_data->pipe_config.vblank_data.drr_info.drr_window_size_ms);
+	KUNIT_EXPECT_EQ(test, test_param->use_ramping,
+			pipe_data->pipe_config.vblank_data.drr_info.use_ramping);
+	KUNIT_EXPECT_EQ(test, test_param->min_vtotal_supported,
+			pipe_data->pipe_config.vblank_data.drr_info.min_vtotal_supported);
+	KUNIT_EXPECT_EQ(test, test_param->max_vtotal_supported,
+			pipe_data->pipe_config.vblank_data.drr_info.max_vtotal_supported);
+}
+
+static struct kunit_case dc_dmub_srv_cases[] = {
+	KUNIT_CASE_PARAM(populate_subvp_cmd_drr_info_test, populate_subvp_cmd_drr_info_gen_params),
+	{  }
+};
+
+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);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 7/8] drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

Add unit test to the SubVP feature in order to avoid possible
regressions and assure the code robustness.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 +
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   1 +
 .../amd/display/tests/dc/dc_dmub_srv_test.c   | 285 ++++++++++++++++++
 4 files changed, 303 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 039227baedfa..f667b954f89f 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -93,4 +93,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
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index cd7225d98b3d..86f78fe017a6 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -819,3 +819,7 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
 		diag_data.is_cw0_enabled,
 		diag_data.is_cw6_enabled);
 }
+
+#if IS_ENABLED(CONFIG_AMD_DC_KUNIT_TEST)
+#include "../tests/dc/dc_dmub_srv_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index eb6f81601757..4c5861ad58bd 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -4,5 +4,6 @@ CONFIG_DRM=y
 CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
 CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+CONFIG_AMD_DC_KUNIT_TEST=y
 CONFIG_DCE_KUNIT_TEST=y
 CONFIG_DML_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c b/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
new file mode 100644
index 000000000000..3f1f15397090
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
@@ -0,0 +1,285 @@
+// 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"
+
+struct populate_subvp_cmd_drr_info_test_case {
+	const char *desc;
+	struct dc *dc;
+	struct pipe_ctx *subvp_pipe;
+	struct pipe_ctx *vblank_pipe;
+	const u8 drr_in_use;
+	const u8 drr_window_size_ms;
+	const u16 min_vtotal_supported;
+	const u16 max_vtotal_supported;
+	const u8 use_ramping;
+};
+
+struct populate_subvp_cmd_drr_info_test_case populate_subvp_cmd_drr_info_cases[] = {
+	{
+		.desc = "Same Clock Frequency",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 1111,
+							.v_addressable = 1080,
+							.v_front_porch = 3,
+							.pix_clk_100hz = 1855800,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_total = 1111,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 63709,
+		.max_vtotal_supported = 363,
+	},
+	{
+		.desc = "Same Clock Frequency with Prefetch End to Mall Start",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 500,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 1111,
+							.v_addressable = 1080,
+							.v_front_porch = 3,
+							.pix_clk_100hz = 1855800,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_total = 1111,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 63709,
+		.max_vtotal_supported = 346,
+	},
+	{
+		.desc = "Same Clock Frequency Not Multiple of 2",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1866743,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 2400,
+							.v_addressable = 2360,
+							.v_front_porch = 4,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 3600,
+					.v_total = 2400,
+					.v_addressable = 2360,
+					.pix_clk_100hz = 1866743,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 1387,
+		.max_vtotal_supported = 399,
+	},
+	{
+		.desc = "Different Clock Frequency for smaller h_total and v_total",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 300,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_addressable = 600,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 1280,
+							.v_total = 720,
+							.v_addressable = 600,
+							.v_front_porch = 4,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_total = 720,
+					.v_addressable = 600,
+					.pix_clk_100hz = 2100800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 1477,
+		.max_vtotal_supported = 212,
+	},
+	{
+		.desc = "Different Clock Frequency for approximately 1920x1080",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1920,
+					.v_addressable = 1000,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 1911,
+							.v_total = 1080,
+							.v_addressable = 1000,
+							.v_front_porch = 7,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_total = 720,
+					.v_addressable = 600,
+					.pix_clk_100hz = 2100800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 2482,
+		.max_vtotal_supported = 247,
+	},
+};
+
+static void populate_subvp_cmd_drr_info_test_to_desc(struct
+		populate_subvp_cmd_drr_info_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(populate_subvp_cmd_drr_info, populate_subvp_cmd_drr_info_cases,
+		  populate_subvp_cmd_drr_info_test_to_desc);
+
+static void populate_subvp_cmd_drr_info_test(struct kunit *test)
+{
+	const struct populate_subvp_cmd_drr_info_test_case *test_param =
+		test->param_value;
+	struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data;
+
+	pipe_data = kunit_kzalloc(test,
+				  sizeof(struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2),
+				  GFP_KERNEL);
+
+	populate_subvp_cmd_drr_info(test_param->dc, test_param->subvp_pipe,
+				    test_param->vblank_pipe, pipe_data);
+
+	KUNIT_EXPECT_EQ(test, test_param->drr_in_use,
+			pipe_data->pipe_config.vblank_data.drr_info.drr_in_use);
+	KUNIT_EXPECT_EQ(test, test_param->drr_window_size_ms,
+			pipe_data->pipe_config.vblank_data.drr_info.drr_window_size_ms);
+	KUNIT_EXPECT_EQ(test, test_param->use_ramping,
+			pipe_data->pipe_config.vblank_data.drr_info.use_ramping);
+	KUNIT_EXPECT_EQ(test, test_param->min_vtotal_supported,
+			pipe_data->pipe_config.vblank_data.drr_info.min_vtotal_supported);
+	KUNIT_EXPECT_EQ(test, test_param->max_vtotal_supported,
+			pipe_data->pipe_config.vblank_data.drr_info.max_vtotal_supported);
+}
+
+static struct kunit_case dc_dmub_srv_cases[] = {
+	KUNIT_CASE_PARAM(populate_subvp_cmd_drr_info_test, populate_subvp_cmd_drr_info_gen_params),
+	{  }
+};
+
+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);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 7/8] drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

Add unit test to the SubVP feature in order to avoid possible
regressions and assure the code robustness.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 drivers/gpu/drm/amd/display/Kconfig           |  13 +
 drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c  |   4 +
 .../gpu/drm/amd/display/tests/.kunitconfig    |   1 +
 .../amd/display/tests/dc/dc_dmub_srv_test.c   | 285 ++++++++++++++++++
 4 files changed, 303 insertions(+)
 create mode 100644 drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c

diff --git a/drivers/gpu/drm/amd/display/Kconfig b/drivers/gpu/drm/amd/display/Kconfig
index 039227baedfa..f667b954f89f 100644
--- a/drivers/gpu/drm/amd/display/Kconfig
+++ b/drivers/gpu/drm/amd/display/Kconfig
@@ -93,4 +93,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
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
index cd7225d98b3d..86f78fe017a6 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
+++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
@@ -819,3 +819,7 @@ void dc_dmub_srv_log_diagnostic_data(struct dc_dmub_srv *dc_dmub_srv)
 		diag_data.is_cw0_enabled,
 		diag_data.is_cw6_enabled);
 }
+
+#if IS_ENABLED(CONFIG_AMD_DC_KUNIT_TEST)
+#include "../tests/dc/dc_dmub_srv_test.c"
+#endif
diff --git a/drivers/gpu/drm/amd/display/tests/.kunitconfig b/drivers/gpu/drm/amd/display/tests/.kunitconfig
index eb6f81601757..4c5861ad58bd 100644
--- a/drivers/gpu/drm/amd/display/tests/.kunitconfig
+++ b/drivers/gpu/drm/amd/display/tests/.kunitconfig
@@ -4,5 +4,6 @@ CONFIG_DRM=y
 CONFIG_DRM_AMDGPU=y
 CONFIG_DRM_AMD_DC=y
 CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+CONFIG_AMD_DC_KUNIT_TEST=y
 CONFIG_DCE_KUNIT_TEST=y
 CONFIG_DML_KUNIT_TEST=y
diff --git a/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c b/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
new file mode 100644
index 000000000000..3f1f15397090
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/tests/dc/dc_dmub_srv_test.c
@@ -0,0 +1,285 @@
+// 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"
+
+struct populate_subvp_cmd_drr_info_test_case {
+	const char *desc;
+	struct dc *dc;
+	struct pipe_ctx *subvp_pipe;
+	struct pipe_ctx *vblank_pipe;
+	const u8 drr_in_use;
+	const u8 drr_window_size_ms;
+	const u16 min_vtotal_supported;
+	const u16 max_vtotal_supported;
+	const u8 use_ramping;
+};
+
+struct populate_subvp_cmd_drr_info_test_case populate_subvp_cmd_drr_info_cases[] = {
+	{
+		.desc = "Same Clock Frequency",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 1111,
+							.v_addressable = 1080,
+							.v_front_porch = 3,
+							.pix_clk_100hz = 1855800,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_total = 1111,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 63709,
+		.max_vtotal_supported = 363,
+	},
+	{
+		.desc = "Same Clock Frequency with Prefetch End to Mall Start",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 500,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 1111,
+							.v_addressable = 1080,
+							.v_front_porch = 3,
+							.pix_clk_100hz = 1855800,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_total = 1111,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1855800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 63709,
+		.max_vtotal_supported = 346,
+	},
+	{
+		.desc = "Same Clock Frequency Not Multiple of 2",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 2784,
+					.v_addressable = 1080,
+					.pix_clk_100hz = 1866743,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 3600,
+							.v_total = 2400,
+							.v_addressable = 2360,
+							.v_front_porch = 4,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 3600,
+					.v_total = 2400,
+					.v_addressable = 2360,
+					.pix_clk_100hz = 1866743,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 1387,
+		.max_vtotal_supported = 399,
+	},
+	{
+		.desc = "Different Clock Frequency for smaller h_total and v_total",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 300,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_addressable = 600,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 1280,
+							.v_total = 720,
+							.v_addressable = 600,
+							.v_front_porch = 4,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_total = 720,
+					.v_addressable = 600,
+					.pix_clk_100hz = 2100800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 1477,
+		.max_vtotal_supported = 212,
+	},
+	{
+		.desc = "Different Clock Frequency for approximately 1920x1080",
+		.dc = &(struct dc) {
+			.caps = {
+				.subvp_prefetch_end_to_mall_start_us = 0,
+			}
+		},
+		.subvp_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1920,
+					.v_addressable = 1000,
+					.pix_clk_100hz = 1855800,
+				},
+				.mall_stream_config = {
+					.paired_stream = &(struct dc_stream_state) {
+						.timing = {
+							.h_total = 1911,
+							.v_total = 1080,
+							.v_addressable = 1000,
+							.v_front_porch = 7,
+							.pix_clk_100hz = 1866743,
+						},
+					},
+				},
+			},
+		},
+		.vblank_pipe = &(struct pipe_ctx) {
+			.stream = &(struct dc_stream_state) {
+				.timing = {
+					.h_total = 1280,
+					.v_total = 720,
+					.v_addressable = 600,
+					.pix_clk_100hz = 2100800,
+				},
+			},
+		},
+		.drr_in_use = true,
+		.use_ramping = false,
+		.drr_window_size_ms = 4,
+		.min_vtotal_supported = 2482,
+		.max_vtotal_supported = 247,
+	},
+};
+
+static void populate_subvp_cmd_drr_info_test_to_desc(struct
+		populate_subvp_cmd_drr_info_test_case * t, char *desc)
+{
+	strcpy(desc, t->desc);
+}
+
+KUNIT_ARRAY_PARAM(populate_subvp_cmd_drr_info, populate_subvp_cmd_drr_info_cases,
+		  populate_subvp_cmd_drr_info_test_to_desc);
+
+static void populate_subvp_cmd_drr_info_test(struct kunit *test)
+{
+	const struct populate_subvp_cmd_drr_info_test_case *test_param =
+		test->param_value;
+	struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data;
+
+	pipe_data = kunit_kzalloc(test,
+				  sizeof(struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2),
+				  GFP_KERNEL);
+
+	populate_subvp_cmd_drr_info(test_param->dc, test_param->subvp_pipe,
+				    test_param->vblank_pipe, pipe_data);
+
+	KUNIT_EXPECT_EQ(test, test_param->drr_in_use,
+			pipe_data->pipe_config.vblank_data.drr_info.drr_in_use);
+	KUNIT_EXPECT_EQ(test, test_param->drr_window_size_ms,
+			pipe_data->pipe_config.vblank_data.drr_info.drr_window_size_ms);
+	KUNIT_EXPECT_EQ(test, test_param->use_ramping,
+			pipe_data->pipe_config.vblank_data.drr_info.use_ramping);
+	KUNIT_EXPECT_EQ(test, test_param->min_vtotal_supported,
+			pipe_data->pipe_config.vblank_data.drr_info.min_vtotal_supported);
+	KUNIT_EXPECT_EQ(test, test_param->max_vtotal_supported,
+			pipe_data->pipe_config.vblank_data.drr_info.max_vtotal_supported);
+}
+
+static struct kunit_case dc_dmub_srv_cases[] = {
+	KUNIT_CASE_PARAM(populate_subvp_cmd_drr_info_test, populate_subvp_cmd_drr_info_gen_params),
+	{  }
+};
+
+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);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 8/8] Documentation/gpu: Add Display Core Unit Test documentation
  2022-08-31 17:22 ` Maíra Canal
  (?)
@ 2022-08-31 17:22   ` Maíra Canal
  -1 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid

Explain how to run the KUnit tests present in the AMDGPU's Display
Core and clarify which architectures and tools can be used to run
the tests. Moreover, explains how to add new tests to the existing
tests.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 .../gpu/amdgpu/display/display-test.rst       | 88 +++++++++++++++++++
 Documentation/gpu/amdgpu/display/index.rst    |  1 +
 2 files changed, 89 insertions(+)
 create mode 100644 Documentation/gpu/amdgpu/display/display-test.rst

diff --git a/Documentation/gpu/amdgpu/display/display-test.rst b/Documentation/gpu/amdgpu/display/display-test.rst
new file mode 100644
index 000000000000..a8c136ce87b7
--- /dev/null
+++ b/Documentation/gpu/amdgpu/display/display-test.rst
@@ -0,0 +1,88 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+========================
+Display Core Unit Tests
+========================
+
+Display core provides a set of unit tests, currently focused on the Display Mode
+Library. The unit tests use KUnit (Kernel Unit Testing Framework), a common
+framework for unit tests within the Linux Kernel.
+
+This section covers the specifics of the tests for the AMDGPU driver. For general
+information about KUnit, please refer to Documentation/dev-tools/kunit/start.rst.
+
+How to run the tests?
+=====================
+
+In order to facilitate running the test suite, a configuration file is present
+in ``drivers/gpu/drm/amd/display/tests/dc/.kunitconfig``. This configuration file
+can be used to run the kunit_tool, a Python script (``tools/testing/kunit/kunit.py``)
+used to configure, build, exec, parse and run tests.
+
+.. code-block:: bash
+
+	$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
+	    --kunitconfig=drivers/gpu/drm/amd/display/tests
+
+Currently, the Display Core Unit Tests are only supported on x86_64.
+
+Moreover, the tests can also be run on real hardware or in other emulation
+environments. To include the Display Core Unit Tests on a deployable kernel,
+you might add the following config options to your ``.config``:
+
+.. code-block:: none
+
+	CONFIG_KUNIT=y
+	CONFIG_AMDGPU=m
+	CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+	CONFIG_AMD_DC_KUNIT_TEST=y
+	CONFIG_DCE_KUNIT_TEST=y
+	CONFIG_DML_KUNIT_TEST=y
+
+Once the kernel is built and installed, you can load the ``amdgpu`` module
+to run all tests available.
+
+Also, the tests can be added to the kernel as built-in modules, by adding the
+following config options to your ``.config``:
+
+.. code-block:: none
+
+	CONFIG_KUNIT=y
+	CONFIG_AMDGPU=y
+	CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+	CONFIG_AMD_DC_KUNIT_TEST=y
+	CONFIG_DCE_KUNIT_TEST=y
+	CONFIG_DML_KUNIT_TEST=y
+
+In order to run specific tests, you can check the filter options from KUnit on
+Documentation/dev-tools/kunit/kunit-tool.rst.
+
+How to add new tests?
+=====================
+
+Tests covering different parts of the Display Core are always welcomed. Adding
+a new test is a simple procedure, that consists in creating a unit test file
+and adding the following guard to the end of the tested file when you are
+testing static functions:
+
+.. code-block:: c
+
+	#ifdef CONFIG_MY_KUNIT_TEST
+	#include "my_kunit_test.c"
+	#endif
+
+If you are not testing static functions, you should use the Makefile placed on
+``display/tests``. In order to add a test to the Makefile, you can just add
+the following entry to the Makefile:
+
+.. code-block:: make
+
+	ifdef CONFIG_MY_KUNIT_TEST
+		DC_TESTS += my_kunit_test.o
+	endif
+
+The ``display/tests`` folder replicates the folder hierarchy of the ``display``
+folder, so this must be considered while adding new tests.
+
+More information on how to write unit tests with the KUnit API can be provided
+on Documentation/dev-tools/kunit/api/test.rst.
diff --git a/Documentation/gpu/amdgpu/display/index.rst b/Documentation/gpu/amdgpu/display/index.rst
index c1fb2fb3c710..4f4e72e3e75f 100644
--- a/Documentation/gpu/amdgpu/display/index.rst
+++ b/Documentation/gpu/amdgpu/display/index.rst
@@ -28,4 +28,5 @@ table of content:
    display-manager.rst
    dc-debug.rst
    dcn-overview.rst
+   display-test.rst
    dc-glossary.rst
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 8/8] Documentation/gpu: Add Display Core Unit Test documentation
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kunit-dev, magalilemes00, tales.aparecida, linux-kernel, amd-gfx,
	mwen, Maíra Canal, dri-devel, Isabella Basso, andrealmeid,
	Trevor Woerner

Explain how to run the KUnit tests present in the AMDGPU's Display
Core and clarify which architectures and tools can be used to run
the tests. Moreover, explains how to add new tests to the existing
tests.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 .../gpu/amdgpu/display/display-test.rst       | 88 +++++++++++++++++++
 Documentation/gpu/amdgpu/display/index.rst    |  1 +
 2 files changed, 89 insertions(+)
 create mode 100644 Documentation/gpu/amdgpu/display/display-test.rst

diff --git a/Documentation/gpu/amdgpu/display/display-test.rst b/Documentation/gpu/amdgpu/display/display-test.rst
new file mode 100644
index 000000000000..a8c136ce87b7
--- /dev/null
+++ b/Documentation/gpu/amdgpu/display/display-test.rst
@@ -0,0 +1,88 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+========================
+Display Core Unit Tests
+========================
+
+Display core provides a set of unit tests, currently focused on the Display Mode
+Library. The unit tests use KUnit (Kernel Unit Testing Framework), a common
+framework for unit tests within the Linux Kernel.
+
+This section covers the specifics of the tests for the AMDGPU driver. For general
+information about KUnit, please refer to Documentation/dev-tools/kunit/start.rst.
+
+How to run the tests?
+=====================
+
+In order to facilitate running the test suite, a configuration file is present
+in ``drivers/gpu/drm/amd/display/tests/dc/.kunitconfig``. This configuration file
+can be used to run the kunit_tool, a Python script (``tools/testing/kunit/kunit.py``)
+used to configure, build, exec, parse and run tests.
+
+.. code-block:: bash
+
+	$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
+	    --kunitconfig=drivers/gpu/drm/amd/display/tests
+
+Currently, the Display Core Unit Tests are only supported on x86_64.
+
+Moreover, the tests can also be run on real hardware or in other emulation
+environments. To include the Display Core Unit Tests on a deployable kernel,
+you might add the following config options to your ``.config``:
+
+.. code-block:: none
+
+	CONFIG_KUNIT=y
+	CONFIG_AMDGPU=m
+	CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+	CONFIG_AMD_DC_KUNIT_TEST=y
+	CONFIG_DCE_KUNIT_TEST=y
+	CONFIG_DML_KUNIT_TEST=y
+
+Once the kernel is built and installed, you can load the ``amdgpu`` module
+to run all tests available.
+
+Also, the tests can be added to the kernel as built-in modules, by adding the
+following config options to your ``.config``:
+
+.. code-block:: none
+
+	CONFIG_KUNIT=y
+	CONFIG_AMDGPU=y
+	CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+	CONFIG_AMD_DC_KUNIT_TEST=y
+	CONFIG_DCE_KUNIT_TEST=y
+	CONFIG_DML_KUNIT_TEST=y
+
+In order to run specific tests, you can check the filter options from KUnit on
+Documentation/dev-tools/kunit/kunit-tool.rst.
+
+How to add new tests?
+=====================
+
+Tests covering different parts of the Display Core are always welcomed. Adding
+a new test is a simple procedure, that consists in creating a unit test file
+and adding the following guard to the end of the tested file when you are
+testing static functions:
+
+.. code-block:: c
+
+	#ifdef CONFIG_MY_KUNIT_TEST
+	#include "my_kunit_test.c"
+	#endif
+
+If you are not testing static functions, you should use the Makefile placed on
+``display/tests``. In order to add a test to the Makefile, you can just add
+the following entry to the Makefile:
+
+.. code-block:: make
+
+	ifdef CONFIG_MY_KUNIT_TEST
+		DC_TESTS += my_kunit_test.o
+	endif
+
+The ``display/tests`` folder replicates the folder hierarchy of the ``display``
+folder, so this must be considered while adding new tests.
+
+More information on how to write unit tests with the KUnit API can be provided
+on Documentation/dev-tools/kunit/api/test.rst.
diff --git a/Documentation/gpu/amdgpu/display/index.rst b/Documentation/gpu/amdgpu/display/index.rst
index c1fb2fb3c710..4f4e72e3e75f 100644
--- a/Documentation/gpu/amdgpu/display/index.rst
+++ b/Documentation/gpu/amdgpu/display/index.rst
@@ -28,4 +28,5 @@ table of content:
    display-manager.rst
    dc-debug.rst
    dcn-overview.rst
+   display-test.rst
    dc-glossary.rst
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH v2 8/8] Documentation/gpu: Add Display Core Unit Test documentation
@ 2022-08-31 17:22   ` Maíra Canal
  0 siblings, 0 replies; 31+ messages in thread
From: Maíra Canal @ 2022-08-31 17:22 UTC (permalink / raw)
  To: Alex Deucher, christian.koenig, Xinhui.Pan, David Airlie,
	Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: andrealmeid, mwen, Isabella Basso, magalilemes00,
	tales.aparecida, Trevor Woerner, amd-gfx, dri-devel, kunit-dev,
	linux-kernel, Maíra Canal

Explain how to run the KUnit tests present in the AMDGPU's Display
Core and clarify which architectures and tools can be used to run
the tests. Moreover, explains how to add new tests to the existing
tests.

Signed-off-by: Maíra Canal <mairacanal@riseup.net>
---
 .../gpu/amdgpu/display/display-test.rst       | 88 +++++++++++++++++++
 Documentation/gpu/amdgpu/display/index.rst    |  1 +
 2 files changed, 89 insertions(+)
 create mode 100644 Documentation/gpu/amdgpu/display/display-test.rst

diff --git a/Documentation/gpu/amdgpu/display/display-test.rst b/Documentation/gpu/amdgpu/display/display-test.rst
new file mode 100644
index 000000000000..a8c136ce87b7
--- /dev/null
+++ b/Documentation/gpu/amdgpu/display/display-test.rst
@@ -0,0 +1,88 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+========================
+Display Core Unit Tests
+========================
+
+Display core provides a set of unit tests, currently focused on the Display Mode
+Library. The unit tests use KUnit (Kernel Unit Testing Framework), a common
+framework for unit tests within the Linux Kernel.
+
+This section covers the specifics of the tests for the AMDGPU driver. For general
+information about KUnit, please refer to Documentation/dev-tools/kunit/start.rst.
+
+How to run the tests?
+=====================
+
+In order to facilitate running the test suite, a configuration file is present
+in ``drivers/gpu/drm/amd/display/tests/dc/.kunitconfig``. This configuration file
+can be used to run the kunit_tool, a Python script (``tools/testing/kunit/kunit.py``)
+used to configure, build, exec, parse and run tests.
+
+.. code-block:: bash
+
+	$ ./tools/testing/kunit/kunit.py run --arch=x86_64 \
+	    --kunitconfig=drivers/gpu/drm/amd/display/tests
+
+Currently, the Display Core Unit Tests are only supported on x86_64.
+
+Moreover, the tests can also be run on real hardware or in other emulation
+environments. To include the Display Core Unit Tests on a deployable kernel,
+you might add the following config options to your ``.config``:
+
+.. code-block:: none
+
+	CONFIG_KUNIT=y
+	CONFIG_AMDGPU=m
+	CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+	CONFIG_AMD_DC_KUNIT_TEST=y
+	CONFIG_DCE_KUNIT_TEST=y
+	CONFIG_DML_KUNIT_TEST=y
+
+Once the kernel is built and installed, you can load the ``amdgpu`` module
+to run all tests available.
+
+Also, the tests can be added to the kernel as built-in modules, by adding the
+following config options to your ``.config``:
+
+.. code-block:: none
+
+	CONFIG_KUNIT=y
+	CONFIG_AMDGPU=y
+	CONFIG_AMD_DC_BASICS_KUNIT_TEST=y
+	CONFIG_AMD_DC_KUNIT_TEST=y
+	CONFIG_DCE_KUNIT_TEST=y
+	CONFIG_DML_KUNIT_TEST=y
+
+In order to run specific tests, you can check the filter options from KUnit on
+Documentation/dev-tools/kunit/kunit-tool.rst.
+
+How to add new tests?
+=====================
+
+Tests covering different parts of the Display Core are always welcomed. Adding
+a new test is a simple procedure, that consists in creating a unit test file
+and adding the following guard to the end of the tested file when you are
+testing static functions:
+
+.. code-block:: c
+
+	#ifdef CONFIG_MY_KUNIT_TEST
+	#include "my_kunit_test.c"
+	#endif
+
+If you are not testing static functions, you should use the Makefile placed on
+``display/tests``. In order to add a test to the Makefile, you can just add
+the following entry to the Makefile:
+
+.. code-block:: make
+
+	ifdef CONFIG_MY_KUNIT_TEST
+		DC_TESTS += my_kunit_test.o
+	endif
+
+The ``display/tests`` folder replicates the folder hierarchy of the ``display``
+folder, so this must be considered while adding new tests.
+
+More information on how to write unit tests with the KUnit API can be provided
+on Documentation/dev-tools/kunit/api/test.rst.
diff --git a/Documentation/gpu/amdgpu/display/index.rst b/Documentation/gpu/amdgpu/display/index.rst
index c1fb2fb3c710..4f4e72e3e75f 100644
--- a/Documentation/gpu/amdgpu/display/index.rst
+++ b/Documentation/gpu/amdgpu/display/index.rst
@@ -28,4 +28,5 @@ table of content:
    display-manager.rst
    dc-debug.rst
    dcn-overview.rst
+   display-test.rst
    dc-glossary.rst
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 7/8] drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
  2022-08-31 17:22   ` Maíra Canal
@ 2022-09-03 11:47     ` kernel test robot
  -1 siblings, 0 replies; 31+ messages in thread
From: kernel test robot @ 2022-09-03 11:47 UTC (permalink / raw)
  To: Maíra Canal, Alex Deucher, christian.koenig, Xinhui.Pan,
	David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kbuild-all, kunit-dev, magalilemes00, tales.aparecida,
	linux-kernel, amd-gfx, mwen, Maíra Canal, dri-devel,
	Isabella Basso, andrealmeid

Hi "Maíra,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on drm/drm-next drm-intel/for-linux-next drm-tip/drm-tip linus/master v6.0-rc3 next-20220901]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20220903/202209031904.Q8eJt6X4-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/510f486251586c33675dc1e1639f1b5fa2bd0da7
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
        git checkout 510f486251586c33675dc1e1639f1b5fa2bd0da7
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/dc_dmub_srv.c:814:
   drivers/gpu/drm/amd/amdgpu/../display/dc/../tests/dc/dc_dmub_srv_test.c: In function 'populate_subvp_cmd_drr_info_test':
>> drivers/gpu/drm/amd/amdgpu/../display/dc/../tests/dc/dc_dmub_srv_test.c:260:9: error: implicit declaration of function 'populate_subvp_cmd_drr_info'; did you mean 'populate_subvp_cmd_drr_info_test'? [-Werror=implicit-function-declaration]
     260 |         populate_subvp_cmd_drr_info(test_param->dc, test_param->subvp_pipe,
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
         |         populate_subvp_cmd_drr_info_test
   In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/inc/core_types.h:32,
                    from drivers/gpu/drm/amd/amdgpu/../display/dc/dc_dmub_srv.c:31:
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h: At top level:
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:137:22: warning: 'SYNAPTICS_DEVICE_ID' defined but not used [-Wunused-const-variable=]
     137 | static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA";
         |                      ^~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:134:17: warning: 'DP_SINK_BRANCH_DEV_NAME_7580' defined but not used [-Wunused-const-variable=]
     134 | static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u";
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:132:22: warning: 'DP_SINK_DEVICE_STR_ID_2' defined but not used [-Wunused-const-variable=]
     132 | static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:131:22: warning: 'DP_SINK_DEVICE_STR_ID_1' defined but not used [-Wunused-const-variable=]
     131 | static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +260 drivers/gpu/drm/amd/amdgpu/../display/dc/../tests/dc/dc_dmub_srv_test.c

   246	
   247	KUNIT_ARRAY_PARAM(populate_subvp_cmd_drr_info, populate_subvp_cmd_drr_info_cases,
   248			  populate_subvp_cmd_drr_info_test_to_desc);
   249	
   250	static void populate_subvp_cmd_drr_info_test(struct kunit *test)
   251	{
   252		const struct populate_subvp_cmd_drr_info_test_case *test_param =
   253			test->param_value;
   254		struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data;
   255	
   256		pipe_data = kunit_kzalloc(test,
   257					  sizeof(struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2),
   258					  GFP_KERNEL);
   259	
 > 260		populate_subvp_cmd_drr_info(test_param->dc, test_param->subvp_pipe,
   261					    test_param->vblank_pipe, pipe_data);
   262	
   263		KUNIT_EXPECT_EQ(test, test_param->drr_in_use,
   264				pipe_data->pipe_config.vblank_data.drr_info.drr_in_use);
   265		KUNIT_EXPECT_EQ(test, test_param->drr_window_size_ms,
   266				pipe_data->pipe_config.vblank_data.drr_info.drr_window_size_ms);
   267		KUNIT_EXPECT_EQ(test, test_param->use_ramping,
   268				pipe_data->pipe_config.vblank_data.drr_info.use_ramping);
   269		KUNIT_EXPECT_EQ(test, test_param->min_vtotal_supported,
   270				pipe_data->pipe_config.vblank_data.drr_info.min_vtotal_supported);
   271		KUNIT_EXPECT_EQ(test, test_param->max_vtotal_supported,
   272				pipe_data->pipe_config.vblank_data.drr_info.max_vtotal_supported);
   273	}
   274	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 7/8] drm/amd/display: Introduce KUnit tests to dc_dmub_srv library
@ 2022-09-03 11:47     ` kernel test robot
  0 siblings, 0 replies; 31+ messages in thread
From: kernel test robot @ 2022-09-03 11:47 UTC (permalink / raw)
  To: Maíra Canal, Alex Deucher, christian.koenig, Xinhui.Pan,
	David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kbuild-all, magalilemes00, tales.aparecida, linux-kernel,
	amd-gfx, mwen, Maíra Canal, dri-devel, Isabella Basso,
	andrealmeid, kunit-dev

Hi "Maíra,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on drm/drm-next drm-intel/for-linux-next drm-tip/drm-tip linus/master v6.0-rc3 next-20220901]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
config: sparc-allyesconfig (https://download.01.org/0day-ci/archive/20220903/202209031904.Q8eJt6X4-lkp@intel.com/config)
compiler: sparc64-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/intel-lab-lkp/linux/commit/510f486251586c33675dc1e1639f1b5fa2bd0da7
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
        git checkout 510f486251586c33675dc1e1639f1b5fa2bd0da7
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=sparc SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/dc_dmub_srv.c:814:
   drivers/gpu/drm/amd/amdgpu/../display/dc/../tests/dc/dc_dmub_srv_test.c: In function 'populate_subvp_cmd_drr_info_test':
>> drivers/gpu/drm/amd/amdgpu/../display/dc/../tests/dc/dc_dmub_srv_test.c:260:9: error: implicit declaration of function 'populate_subvp_cmd_drr_info'; did you mean 'populate_subvp_cmd_drr_info_test'? [-Werror=implicit-function-declaration]
     260 |         populate_subvp_cmd_drr_info(test_param->dc, test_param->subvp_pipe,
         |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
         |         populate_subvp_cmd_drr_info_test
   In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/inc/core_types.h:32,
                    from drivers/gpu/drm/amd/amdgpu/../display/dc/dc_dmub_srv.c:31:
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h: At top level:
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:137:22: warning: 'SYNAPTICS_DEVICE_ID' defined but not used [-Wunused-const-variable=]
     137 | static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA";
         |                      ^~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:134:17: warning: 'DP_SINK_BRANCH_DEV_NAME_7580' defined but not used [-Wunused-const-variable=]
     134 | static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u";
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:132:22: warning: 'DP_SINK_DEVICE_STR_ID_2' defined but not used [-Wunused-const-variable=]
     132 | static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:131:22: warning: 'DP_SINK_DEVICE_STR_ID_1' defined but not used [-Wunused-const-variable=]
     131 | static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~
   cc1: some warnings being treated as errors


vim +260 drivers/gpu/drm/amd/amdgpu/../display/dc/../tests/dc/dc_dmub_srv_test.c

   246	
   247	KUNIT_ARRAY_PARAM(populate_subvp_cmd_drr_info, populate_subvp_cmd_drr_info_cases,
   248			  populate_subvp_cmd_drr_info_test_to_desc);
   249	
   250	static void populate_subvp_cmd_drr_info_test(struct kunit *test)
   251	{
   252		const struct populate_subvp_cmd_drr_info_test_case *test_param =
   253			test->param_value;
   254		struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2 *pipe_data;
   255	
   256		pipe_data = kunit_kzalloc(test,
   257					  sizeof(struct dmub_cmd_fw_assisted_mclk_switch_pipe_data_v2),
   258					  GFP_KERNEL);
   259	
 > 260		populate_subvp_cmd_drr_info(test_param->dc, test_param->subvp_pipe,
   261					    test_param->vblank_pipe, pipe_data);
   262	
   263		KUNIT_EXPECT_EQ(test, test_param->drr_in_use,
   264				pipe_data->pipe_config.vblank_data.drr_info.drr_in_use);
   265		KUNIT_EXPECT_EQ(test, test_param->drr_window_size_ms,
   266				pipe_data->pipe_config.vblank_data.drr_info.drr_window_size_ms);
   267		KUNIT_EXPECT_EQ(test, test_param->use_ramping,
   268				pipe_data->pipe_config.vblank_data.drr_info.use_ramping);
   269		KUNIT_EXPECT_EQ(test, test_param->min_vtotal_supported,
   270				pipe_data->pipe_config.vblank_data.drr_info.min_vtotal_supported);
   271		KUNIT_EXPECT_EQ(test, test_param->max_vtotal_supported,
   272				pipe_data->pipe_config.vblank_data.drr_info.max_vtotal_supported);
   273	}
   274	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 6/8] drm/amd/display: Introduce KUnit tests for dcn20_fpu
  2022-08-31 17:22   ` Maíra Canal
@ 2022-09-03 19:50     ` kernel test robot
  -1 siblings, 0 replies; 31+ messages in thread
From: kernel test robot @ 2022-09-03 19:50 UTC (permalink / raw)
  To: Maíra Canal, Alex Deucher, christian.koenig, Xinhui.Pan,
	David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kbuild-all, kunit-dev, magalilemes00, tales.aparecida,
	linux-kernel, amd-gfx, mwen, Maíra Canal, dri-devel,
	Isabella Basso, andrealmeid

Hi "Maíra,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on drm/drm-next drm-intel/for-linux-next drm-tip/drm-tip linus/master v6.0-rc3 next-20220901]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20220904/202209040310.aa1jd14e-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-5) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/6b01e906d58654fb9c209fa848883658d203b073
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
        git checkout 6b01e906d58654fb9c209fa848883658d203b073
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/amd/amdgpu/../display/tests/dc/dml/dcn20/dcn20_fpu_test.c:455:5: warning: no previous prototype for 'dcn20_fpu_dcn21_update_bw_bounding_box_test_init' [-Wmissing-prototypes]
     455 | int dcn20_fpu_dcn21_update_bw_bounding_box_test_init(struct kunit *test)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/inc/core_types.h:32,
                    from drivers/gpu/drm/amd/amdgpu/../display/dc/inc/resource.h:28,
                    from drivers/gpu/drm/amd/amdgpu/../display/tests/dc/dml/dcn20/dcn20_fpu_test.c:10:
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:137:22: warning: 'SYNAPTICS_DEVICE_ID' defined but not used [-Wunused-const-variable=]
     137 | static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA";
         |                      ^~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:134:17: warning: 'DP_SINK_BRANCH_DEV_NAME_7580' defined but not used [-Wunused-const-variable=]
     134 | static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u";
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:132:22: warning: 'DP_SINK_DEVICE_STR_ID_2' defined but not used [-Wunused-const-variable=]
     132 | static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:131:22: warning: 'DP_SINK_DEVICE_STR_ID_1' defined but not used [-Wunused-const-variable=]
     131 | static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~


vim +/dcn20_fpu_dcn21_update_bw_bounding_box_test_init +455 drivers/gpu/drm/amd/amdgpu/../display/tests/dc/dml/dcn20/dcn20_fpu_test.c

   450	
   451	/**
   452	 * dcn20_fpu_dcn21_update_bw_bounding_box_test_init - Store backup copies of DCN global structures
   453	 * @test: represents a running instance of a test.
   454	 */
 > 455	int dcn20_fpu_dcn21_update_bw_bounding_box_test_init(struct kunit *test)
   456	{
   457		memcpy(&original_dcn2_1_soc, &dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
   458		memcpy(&original_dcn2_1_ip, &dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
   459	
   460		return 0;
   461	}
   462	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH v2 6/8] drm/amd/display: Introduce KUnit tests for dcn20_fpu
@ 2022-09-03 19:50     ` kernel test robot
  0 siblings, 0 replies; 31+ messages in thread
From: kernel test robot @ 2022-09-03 19:50 UTC (permalink / raw)
  To: Maíra Canal, Alex Deucher, christian.koenig, Xinhui.Pan,
	David Airlie, Daniel Vetter, Maarten Lankhorst, Maxime Ripard,
	Thomas Zimmermann, Jonathan Corbet, Harry Wentland, Leo Li,
	Rodrigo Siqueira, Daniel Latypov, David Gow
  Cc: kbuild-all, magalilemes00, tales.aparecida, linux-kernel,
	amd-gfx, mwen, Maíra Canal, dri-devel, Isabella Basso,
	andrealmeid, kunit-dev

Hi "Maíra,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on drm-misc/drm-misc-next]
[also build test WARNING on drm/drm-next drm-intel/for-linux-next drm-tip/drm-tip linus/master v6.0-rc3 next-20220901]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
base:   git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20220904/202209040310.aa1jd14e-lkp@intel.com/config)
compiler: gcc-11 (Debian 11.3.0-5) 11.3.0
reproduce (this is a W=1 build):
        # https://github.com/intel-lab-lkp/linux/commit/6b01e906d58654fb9c209fa848883658d203b073
        git remote add linux-review https://github.com/intel-lab-lkp/linux
        git fetch --no-tags linux-review Ma-ra-Canal/drm-amd-display-Introduce-KUnit-to-Display-Mode-Library/20220901-012715
        git checkout 6b01e906d58654fb9c209fa848883658d203b073
        # save the config file
        mkdir build_dir && cp config build_dir/.config
        make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash

If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

>> drivers/gpu/drm/amd/amdgpu/../display/tests/dc/dml/dcn20/dcn20_fpu_test.c:455:5: warning: no previous prototype for 'dcn20_fpu_dcn21_update_bw_bounding_box_test_init' [-Wmissing-prototypes]
     455 | int dcn20_fpu_dcn21_update_bw_bounding_box_test_init(struct kunit *test)
         |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from drivers/gpu/drm/amd/amdgpu/../display/dc/inc/core_types.h:32,
                    from drivers/gpu/drm/amd/amdgpu/../display/dc/inc/resource.h:28,
                    from drivers/gpu/drm/amd/amdgpu/../display/tests/dc/dml/dcn20/dcn20_fpu_test.c:10:
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:137:22: warning: 'SYNAPTICS_DEVICE_ID' defined but not used [-Wunused-const-variable=]
     137 | static const uint8_t SYNAPTICS_DEVICE_ID[] = "SYNA";
         |                      ^~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:134:17: warning: 'DP_SINK_BRANCH_DEV_NAME_7580' defined but not used [-Wunused-const-variable=]
     134 | static const u8 DP_SINK_BRANCH_DEV_NAME_7580[] = "7580\x80u";
         |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:132:22: warning: 'DP_SINK_DEVICE_STR_ID_2' defined but not used [-Wunused-const-variable=]
     132 | static const uint8_t DP_SINK_DEVICE_STR_ID_2[] = {7, 1, 8, 7, 5, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~
   drivers/gpu/drm/amd/amdgpu/../display/include/ddc_service_types.h:131:22: warning: 'DP_SINK_DEVICE_STR_ID_1' defined but not used [-Wunused-const-variable=]
     131 | static const uint8_t DP_SINK_DEVICE_STR_ID_1[] = {7, 1, 8, 7, 3, 0};
         |                      ^~~~~~~~~~~~~~~~~~~~~~~


vim +/dcn20_fpu_dcn21_update_bw_bounding_box_test_init +455 drivers/gpu/drm/amd/amdgpu/../display/tests/dc/dml/dcn20/dcn20_fpu_test.c

   450	
   451	/**
   452	 * dcn20_fpu_dcn21_update_bw_bounding_box_test_init - Store backup copies of DCN global structures
   453	 * @test: represents a running instance of a test.
   454	 */
 > 455	int dcn20_fpu_dcn21_update_bw_bounding_box_test_init(struct kunit *test)
   456	{
   457		memcpy(&original_dcn2_1_soc, &dcn2_1_soc, sizeof(struct _vcs_dpi_soc_bounding_box_st));
   458		memcpy(&original_dcn2_1_ip, &dcn2_1_ip, sizeof(struct _vcs_dpi_ip_params_st));
   459	
   460		return 0;
   461	}
   462	

-- 
0-DAY CI Kernel Test Service
https://01.org/lkp

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2022-09-03 19:51 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-31 17:22 [PATCH v2 0/8] drm/amd/display: Introduce KUnit to Display Mode Library Maíra Canal
2022-08-31 17:22 ` Maíra Canal
2022-08-31 17:22 ` Maíra Canal
2022-08-31 17:22 ` [PATCH v2 1/8] drm/amd/display: Introduce KUnit tests for fixed31_32 library Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22 ` [PATCH v2 2/8] drm/amd/display: Introduce KUnit tests to the bw_fixed library Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22 ` [PATCH v2 3/8] drm/amd/display: Introduce KUnit tests to display_rq_dlg_calc_20 Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22 ` [PATCH v2 4/8] drm/amd/display: Introduce KUnit tests to the display_mode_vba library Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22 ` [PATCH v2 5/8] drm/amd/display: Introduce KUnit to dcn20/display_mode_vba_20 library Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22 ` [PATCH v2 6/8] drm/amd/display: Introduce KUnit tests for dcn20_fpu Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-09-03 19:50   ` kernel test robot
2022-09-03 19:50     ` kernel test robot
2022-08-31 17:22 ` [PATCH v2 7/8] drm/amd/display: Introduce KUnit tests to dc_dmub_srv library Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-09-03 11:47   ` kernel test robot
2022-09-03 11:47     ` kernel test robot
2022-08-31 17:22 ` [PATCH v2 8/8] Documentation/gpu: Add Display Core Unit Test documentation Maíra Canal
2022-08-31 17:22   ` Maíra Canal
2022-08-31 17:22   ` Maíra Canal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.