drm_probe_helper_test.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Kunit test for drm_probe_helper functions
  4. */
  5. #include <drm/drm_atomic_state_helper.h>
  6. #include <drm/drm_connector.h>
  7. #include <drm/drm_device.h>
  8. #include <drm/drm_drv.h>
  9. #include <drm/drm_kunit_helpers.h>
  10. #include <drm/drm_mode.h>
  11. #include <drm/drm_modes.h>
  12. #include <drm/drm_modeset_helper_vtables.h>
  13. #include <drm/drm_probe_helper.h>
  14. #include <kunit/test.h>
  15. struct drm_probe_helper_test_priv {
  16. struct drm_device *drm;
  17. struct device *dev;
  18. struct drm_connector connector;
  19. };
  20. static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = {
  21. };
  22. static const struct drm_connector_funcs drm_probe_helper_connector_funcs = {
  23. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  24. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  25. .reset = drm_atomic_helper_connector_reset,
  26. };
  27. static int drm_probe_helper_test_init(struct kunit *test)
  28. {
  29. struct drm_probe_helper_test_priv *priv;
  30. struct drm_connector *connector;
  31. int ret;
  32. priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
  33. KUNIT_ASSERT_NOT_NULL(test, priv);
  34. test->priv = priv;
  35. priv->dev = drm_kunit_helper_alloc_device(test);
  36. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
  37. priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
  38. sizeof(*priv->drm), 0,
  39. DRIVER_MODESET | DRIVER_ATOMIC);
  40. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
  41. connector = &priv->connector;
  42. ret = drmm_connector_init(priv->drm, connector,
  43. &drm_probe_helper_connector_funcs,
  44. DRM_MODE_CONNECTOR_Unknown,
  45. NULL);
  46. KUNIT_ASSERT_EQ(test, ret, 0);
  47. drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs);
  48. return 0;
  49. }
  50. typedef struct drm_display_mode *(*expected_mode_func_t)(struct drm_device *);
  51. struct drm_connector_helper_tv_get_modes_test {
  52. const char *name;
  53. unsigned int supported_tv_modes;
  54. enum drm_connector_tv_mode default_mode;
  55. bool cmdline;
  56. enum drm_connector_tv_mode cmdline_mode;
  57. expected_mode_func_t *expected_modes;
  58. unsigned int num_expected_modes;
  59. };
  60. #define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...) \
  61. { \
  62. .name = _name, \
  63. .supported_tv_modes = _supported, \
  64. .default_mode = _default, \
  65. .cmdline = _cmdline, \
  66. .cmdline_mode = _cmdline_mode, \
  67. .expected_modes = (expected_mode_func_t[]) { __VA_ARGS__ }, \
  68. .num_expected_modes = sizeof((expected_mode_func_t[]) { __VA_ARGS__ }) / \
  69. (sizeof(expected_mode_func_t)), \
  70. }
  71. #define TV_MODE_TEST(_name, _supported, _default, ...) \
  72. _TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__)
  73. #define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \
  74. _TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__)
  75. static void
  76. drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
  77. {
  78. const struct drm_connector_helper_tv_get_modes_test *params = test->param_value;
  79. struct drm_probe_helper_test_priv *priv = test->priv;
  80. struct drm_connector *connector = &priv->connector;
  81. struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
  82. struct drm_display_mode *mode;
  83. struct drm_display_mode *expected;
  84. size_t len;
  85. int ret;
  86. if (params->cmdline) {
  87. cmdline->tv_mode_specified = true;
  88. cmdline->tv_mode = params->cmdline_mode;
  89. }
  90. ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes);
  91. KUNIT_ASSERT_EQ(test, ret, 0);
  92. drm_object_attach_property(&connector->base,
  93. priv->drm->mode_config.tv_mode_property,
  94. params->default_mode);
  95. mutex_lock(&priv->drm->mode_config.mutex);
  96. ret = drm_connector_helper_tv_get_modes(connector);
  97. KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes);
  98. len = 0;
  99. list_for_each_entry(mode, &connector->probed_modes, head)
  100. len++;
  101. KUNIT_EXPECT_EQ(test, len, params->num_expected_modes);
  102. if (params->num_expected_modes >= 1) {
  103. mode = list_first_entry_or_null(&connector->probed_modes,
  104. struct drm_display_mode, head);
  105. KUNIT_ASSERT_NOT_NULL(test, mode);
  106. expected = params->expected_modes[0](priv->drm);
  107. KUNIT_ASSERT_NOT_NULL(test, expected);
  108. KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
  109. KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
  110. ret = drm_kunit_add_mode_destroy_action(test, expected);
  111. KUNIT_ASSERT_EQ(test, ret, 0);
  112. }
  113. if (params->num_expected_modes >= 2) {
  114. mode = list_next_entry(mode, head);
  115. KUNIT_ASSERT_NOT_NULL(test, mode);
  116. expected = params->expected_modes[1](priv->drm);
  117. KUNIT_ASSERT_NOT_NULL(test, expected);
  118. KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
  119. KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
  120. ret = drm_kunit_add_mode_destroy_action(test, expected);
  121. KUNIT_ASSERT_EQ(test, ret, 0);
  122. }
  123. mutex_unlock(&priv->drm->mode_config.mutex);
  124. }
  125. static const
  126. struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = {
  127. { .name = "None" },
  128. TV_MODE_TEST("PAL",
  129. BIT(DRM_MODE_TV_MODE_PAL),
  130. DRM_MODE_TV_MODE_PAL,
  131. drm_mode_analog_pal_576i),
  132. TV_MODE_TEST("NTSC",
  133. BIT(DRM_MODE_TV_MODE_NTSC),
  134. DRM_MODE_TV_MODE_NTSC,
  135. drm_mode_analog_ntsc_480i),
  136. TV_MODE_TEST("Both, NTSC Default",
  137. BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
  138. DRM_MODE_TV_MODE_NTSC,
  139. drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
  140. TV_MODE_TEST("Both, PAL Default",
  141. BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
  142. DRM_MODE_TV_MODE_PAL,
  143. drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
  144. TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line",
  145. BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
  146. DRM_MODE_TV_MODE_NTSC,
  147. DRM_MODE_TV_MODE_PAL,
  148. drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
  149. TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line",
  150. BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
  151. DRM_MODE_TV_MODE_PAL,
  152. DRM_MODE_TV_MODE_NTSC,
  153. drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
  154. };
  155. static void
  156. drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t,
  157. char *desc)
  158. {
  159. sprintf(desc, "%s", t->name);
  160. }
  161. KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes,
  162. drm_connector_helper_tv_get_modes_tests,
  163. drm_connector_helper_tv_get_modes_desc);
  164. static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = {
  165. KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check,
  166. drm_connector_helper_tv_get_modes_gen_params),
  167. { }
  168. };
  169. static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = {
  170. .name = "drm_connector_helper_tv_get_modes",
  171. .init = drm_probe_helper_test_init,
  172. .test_cases = drm_test_connector_helper_tv_get_modes_tests,
  173. };
  174. kunit_test_suite(drm_test_connector_helper_tv_get_modes_suite);
  175. MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
  176. MODULE_DESCRIPTION("Kunit test for drm_probe_helper functions");
  177. MODULE_LICENSE("GPL");