Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/tests: Add HDMI TDMS character rate tests

The previous patch added an helper to compute the TMDS character rate on
an HDMI connector. Let's add a few tests to make sure it works as
expected.

Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20240527-kms-hdmi-connector-state-v15-10-c5af16c3aae2@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>

+300
+300
drivers/gpu/drm/tests/drm_connector_test.c
··· 8 8 #include <drm/drm_atomic_state_helper.h> 9 9 #include <drm/drm_connector.h> 10 10 #include <drm/drm_drv.h> 11 + #include <drm/drm_edid.h> 11 12 #include <drm/drm_kunit_helpers.h> 13 + #include <drm/drm_modes.h> 14 + 15 + #include <drm/display/drm_hdmi_helper.h> 12 16 13 17 #include <kunit/test.h> 14 18 ··· 625 621 .test_cases = drm_hdmi_connector_get_output_format_name_tests, 626 622 }; 627 623 624 + /* 625 + * Test that for a given mode, with 8bpc and an RGB output the TMDS 626 + * character rate is equal to the mode pixel clock. 627 + */ 628 + static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test) 629 + { 630 + struct drm_connector_init_priv *priv = test->priv; 631 + const struct drm_display_mode *mode; 632 + unsigned long long rate; 633 + struct drm_device *drm = &priv->drm; 634 + 635 + mode = drm_display_mode_from_cea_vic(drm, 16); 636 + KUNIT_ASSERT_NOT_NULL(test, mode); 637 + 638 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 639 + 640 + rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 641 + KUNIT_ASSERT_GT(test, rate, 0); 642 + KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate); 643 + } 644 + 645 + /* 646 + * Test that for a given mode, with 10bpc and an RGB output the TMDS 647 + * character rate is equal to 1.25 times the mode pixel clock. 648 + */ 649 + static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test) 650 + { 651 + struct drm_connector_init_priv *priv = test->priv; 652 + const struct drm_display_mode *mode; 653 + unsigned long long rate; 654 + struct drm_device *drm = &priv->drm; 655 + 656 + mode = drm_display_mode_from_cea_vic(drm, 16); 657 + KUNIT_ASSERT_NOT_NULL(test, mode); 658 + 659 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 660 + 661 + rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 662 + KUNIT_ASSERT_GT(test, rate, 0); 663 + KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate); 664 + } 665 + 666 + /* 667 + * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS 668 + * character rate computation fails. 669 + */ 670 + static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test) 671 + { 672 + struct drm_connector_init_priv *priv = test->priv; 673 + const struct drm_display_mode *mode; 674 + unsigned long long rate; 675 + struct drm_device *drm = &priv->drm; 676 + 677 + mode = drm_display_mode_from_cea_vic(drm, 1); 678 + KUNIT_ASSERT_NOT_NULL(test, mode); 679 + 680 + rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 681 + KUNIT_EXPECT_EQ(test, rate, 0); 682 + } 683 + 684 + /* 685 + * Test that for a given mode, with 12bpc and an RGB output the TMDS 686 + * character rate is equal to 1.5 times the mode pixel clock. 687 + */ 688 + static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test) 689 + { 690 + struct drm_connector_init_priv *priv = test->priv; 691 + const struct drm_display_mode *mode; 692 + unsigned long long rate; 693 + struct drm_device *drm = &priv->drm; 694 + 695 + mode = drm_display_mode_from_cea_vic(drm, 16); 696 + KUNIT_ASSERT_NOT_NULL(test, mode); 697 + 698 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 699 + 700 + rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 701 + KUNIT_ASSERT_GT(test, rate, 0); 702 + KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate); 703 + } 704 + 705 + /* 706 + * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS 707 + * character rate computation fails. 708 + */ 709 + static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test) 710 + { 711 + struct drm_connector_init_priv *priv = test->priv; 712 + const struct drm_display_mode *mode; 713 + unsigned long long rate; 714 + struct drm_device *drm = &priv->drm; 715 + 716 + mode = drm_display_mode_from_cea_vic(drm, 1); 717 + KUNIT_ASSERT_NOT_NULL(test, mode); 718 + 719 + rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 720 + KUNIT_EXPECT_EQ(test, rate, 0); 721 + } 722 + 723 + /* 724 + * Test that for a mode with the pixel repetition flag, the TMDS 725 + * character rate is indeed double the mode pixel clock. 726 + */ 727 + static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test) 728 + { 729 + struct drm_connector_init_priv *priv = test->priv; 730 + const struct drm_display_mode *mode; 731 + unsigned long long rate; 732 + struct drm_device *drm = &priv->drm; 733 + 734 + mode = drm_display_mode_from_cea_vic(drm, 6); 735 + KUNIT_ASSERT_NOT_NULL(test, mode); 736 + 737 + KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 738 + 739 + rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 740 + KUNIT_ASSERT_GT(test, rate, 0); 741 + KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate); 742 + } 743 + 744 + /* 745 + * Test that the TMDS character rate computation for the VIC modes 746 + * explicitly listed in the spec as supporting YUV420 succeed and return 747 + * half the mode pixel clock. 748 + */ 749 + static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test) 750 + { 751 + struct drm_connector_init_priv *priv = test->priv; 752 + const struct drm_display_mode *mode; 753 + struct drm_device *drm = &priv->drm; 754 + unsigned long long rate; 755 + unsigned int vic = *(unsigned int *)test->param_value; 756 + 757 + mode = drm_display_mode_from_cea_vic(drm, vic); 758 + KUNIT_ASSERT_NOT_NULL(test, mode); 759 + 760 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 761 + 762 + rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420); 763 + KUNIT_ASSERT_GT(test, rate, 0); 764 + KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate); 765 + } 766 + 767 + static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = { 768 + 96, 97, 101, 102, 106, 107, 769 + }; 770 + 771 + static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc) 772 + { 773 + sprintf(desc, "VIC %u", *vic); 774 + } 775 + 776 + KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid, 777 + drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests, 778 + drm_hdmi_compute_mode_clock_yuv420_vic_desc); 779 + 780 + /* 781 + * Test that for a given mode listed supporting it and an YUV420 output 782 + * with 10bpc, the TMDS character rate is equal to 0.625 times the mode 783 + * pixel clock. 784 + */ 785 + static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test) 786 + { 787 + struct drm_connector_init_priv *priv = test->priv; 788 + const struct drm_display_mode *mode; 789 + struct drm_device *drm = &priv->drm; 790 + unsigned int vic = 791 + drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 792 + unsigned long long rate; 793 + 794 + mode = drm_display_mode_from_cea_vic(drm, vic); 795 + KUNIT_ASSERT_NOT_NULL(test, mode); 796 + 797 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 798 + 799 + rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420); 800 + KUNIT_ASSERT_GT(test, rate, 0); 801 + 802 + KUNIT_EXPECT_EQ(test, mode->clock * 625, rate); 803 + } 804 + 805 + /* 806 + * Test that for a given mode listed supporting it and an YUV420 output 807 + * with 12bpc, the TMDS character rate is equal to 0.75 times the mode 808 + * pixel clock. 809 + */ 810 + static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test) 811 + { 812 + struct drm_connector_init_priv *priv = test->priv; 813 + const struct drm_display_mode *mode; 814 + struct drm_device *drm = &priv->drm; 815 + unsigned int vic = 816 + drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 817 + unsigned long long rate; 818 + 819 + mode = drm_display_mode_from_cea_vic(drm, vic); 820 + KUNIT_ASSERT_NOT_NULL(test, mode); 821 + 822 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 823 + 824 + rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420); 825 + KUNIT_ASSERT_GT(test, rate, 0); 826 + 827 + KUNIT_EXPECT_EQ(test, mode->clock * 750, rate); 828 + } 829 + 830 + /* 831 + * Test that for a given mode, the computation of the TMDS character 832 + * rate with 8bpc and a YUV422 output succeeds and returns a rate equal 833 + * to the mode pixel clock. 834 + */ 835 + static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test) 836 + { 837 + struct drm_connector_init_priv *priv = test->priv; 838 + const struct drm_display_mode *mode; 839 + struct drm_device *drm = &priv->drm; 840 + unsigned long long rate; 841 + 842 + mode = drm_display_mode_from_cea_vic(drm, 16); 843 + KUNIT_ASSERT_NOT_NULL(test, mode); 844 + 845 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 846 + 847 + rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422); 848 + KUNIT_ASSERT_GT(test, rate, 0); 849 + KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 850 + } 851 + 852 + /* 853 + * Test that for a given mode, the computation of the TMDS character 854 + * rate with 10bpc and a YUV422 output succeeds and returns a rate equal 855 + * to the mode pixel clock. 856 + */ 857 + static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test) 858 + { 859 + struct drm_connector_init_priv *priv = test->priv; 860 + const struct drm_display_mode *mode; 861 + struct drm_device *drm = &priv->drm; 862 + unsigned long long rate; 863 + 864 + mode = drm_display_mode_from_cea_vic(drm, 16); 865 + KUNIT_ASSERT_NOT_NULL(test, mode); 866 + 867 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 868 + 869 + rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422); 870 + KUNIT_ASSERT_GT(test, rate, 0); 871 + KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 872 + } 873 + 874 + /* 875 + * Test that for a given mode, the computation of the TMDS character 876 + * rate with 12bpc and a YUV422 output succeeds and returns a rate equal 877 + * to the mode pixel clock. 878 + */ 879 + static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test) 880 + { 881 + struct drm_connector_init_priv *priv = test->priv; 882 + const struct drm_display_mode *mode; 883 + struct drm_device *drm = &priv->drm; 884 + unsigned long long rate; 885 + 886 + mode = drm_display_mode_from_cea_vic(drm, 16); 887 + KUNIT_ASSERT_NOT_NULL(test, mode); 888 + 889 + KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 890 + 891 + rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422); 892 + KUNIT_ASSERT_GT(test, rate, 0); 893 + KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 894 + } 895 + 896 + static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = { 897 + KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb), 898 + KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc), 899 + KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1), 900 + KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc), 901 + KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1), 902 + KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double), 903 + KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid, 904 + drm_hdmi_compute_mode_clock_yuv420_valid_gen_params), 905 + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc), 906 + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc), 907 + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc), 908 + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc), 909 + KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc), 910 + { } 911 + }; 912 + 913 + static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = { 914 + .name = "drm_test_connector_hdmi_compute_mode_clock", 915 + .init = drm_test_connector_init, 916 + .test_cases = drm_hdmi_compute_mode_clock_tests, 917 + }; 918 + 628 919 kunit_test_suites( 629 920 &drmm_connector_hdmi_init_test_suite, 630 921 &drmm_connector_init_test_suite, 631 922 &drm_get_tv_mode_from_name_test_suite, 923 + &drm_hdmi_compute_mode_clock_test_suite, 632 924 &drm_hdmi_connector_get_output_format_name_test_suite 633 925 ); 634 926