drm_connector_test.c 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Kunit test for drm_modes functions
  4. */
  5. #include <linux/i2c.h>
  6. #include <drm/drm_atomic_state_helper.h>
  7. #include <drm/drm_connector.h>
  8. #include <drm/drm_drv.h>
  9. #include <drm/drm_edid.h>
  10. #include <drm/drm_file.h>
  11. #include <drm/drm_kunit_helpers.h>
  12. #include <drm/drm_modes.h>
  13. #include <drm/display/drm_hdmi_helper.h>
  14. #include <kunit/test.h>
  15. #include "../drm_crtc_internal.h"
  16. struct drm_connector_init_priv {
  17. struct drm_device drm;
  18. struct drm_connector connector;
  19. struct i2c_adapter ddc;
  20. };
  21. static int accept_infoframe_clear_infoframe(struct drm_connector *connector)
  22. {
  23. return 0;
  24. }
  25. static int accept_infoframe_write_infoframe(struct drm_connector *connector,
  26. const u8 *buffer, size_t len)
  27. {
  28. return 0;
  29. }
  30. static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
  31. .avi = {
  32. .clear_infoframe = accept_infoframe_clear_infoframe,
  33. .write_infoframe = accept_infoframe_write_infoframe,
  34. },
  35. .hdmi = {
  36. .clear_infoframe = accept_infoframe_clear_infoframe,
  37. .write_infoframe = accept_infoframe_write_infoframe,
  38. },
  39. };
  40. static const struct drm_connector_funcs dummy_funcs = {
  41. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  42. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  43. .reset = drm_atomic_helper_connector_reset,
  44. };
  45. static int dummy_ddc_xfer(struct i2c_adapter *adapter,
  46. struct i2c_msg *msgs, int num)
  47. {
  48. return num;
  49. }
  50. static u32 dummy_ddc_func(struct i2c_adapter *adapter)
  51. {
  52. return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
  53. }
  54. static const struct i2c_algorithm dummy_ddc_algorithm = {
  55. .master_xfer = dummy_ddc_xfer,
  56. .functionality = dummy_ddc_func,
  57. };
  58. static void i2c_del_adapter_wrapper(void *ptr)
  59. {
  60. struct i2c_adapter *adap = ptr;
  61. i2c_del_adapter(adap);
  62. }
  63. static int drm_test_connector_init(struct kunit *test)
  64. {
  65. struct drm_connector_init_priv *priv;
  66. struct device *dev;
  67. int ret;
  68. dev = drm_kunit_helper_alloc_device(test);
  69. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
  70. priv = drm_kunit_helper_alloc_drm_device(test, dev,
  71. struct drm_connector_init_priv, drm,
  72. DRIVER_MODESET | DRIVER_ATOMIC);
  73. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
  74. strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
  75. priv->ddc.owner = THIS_MODULE;
  76. priv->ddc.algo = &dummy_ddc_algorithm;
  77. priv->ddc.dev.parent = dev;
  78. ret = i2c_add_adapter(&priv->ddc);
  79. KUNIT_ASSERT_EQ(test, ret, 0);
  80. ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
  81. KUNIT_ASSERT_EQ(test, ret, 0);
  82. test->priv = priv;
  83. return 0;
  84. }
  85. /*
  86. * Test that the registration of a bog standard connector works as
  87. * expected and doesn't report any error.
  88. */
  89. static void drm_test_drmm_connector_init(struct kunit *test)
  90. {
  91. struct drm_connector_init_priv *priv = test->priv;
  92. int ret;
  93. ret = drmm_connector_init(&priv->drm, &priv->connector,
  94. &dummy_funcs,
  95. DRM_MODE_CONNECTOR_HDMIA,
  96. &priv->ddc);
  97. KUNIT_EXPECT_EQ(test, ret, 0);
  98. }
  99. /*
  100. * Test that the registration of a connector without a DDC adapter
  101. * doesn't report any error.
  102. */
  103. static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
  104. {
  105. struct drm_connector_init_priv *priv = test->priv;
  106. int ret;
  107. ret = drmm_connector_init(&priv->drm, &priv->connector,
  108. &dummy_funcs,
  109. DRM_MODE_CONNECTOR_HDMIA,
  110. NULL);
  111. KUNIT_EXPECT_EQ(test, ret, 0);
  112. }
  113. /*
  114. * Test that the registration of a connector succeeds for all possible
  115. * connector types.
  116. */
  117. static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
  118. {
  119. struct drm_connector_init_priv *priv = test->priv;
  120. unsigned int connector_type = *(unsigned int *)test->param_value;
  121. int ret;
  122. ret = drmm_connector_init(&priv->drm, &priv->connector,
  123. &dummy_funcs,
  124. connector_type,
  125. &priv->ddc);
  126. KUNIT_EXPECT_EQ(test, ret, 0);
  127. }
  128. static const unsigned int drm_connector_init_type_valid_tests[] = {
  129. DRM_MODE_CONNECTOR_Unknown,
  130. DRM_MODE_CONNECTOR_VGA,
  131. DRM_MODE_CONNECTOR_DVII,
  132. DRM_MODE_CONNECTOR_DVID,
  133. DRM_MODE_CONNECTOR_DVIA,
  134. DRM_MODE_CONNECTOR_Composite,
  135. DRM_MODE_CONNECTOR_SVIDEO,
  136. DRM_MODE_CONNECTOR_LVDS,
  137. DRM_MODE_CONNECTOR_Component,
  138. DRM_MODE_CONNECTOR_9PinDIN,
  139. DRM_MODE_CONNECTOR_DisplayPort,
  140. DRM_MODE_CONNECTOR_HDMIA,
  141. DRM_MODE_CONNECTOR_HDMIB,
  142. DRM_MODE_CONNECTOR_TV,
  143. DRM_MODE_CONNECTOR_eDP,
  144. DRM_MODE_CONNECTOR_VIRTUAL,
  145. DRM_MODE_CONNECTOR_DSI,
  146. DRM_MODE_CONNECTOR_DPI,
  147. DRM_MODE_CONNECTOR_WRITEBACK,
  148. DRM_MODE_CONNECTOR_SPI,
  149. DRM_MODE_CONNECTOR_USB,
  150. };
  151. static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
  152. {
  153. sprintf(desc, "%s", drm_get_connector_type_name(*type));
  154. }
  155. KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
  156. drm_connector_init_type_valid_tests,
  157. drm_connector_init_type_desc);
  158. static struct kunit_case drmm_connector_init_tests[] = {
  159. KUNIT_CASE(drm_test_drmm_connector_init),
  160. KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
  161. KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
  162. drm_connector_init_type_valid_gen_params),
  163. { }
  164. };
  165. static struct kunit_suite drmm_connector_init_test_suite = {
  166. .name = "drmm_connector_init",
  167. .init = drm_test_connector_init,
  168. .test_cases = drmm_connector_init_tests,
  169. };
  170. static const struct drm_connector_funcs dummy_dynamic_init_funcs = {
  171. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  172. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  173. .reset = drm_atomic_helper_connector_reset,
  174. .destroy = drm_connector_cleanup,
  175. };
  176. /*
  177. * Test that the initialization of a bog standard dynamic connector works
  178. * as expected and doesn't report any error.
  179. */
  180. static void drm_test_drm_connector_dynamic_init(struct kunit *test)
  181. {
  182. struct drm_connector_init_priv *priv = test->priv;
  183. struct drm_connector *connector = &priv->connector;
  184. int ret;
  185. ret = drm_connector_dynamic_init(&priv->drm, connector,
  186. &dummy_dynamic_init_funcs,
  187. DRM_MODE_CONNECTOR_DisplayPort,
  188. &priv->ddc);
  189. KUNIT_ASSERT_EQ(test, ret, 0);
  190. }
  191. static void drm_test_connector_dynamic_init_cleanup(struct kunit *test)
  192. {
  193. struct drm_connector_init_priv *priv = test->priv;
  194. struct drm_connector *connector = &priv->connector;
  195. drm_connector_cleanup(connector);
  196. }
  197. /*
  198. * Test that the initialization of a dynamic connector without a DDC adapter
  199. * doesn't report any error.
  200. */
  201. static void drm_test_drm_connector_dynamic_init_null_ddc(struct kunit *test)
  202. {
  203. struct drm_connector_init_priv *priv = test->priv;
  204. struct drm_connector *connector = &priv->connector;
  205. int ret;
  206. ret = drm_connector_dynamic_init(&priv->drm, connector,
  207. &dummy_dynamic_init_funcs,
  208. DRM_MODE_CONNECTOR_DisplayPort,
  209. NULL);
  210. KUNIT_ASSERT_EQ(test, ret, 0);
  211. }
  212. /*
  213. * Test that the initialization of a dynamic connector doesn't add the
  214. * connector to the connector list.
  215. */
  216. static void drm_test_drm_connector_dynamic_init_not_added(struct kunit *test)
  217. {
  218. struct drm_connector_init_priv *priv = test->priv;
  219. struct drm_connector *connector = &priv->connector;
  220. int ret;
  221. ret = drm_connector_dynamic_init(&priv->drm, connector,
  222. &dummy_dynamic_init_funcs,
  223. DRM_MODE_CONNECTOR_DisplayPort,
  224. &priv->ddc);
  225. KUNIT_ASSERT_EQ(test, ret, 0);
  226. KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &connector->head);
  227. }
  228. static void test_connector_property(struct kunit *test,
  229. struct drm_connector *connector,
  230. const struct drm_property *expected_prop)
  231. {
  232. struct drm_property *prop;
  233. uint64_t val;
  234. int ret;
  235. KUNIT_ASSERT_NOT_NULL(test, expected_prop);
  236. prop = drm_mode_obj_find_prop_id(&connector->base, expected_prop->base.id);
  237. KUNIT_ASSERT_PTR_EQ_MSG(test, prop, expected_prop,
  238. "Can't find property %s", expected_prop->name);
  239. ret = drm_object_property_get_default_value(&connector->base, prop, &val);
  240. KUNIT_EXPECT_EQ(test, ret, 0);
  241. KUNIT_EXPECT_EQ(test, val, 0);
  242. /* TODO: Check property value in the connector state. */
  243. }
  244. /*
  245. * Test that the initialization of a dynamic connector adds all the expected
  246. * properties to it.
  247. */
  248. static void drm_test_drm_connector_dynamic_init_properties(struct kunit *test)
  249. {
  250. struct drm_connector_init_priv *priv = test->priv;
  251. struct drm_connector *connector = &priv->connector;
  252. struct drm_mode_config *config = &priv->drm.mode_config;
  253. const struct drm_property *props[] = {
  254. config->edid_property,
  255. config->dpms_property,
  256. config->link_status_property,
  257. config->non_desktop_property,
  258. config->tile_property,
  259. config->prop_crtc_id,
  260. };
  261. int ret;
  262. int i;
  263. ret = drm_connector_dynamic_init(&priv->drm, connector,
  264. &dummy_dynamic_init_funcs,
  265. DRM_MODE_CONNECTOR_DisplayPort,
  266. &priv->ddc);
  267. KUNIT_ASSERT_EQ(test, ret, 0);
  268. for (i = 0; i < ARRAY_SIZE(props); i++)
  269. test_connector_property(test, connector, props[i]);
  270. }
  271. /*
  272. * Test that the initialization of a dynamic connector succeeds for all
  273. * possible connector types.
  274. */
  275. static void drm_test_drm_connector_dynamic_init_type_valid(struct kunit *test)
  276. {
  277. struct drm_connector_init_priv *priv = test->priv;
  278. struct drm_connector *connector = &priv->connector;
  279. unsigned int connector_type = *(unsigned int *)test->param_value;
  280. int ret;
  281. ret = drm_connector_dynamic_init(&priv->drm, connector,
  282. &dummy_dynamic_init_funcs,
  283. connector_type,
  284. &priv->ddc);
  285. KUNIT_ASSERT_EQ(test, ret, 0);
  286. }
  287. /*
  288. * Test that the initialization of a dynamic connector sets the expected name
  289. * for it for all possible connector types.
  290. */
  291. static void drm_test_drm_connector_dynamic_init_name(struct kunit *test)
  292. {
  293. struct drm_connector_init_priv *priv = test->priv;
  294. struct drm_connector *connector = &priv->connector;
  295. unsigned int connector_type = *(unsigned int *)test->param_value;
  296. char expected_name[128];
  297. int ret;
  298. ret = drm_connector_dynamic_init(&priv->drm, connector,
  299. &dummy_dynamic_init_funcs,
  300. connector_type,
  301. &priv->ddc);
  302. KUNIT_ASSERT_EQ(test, ret, 0);
  303. snprintf(expected_name, sizeof(expected_name), "%s-%d",
  304. drm_get_connector_type_name(connector_type), connector->connector_type_id);
  305. KUNIT_ASSERT_STREQ(test, connector->name, expected_name);
  306. }
  307. static struct kunit_case drm_connector_dynamic_init_tests[] = {
  308. KUNIT_CASE(drm_test_drm_connector_dynamic_init),
  309. KUNIT_CASE(drm_test_drm_connector_dynamic_init_null_ddc),
  310. KUNIT_CASE(drm_test_drm_connector_dynamic_init_not_added),
  311. KUNIT_CASE(drm_test_drm_connector_dynamic_init_properties),
  312. KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_type_valid,
  313. drm_connector_init_type_valid_gen_params),
  314. KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_name,
  315. drm_connector_init_type_valid_gen_params),
  316. {}
  317. };
  318. static struct kunit_suite drm_connector_dynamic_init_test_suite = {
  319. .name = "drm_connector_dynamic_init",
  320. .init = drm_test_connector_init,
  321. .exit = drm_test_connector_dynamic_init_cleanup,
  322. .test_cases = drm_connector_dynamic_init_tests,
  323. };
  324. static int drm_test_connector_dynamic_register_early_init(struct kunit *test)
  325. {
  326. struct drm_connector_init_priv *priv;
  327. int ret;
  328. ret = drm_test_connector_init(test);
  329. KUNIT_ASSERT_EQ(test, ret, 0);
  330. priv = test->priv;
  331. ret = drm_connector_dynamic_init(&priv->drm, &priv->connector,
  332. &dummy_dynamic_init_funcs,
  333. DRM_MODE_CONNECTOR_DisplayPort,
  334. &priv->ddc);
  335. KUNIT_ASSERT_EQ(test, ret, 0);
  336. return 0;
  337. }
  338. static void drm_test_connector_dynamic_register_early_cleanup(struct kunit *test)
  339. {
  340. struct drm_connector_init_priv *priv = test->priv;
  341. struct drm_connector *connector = &priv->connector;
  342. drm_connector_unregister(connector);
  343. drm_connector_put(connector);
  344. }
  345. /*
  346. * Test that registration of a dynamic connector adds it to the connector list.
  347. */
  348. static void drm_test_drm_connector_dynamic_register_early_on_list(struct kunit *test)
  349. {
  350. struct drm_connector_init_priv *priv = test->priv;
  351. struct drm_connector *connector = &priv->connector;
  352. int ret;
  353. KUNIT_ASSERT_TRUE(test, list_empty(&connector->head));
  354. ret = drm_connector_dynamic_register(connector);
  355. KUNIT_ASSERT_EQ(test, ret, 0);
  356. KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &priv->drm.mode_config.connector_list);
  357. }
  358. /*
  359. * Test that the registration of a dynamic connector before the drm device is
  360. * registered results in deferring the connector's user interface registration.
  361. */
  362. static void drm_test_drm_connector_dynamic_register_early_defer(struct kunit *test)
  363. {
  364. struct drm_connector_init_priv *priv = test->priv;
  365. struct drm_connector *connector = &priv->connector;
  366. int ret;
  367. ret = drm_connector_dynamic_register(connector);
  368. KUNIT_ASSERT_EQ(test, ret, 0);
  369. KUNIT_ASSERT_EQ(test, connector->registration_state, DRM_CONNECTOR_INITIALIZING);
  370. }
  371. /*
  372. * Test that the registration of a dynamic connector fails, if this is done before
  373. * the connector is initialized.
  374. */
  375. static void drm_test_drm_connector_dynamic_register_early_no_init(struct kunit *test)
  376. {
  377. struct drm_connector *connector;
  378. int ret;
  379. connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */
  380. KUNIT_ASSERT_NOT_NULL(test, connector);
  381. ret = drm_connector_dynamic_register(connector);
  382. KUNIT_ASSERT_EQ(test, ret, -EINVAL);
  383. }
  384. /*
  385. * Test that the registration of a dynamic connector before the drm device is
  386. * registered results in deferring adding a mode object for the connector.
  387. */
  388. static void drm_test_drm_connector_dynamic_register_early_no_mode_object(struct kunit *test)
  389. {
  390. struct drm_connector_init_priv *priv = test->priv;
  391. struct drm_connector *connector = &priv->connector;
  392. struct drm_connector *tmp_connector;
  393. int ret;
  394. ret = drm_connector_dynamic_register(&priv->connector);
  395. KUNIT_ASSERT_EQ(test, ret, 0);
  396. tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
  397. KUNIT_ASSERT_NULL(test, tmp_connector);
  398. }
  399. static struct kunit_case drm_connector_dynamic_register_early_tests[] = {
  400. KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_on_list),
  401. KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_defer),
  402. KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_init),
  403. KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_mode_object),
  404. { }
  405. };
  406. static struct kunit_suite drm_connector_dynamic_register_early_test_suite = {
  407. .name = "drm_connector_dynamic_register_early",
  408. .init = drm_test_connector_dynamic_register_early_init,
  409. .exit = drm_test_connector_dynamic_register_early_cleanup,
  410. .test_cases = drm_connector_dynamic_register_early_tests,
  411. };
  412. static int drm_test_connector_dynamic_register_init(struct kunit *test)
  413. {
  414. struct drm_connector_init_priv *priv;
  415. int ret;
  416. ret = drm_test_connector_dynamic_register_early_init(test);
  417. KUNIT_ASSERT_EQ(test, ret, 0);
  418. priv = test->priv;
  419. ret = drm_dev_register(priv->connector.dev, 0);
  420. KUNIT_ASSERT_EQ(test, ret, 0);
  421. return 0;
  422. }
  423. static void drm_test_connector_dynamic_register_cleanup(struct kunit *test)
  424. {
  425. struct drm_connector_init_priv *priv = test->priv;
  426. struct drm_device *dev = priv->connector.dev;
  427. drm_connector_unregister(&priv->connector);
  428. drm_connector_put(&priv->connector);
  429. drm_dev_unregister(dev);
  430. drm_test_connector_dynamic_register_early_cleanup(test);
  431. }
  432. static void drm_test_drm_connector_dynamic_register_on_list(struct kunit *test)
  433. {
  434. struct drm_connector_init_priv *priv = test->priv;
  435. int ret;
  436. KUNIT_ASSERT_TRUE(test, list_empty(&priv->connector.head));
  437. ret = drm_connector_dynamic_register(&priv->connector);
  438. KUNIT_ASSERT_EQ(test, ret, 0);
  439. KUNIT_ASSERT_PTR_EQ(test, priv->connector.head.next, &priv->drm.mode_config.connector_list);
  440. }
  441. /*
  442. * Test that the registration of a dynamic connector doesn't get deferred if
  443. * this is done after the drm device is registered.
  444. */
  445. static void drm_test_drm_connector_dynamic_register_no_defer(struct kunit *test)
  446. {
  447. struct drm_connector_init_priv *priv = test->priv;
  448. int ret;
  449. KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_INITIALIZING);
  450. ret = drm_connector_dynamic_register(&priv->connector);
  451. KUNIT_ASSERT_EQ(test, ret, 0);
  452. KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_REGISTERED);
  453. }
  454. /*
  455. * Test that the registration of a dynamic connector fails if this is done after the
  456. * drm device is registered, but before the connector is initialized.
  457. */
  458. static void drm_test_drm_connector_dynamic_register_no_init(struct kunit *test)
  459. {
  460. struct drm_connector *connector;
  461. int ret;
  462. connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */
  463. KUNIT_ASSERT_NOT_NULL(test, connector);
  464. ret = drm_connector_dynamic_register(connector);
  465. KUNIT_ASSERT_EQ(test, ret, -EINVAL);
  466. }
  467. /*
  468. * Test that the registration of a dynamic connector after the drm device is
  469. * registered adds the mode object for the connector.
  470. */
  471. static void drm_test_drm_connector_dynamic_register_mode_object(struct kunit *test)
  472. {
  473. struct drm_connector_init_priv *priv = test->priv;
  474. struct drm_connector *connector = &priv->connector;
  475. struct drm_connector *tmp_connector;
  476. int ret;
  477. tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
  478. KUNIT_ASSERT_NULL(test, tmp_connector);
  479. ret = drm_connector_dynamic_register(&priv->connector);
  480. KUNIT_ASSERT_EQ(test, ret, 0);
  481. tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
  482. KUNIT_ASSERT_PTR_EQ(test, tmp_connector, connector);
  483. }
  484. /*
  485. * Test that the registration of a dynamic connector after the drm device is
  486. * registered adds the connector to sysfs.
  487. */
  488. static void drm_test_drm_connector_dynamic_register_sysfs(struct kunit *test)
  489. {
  490. struct drm_connector_init_priv *priv = test->priv;
  491. struct drm_connector *connector = &priv->connector;
  492. int ret;
  493. KUNIT_ASSERT_NULL(test, connector->kdev);
  494. ret = drm_connector_dynamic_register(connector);
  495. KUNIT_ASSERT_EQ(test, ret, 0);
  496. KUNIT_ASSERT_NOT_NULL(test, connector->kdev);
  497. }
  498. /*
  499. * Test that the registration of a dynamic connector after the drm device is
  500. * registered sets the connector's sysfs name as expected.
  501. */
  502. static void drm_test_drm_connector_dynamic_register_sysfs_name(struct kunit *test)
  503. {
  504. struct drm_connector_init_priv *priv = test->priv;
  505. struct drm_connector *connector = &priv->connector;
  506. char expected_name[128];
  507. int ret;
  508. ret = drm_connector_dynamic_register(connector);
  509. KUNIT_ASSERT_EQ(test, ret, 0);
  510. snprintf(expected_name, sizeof(expected_name), "card%d-%s",
  511. connector->dev->primary->index, connector->name);
  512. KUNIT_ASSERT_STREQ(test, dev_name(connector->kdev), expected_name);
  513. }
  514. /*
  515. * Test that the registration of a dynamic connector after the drm device is
  516. * registered adds the connector to debugfs.
  517. */
  518. static void drm_test_drm_connector_dynamic_register_debugfs(struct kunit *test)
  519. {
  520. struct drm_connector_init_priv *priv = test->priv;
  521. int ret;
  522. KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry);
  523. ret = drm_connector_dynamic_register(&priv->connector);
  524. KUNIT_ASSERT_EQ(test, ret, 0);
  525. if (IS_ENABLED(CONFIG_DEBUG_FS))
  526. KUNIT_ASSERT_NOT_NULL(test, priv->connector.debugfs_entry);
  527. else
  528. KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry);
  529. }
  530. static struct kunit_case drm_connector_dynamic_register_tests[] = {
  531. KUNIT_CASE(drm_test_drm_connector_dynamic_register_on_list),
  532. KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_defer),
  533. KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_init),
  534. KUNIT_CASE(drm_test_drm_connector_dynamic_register_mode_object),
  535. KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs),
  536. KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs_name),
  537. KUNIT_CASE(drm_test_drm_connector_dynamic_register_debugfs),
  538. { }
  539. };
  540. static struct kunit_suite drm_connector_dynamic_register_test_suite = {
  541. .name = "drm_connector_dynamic_register",
  542. .init = drm_test_connector_dynamic_register_init,
  543. .exit = drm_test_connector_dynamic_register_cleanup,
  544. .test_cases = drm_connector_dynamic_register_tests,
  545. };
  546. /*
  547. * Test that the registration of a bog standard connector works as
  548. * expected and doesn't report any error.
  549. */
  550. static void drm_test_connector_hdmi_init_valid(struct kunit *test)
  551. {
  552. struct drm_connector_init_priv *priv = test->priv;
  553. int ret;
  554. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  555. "Vendor", "Product",
  556. &dummy_funcs,
  557. &dummy_hdmi_funcs,
  558. DRM_MODE_CONNECTOR_HDMIA,
  559. &priv->ddc,
  560. BIT(HDMI_COLORSPACE_RGB),
  561. 8);
  562. KUNIT_EXPECT_EQ(test, ret, 0);
  563. }
  564. /*
  565. * Test that the registration of a connector without a DDC adapter
  566. * doesn't report any error.
  567. */
  568. static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
  569. {
  570. struct drm_connector_init_priv *priv = test->priv;
  571. int ret;
  572. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  573. "Vendor", "Product",
  574. &dummy_funcs,
  575. &dummy_hdmi_funcs,
  576. DRM_MODE_CONNECTOR_HDMIA,
  577. NULL,
  578. BIT(HDMI_COLORSPACE_RGB),
  579. 8);
  580. KUNIT_EXPECT_EQ(test, ret, 0);
  581. }
  582. /*
  583. * Test that the registration of an HDMI connector with a NULL vendor
  584. * fails.
  585. */
  586. static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
  587. {
  588. struct drm_connector_init_priv *priv = test->priv;
  589. int ret;
  590. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  591. NULL, "Product",
  592. &dummy_funcs,
  593. &dummy_hdmi_funcs,
  594. DRM_MODE_CONNECTOR_HDMIA,
  595. &priv->ddc,
  596. BIT(HDMI_COLORSPACE_RGB),
  597. 8);
  598. KUNIT_EXPECT_LT(test, ret, 0);
  599. }
  600. /*
  601. * Test that the registration of an HDMI connector with a NULL product
  602. * fails.
  603. */
  604. static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
  605. {
  606. struct drm_connector_init_priv *priv = test->priv;
  607. int ret;
  608. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  609. "Vendor", NULL,
  610. &dummy_funcs,
  611. &dummy_hdmi_funcs,
  612. DRM_MODE_CONNECTOR_HDMIA,
  613. &priv->ddc,
  614. BIT(HDMI_COLORSPACE_RGB),
  615. 8);
  616. KUNIT_EXPECT_LT(test, ret, 0);
  617. }
  618. /*
  619. * Test that the registration of a connector with a valid, shorter than
  620. * the max length, product name succeeds, and is stored padded with 0.
  621. */
  622. static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
  623. {
  624. struct drm_connector_init_priv *priv = test->priv;
  625. const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
  626. 'P', 'r', 'o', 'd',
  627. };
  628. const char *product_name = "Prod";
  629. int ret;
  630. KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
  631. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  632. "Vendor", product_name,
  633. &dummy_funcs,
  634. &dummy_hdmi_funcs,
  635. DRM_MODE_CONNECTOR_HDMIA,
  636. &priv->ddc,
  637. BIT(HDMI_COLORSPACE_RGB),
  638. 8);
  639. KUNIT_EXPECT_EQ(test, ret, 0);
  640. KUNIT_EXPECT_MEMEQ(test,
  641. priv->connector.hdmi.product,
  642. expected_product,
  643. sizeof(priv->connector.hdmi.product));
  644. }
  645. /*
  646. * Test that the registration of a connector with a valid, at max
  647. * length, product name succeeds, and is stored padded without any
  648. * trailing \0.
  649. */
  650. static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
  651. {
  652. struct drm_connector_init_priv *priv = test->priv;
  653. const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
  654. 'P', 'r', 'o', 'd', 'u', 'c', 't',
  655. 'P', 'r', 'o', 'd', 'u', 'c', 't',
  656. 'P', 'r',
  657. };
  658. const char *product_name = "ProductProductPr";
  659. int ret;
  660. KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
  661. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  662. "Vendor", product_name,
  663. &dummy_funcs,
  664. &dummy_hdmi_funcs,
  665. DRM_MODE_CONNECTOR_HDMIA,
  666. &priv->ddc,
  667. BIT(HDMI_COLORSPACE_RGB),
  668. 8);
  669. KUNIT_EXPECT_EQ(test, ret, 0);
  670. KUNIT_EXPECT_MEMEQ(test,
  671. priv->connector.hdmi.product,
  672. expected_product,
  673. sizeof(priv->connector.hdmi.product));
  674. }
  675. /*
  676. * Test that the registration of a connector with a product name larger
  677. * than the maximum length fails.
  678. */
  679. static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
  680. {
  681. struct drm_connector_init_priv *priv = test->priv;
  682. const char *product_name = "ProductProductProduct";
  683. int ret;
  684. KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
  685. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  686. "Vendor", product_name,
  687. &dummy_funcs,
  688. &dummy_hdmi_funcs,
  689. DRM_MODE_CONNECTOR_HDMIA,
  690. &priv->ddc,
  691. BIT(HDMI_COLORSPACE_RGB),
  692. 8);
  693. KUNIT_EXPECT_LT(test, ret, 0);
  694. }
  695. /*
  696. * Test that the registration of a connector with a vendor name smaller
  697. * than the maximum length succeeds, and is stored padded with zeros.
  698. */
  699. static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
  700. {
  701. struct drm_connector_init_priv *priv = test->priv;
  702. const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
  703. 'V', 'e', 'n', 'd',
  704. };
  705. const char *vendor_name = "Vend";
  706. int ret;
  707. KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
  708. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  709. vendor_name, "Product",
  710. &dummy_funcs,
  711. &dummy_hdmi_funcs,
  712. DRM_MODE_CONNECTOR_HDMIA,
  713. &priv->ddc,
  714. BIT(HDMI_COLORSPACE_RGB),
  715. 8);
  716. KUNIT_EXPECT_EQ(test, ret, 0);
  717. KUNIT_EXPECT_MEMEQ(test,
  718. priv->connector.hdmi.vendor,
  719. expected_vendor,
  720. sizeof(priv->connector.hdmi.vendor));
  721. }
  722. /*
  723. * Test that the registration of a connector with a vendor name at the
  724. * maximum length succeeds, and is stored padded without the trailing
  725. * zero.
  726. */
  727. static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
  728. {
  729. struct drm_connector_init_priv *priv = test->priv;
  730. const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
  731. 'V', 'e', 'n', 'd', 'o', 'r',
  732. 'V', 'e',
  733. };
  734. const char *vendor_name = "VendorVe";
  735. int ret;
  736. KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
  737. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  738. vendor_name, "Product",
  739. &dummy_funcs,
  740. &dummy_hdmi_funcs,
  741. DRM_MODE_CONNECTOR_HDMIA,
  742. &priv->ddc,
  743. BIT(HDMI_COLORSPACE_RGB),
  744. 8);
  745. KUNIT_EXPECT_EQ(test, ret, 0);
  746. KUNIT_EXPECT_MEMEQ(test,
  747. priv->connector.hdmi.vendor,
  748. expected_vendor,
  749. sizeof(priv->connector.hdmi.vendor));
  750. }
  751. /*
  752. * Test that the registration of a connector with a vendor name larger
  753. * than the maximum length fails.
  754. */
  755. static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
  756. {
  757. struct drm_connector_init_priv *priv = test->priv;
  758. const char *vendor_name = "VendorVendor";
  759. int ret;
  760. KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
  761. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  762. vendor_name, "Product",
  763. &dummy_funcs,
  764. &dummy_hdmi_funcs,
  765. DRM_MODE_CONNECTOR_HDMIA,
  766. &priv->ddc,
  767. BIT(HDMI_COLORSPACE_RGB),
  768. 8);
  769. KUNIT_EXPECT_LT(test, ret, 0);
  770. }
  771. /*
  772. * Test that the registration of a connector with an invalid maximum bpc
  773. * count fails.
  774. */
  775. static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
  776. {
  777. struct drm_connector_init_priv *priv = test->priv;
  778. int ret;
  779. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  780. "Vendor", "Product",
  781. &dummy_funcs,
  782. &dummy_hdmi_funcs,
  783. DRM_MODE_CONNECTOR_HDMIA,
  784. &priv->ddc,
  785. BIT(HDMI_COLORSPACE_RGB),
  786. 9);
  787. KUNIT_EXPECT_LT(test, ret, 0);
  788. }
  789. /*
  790. * Test that the registration of a connector with a null maximum bpc
  791. * count fails.
  792. */
  793. static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
  794. {
  795. struct drm_connector_init_priv *priv = test->priv;
  796. int ret;
  797. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  798. "Vendor", "Product",
  799. &dummy_funcs,
  800. &dummy_hdmi_funcs,
  801. DRM_MODE_CONNECTOR_HDMIA,
  802. &priv->ddc,
  803. BIT(HDMI_COLORSPACE_RGB),
  804. 0);
  805. KUNIT_EXPECT_LT(test, ret, 0);
  806. }
  807. /*
  808. * Test that the registration of a connector with a maximum bpc count of
  809. * 8 succeeds, registers the max bpc property, but doesn't register the
  810. * HDR output metadata one.
  811. */
  812. static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
  813. {
  814. struct drm_connector_init_priv *priv = test->priv;
  815. struct drm_connector_state *state;
  816. struct drm_connector *connector = &priv->connector;
  817. struct drm_property *prop;
  818. uint64_t val;
  819. int ret;
  820. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  821. "Vendor", "Product",
  822. &dummy_funcs,
  823. &dummy_hdmi_funcs,
  824. DRM_MODE_CONNECTOR_HDMIA,
  825. &priv->ddc,
  826. BIT(HDMI_COLORSPACE_RGB),
  827. 8);
  828. KUNIT_EXPECT_EQ(test, ret, 0);
  829. prop = connector->max_bpc_property;
  830. KUNIT_ASSERT_NOT_NULL(test, prop);
  831. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  832. ret = drm_object_property_get_default_value(&connector->base, prop, &val);
  833. KUNIT_EXPECT_EQ(test, ret, 0);
  834. KUNIT_EXPECT_EQ(test, val, 8);
  835. state = connector->state;
  836. KUNIT_EXPECT_EQ(test, state->max_bpc, 8);
  837. KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8);
  838. prop = priv->drm.mode_config.hdr_output_metadata_property;
  839. KUNIT_ASSERT_NOT_NULL(test, prop);
  840. KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  841. }
  842. /*
  843. * Test that the registration of a connector with a maximum bpc count of
  844. * 10 succeeds and registers the max bpc and HDR output metadata
  845. * properties.
  846. */
  847. static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
  848. {
  849. struct drm_connector_init_priv *priv = test->priv;
  850. struct drm_connector_state *state;
  851. struct drm_connector *connector = &priv->connector;
  852. struct drm_property *prop;
  853. uint64_t val;
  854. int ret;
  855. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  856. "Vendor", "Product",
  857. &dummy_funcs,
  858. &dummy_hdmi_funcs,
  859. DRM_MODE_CONNECTOR_HDMIA,
  860. &priv->ddc,
  861. BIT(HDMI_COLORSPACE_RGB),
  862. 10);
  863. KUNIT_EXPECT_EQ(test, ret, 0);
  864. prop = connector->max_bpc_property;
  865. KUNIT_ASSERT_NOT_NULL(test, prop);
  866. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  867. ret = drm_object_property_get_default_value(&connector->base, prop, &val);
  868. KUNIT_EXPECT_EQ(test, ret, 0);
  869. KUNIT_EXPECT_EQ(test, val, 10);
  870. state = connector->state;
  871. KUNIT_EXPECT_EQ(test, state->max_bpc, 10);
  872. KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10);
  873. prop = priv->drm.mode_config.hdr_output_metadata_property;
  874. KUNIT_ASSERT_NOT_NULL(test, prop);
  875. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  876. }
  877. /*
  878. * Test that the registration of a connector with a maximum bpc count of
  879. * 12 succeeds and registers the max bpc and HDR output metadata
  880. * properties.
  881. */
  882. static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
  883. {
  884. struct drm_connector_init_priv *priv = test->priv;
  885. struct drm_connector_state *state;
  886. struct drm_connector *connector = &priv->connector;
  887. struct drm_property *prop;
  888. uint64_t val;
  889. int ret;
  890. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  891. "Vendor", "Product",
  892. &dummy_funcs,
  893. &dummy_hdmi_funcs,
  894. DRM_MODE_CONNECTOR_HDMIA,
  895. &priv->ddc,
  896. BIT(HDMI_COLORSPACE_RGB),
  897. 12);
  898. KUNIT_EXPECT_EQ(test, ret, 0);
  899. prop = connector->max_bpc_property;
  900. KUNIT_ASSERT_NOT_NULL(test, prop);
  901. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  902. ret = drm_object_property_get_default_value(&connector->base, prop, &val);
  903. KUNIT_EXPECT_EQ(test, ret, 0);
  904. KUNIT_EXPECT_EQ(test, val, 12);
  905. state = connector->state;
  906. KUNIT_EXPECT_EQ(test, state->max_bpc, 12);
  907. KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12);
  908. prop = priv->drm.mode_config.hdr_output_metadata_property;
  909. KUNIT_ASSERT_NOT_NULL(test, prop);
  910. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  911. }
  912. /*
  913. * Test that the registration of an HDMI connector with no supported
  914. * format fails.
  915. */
  916. static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
  917. {
  918. struct drm_connector_init_priv *priv = test->priv;
  919. int ret;
  920. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  921. "Vendor", "Product",
  922. &dummy_funcs,
  923. &dummy_hdmi_funcs,
  924. DRM_MODE_CONNECTOR_HDMIA,
  925. &priv->ddc,
  926. 0,
  927. 8);
  928. KUNIT_EXPECT_LT(test, ret, 0);
  929. }
  930. /*
  931. * Test that the registration of an HDMI connector not listing RGB as a
  932. * supported format fails.
  933. */
  934. static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
  935. {
  936. struct drm_connector_init_priv *priv = test->priv;
  937. int ret;
  938. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  939. "Vendor", "Product",
  940. &dummy_funcs,
  941. &dummy_hdmi_funcs,
  942. DRM_MODE_CONNECTOR_HDMIA,
  943. &priv->ddc,
  944. BIT(HDMI_COLORSPACE_YUV422),
  945. 8);
  946. KUNIT_EXPECT_LT(test, ret, 0);
  947. }
  948. struct drm_connector_hdmi_init_formats_yuv420_allowed_test {
  949. unsigned long supported_formats;
  950. bool yuv420_allowed;
  951. int expected_result;
  952. };
  953. #define YUV420_ALLOWED_TEST(_formats, _allowed, _result) \
  954. { \
  955. .supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats), \
  956. .yuv420_allowed = _allowed, \
  957. .expected_result = _result, \
  958. }
  959. static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test
  960. drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = {
  961. YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0),
  962. YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL),
  963. YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL),
  964. YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0),
  965. };
  966. static void
  967. drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t,
  968. char *desc)
  969. {
  970. sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d",
  971. t->supported_formats, t->yuv420_allowed);
  972. }
  973. KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed,
  974. drm_connector_hdmi_init_formats_yuv420_allowed_tests,
  975. drm_connector_hdmi_init_formats_yuv420_allowed_desc);
  976. /*
  977. * Test that the registration of an HDMI connector succeeds only when
  978. * the presence of YUV420 in the supported formats matches the value
  979. * of the ycbcr_420_allowed flag.
  980. */
  981. static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test)
  982. {
  983. const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params;
  984. struct drm_connector_init_priv *priv = test->priv;
  985. int ret;
  986. params = test->param_value;
  987. priv->connector.ycbcr_420_allowed = params->yuv420_allowed;
  988. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  989. "Vendor", "Product",
  990. &dummy_funcs,
  991. &dummy_hdmi_funcs,
  992. DRM_MODE_CONNECTOR_HDMIA,
  993. &priv->ddc,
  994. params->supported_formats,
  995. 8);
  996. KUNIT_EXPECT_EQ(test, ret, params->expected_result);
  997. }
  998. /*
  999. * Test that the registration of an HDMI connector with an HDMI
  1000. * connector type succeeds.
  1001. */
  1002. static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
  1003. {
  1004. struct drm_connector_init_priv *priv = test->priv;
  1005. unsigned int connector_type = *(unsigned int *)test->param_value;
  1006. int ret;
  1007. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  1008. "Vendor", "Product",
  1009. &dummy_funcs,
  1010. &dummy_hdmi_funcs,
  1011. connector_type,
  1012. &priv->ddc,
  1013. BIT(HDMI_COLORSPACE_RGB),
  1014. 8);
  1015. KUNIT_EXPECT_EQ(test, ret, 0);
  1016. }
  1017. static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
  1018. DRM_MODE_CONNECTOR_HDMIA,
  1019. DRM_MODE_CONNECTOR_HDMIB,
  1020. };
  1021. static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
  1022. {
  1023. sprintf(desc, "%s", drm_get_connector_type_name(*type));
  1024. }
  1025. KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
  1026. drm_connector_hdmi_init_type_valid_tests,
  1027. drm_connector_hdmi_init_type_desc);
  1028. /*
  1029. * Test that the registration of an HDMI connector with an !HDMI
  1030. * connector type fails.
  1031. */
  1032. static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
  1033. {
  1034. struct drm_connector_init_priv *priv = test->priv;
  1035. unsigned int connector_type = *(unsigned int *)test->param_value;
  1036. int ret;
  1037. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  1038. "Vendor", "Product",
  1039. &dummy_funcs,
  1040. &dummy_hdmi_funcs,
  1041. connector_type,
  1042. &priv->ddc,
  1043. BIT(HDMI_COLORSPACE_RGB),
  1044. 8);
  1045. KUNIT_EXPECT_LT(test, ret, 0);
  1046. }
  1047. static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
  1048. DRM_MODE_CONNECTOR_Unknown,
  1049. DRM_MODE_CONNECTOR_VGA,
  1050. DRM_MODE_CONNECTOR_DVII,
  1051. DRM_MODE_CONNECTOR_DVID,
  1052. DRM_MODE_CONNECTOR_DVIA,
  1053. DRM_MODE_CONNECTOR_Composite,
  1054. DRM_MODE_CONNECTOR_SVIDEO,
  1055. DRM_MODE_CONNECTOR_LVDS,
  1056. DRM_MODE_CONNECTOR_Component,
  1057. DRM_MODE_CONNECTOR_9PinDIN,
  1058. DRM_MODE_CONNECTOR_DisplayPort,
  1059. DRM_MODE_CONNECTOR_TV,
  1060. DRM_MODE_CONNECTOR_eDP,
  1061. DRM_MODE_CONNECTOR_VIRTUAL,
  1062. DRM_MODE_CONNECTOR_DSI,
  1063. DRM_MODE_CONNECTOR_DPI,
  1064. DRM_MODE_CONNECTOR_WRITEBACK,
  1065. DRM_MODE_CONNECTOR_SPI,
  1066. DRM_MODE_CONNECTOR_USB,
  1067. };
  1068. KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
  1069. drm_connector_hdmi_init_type_invalid_tests,
  1070. drm_connector_hdmi_init_type_desc);
  1071. static struct kunit_case drmm_connector_hdmi_init_tests[] = {
  1072. KUNIT_CASE(drm_test_connector_hdmi_init_valid),
  1073. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
  1074. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
  1075. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
  1076. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
  1077. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
  1078. KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
  1079. KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
  1080. KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed,
  1081. drm_connector_hdmi_init_formats_yuv420_allowed_gen_params),
  1082. KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
  1083. KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
  1084. KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
  1085. KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
  1086. KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
  1087. KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
  1088. KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
  1089. KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
  1090. KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
  1091. KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
  1092. drm_connector_hdmi_init_type_valid_gen_params),
  1093. KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
  1094. drm_connector_hdmi_init_type_invalid_gen_params),
  1095. { }
  1096. };
  1097. static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
  1098. .name = "drmm_connector_hdmi_init",
  1099. .init = drm_test_connector_init,
  1100. .test_cases = drmm_connector_hdmi_init_tests,
  1101. };
  1102. struct drm_get_tv_mode_from_name_test {
  1103. const char *name;
  1104. enum drm_connector_tv_mode expected_mode;
  1105. };
  1106. #define TV_MODE_NAME(_name, _mode) \
  1107. { \
  1108. .name = _name, \
  1109. .expected_mode = _mode, \
  1110. }
  1111. static void drm_test_get_tv_mode_from_name_valid(struct kunit *test)
  1112. {
  1113. const struct drm_get_tv_mode_from_name_test *params = test->param_value;
  1114. KUNIT_EXPECT_EQ(test,
  1115. drm_get_tv_mode_from_name(params->name, strlen(params->name)),
  1116. params->expected_mode);
  1117. }
  1118. static const
  1119. struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = {
  1120. TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC),
  1121. TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443),
  1122. TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J),
  1123. TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL),
  1124. TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M),
  1125. TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N),
  1126. TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM),
  1127. TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME),
  1128. };
  1129. static void
  1130. drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t,
  1131. char *desc)
  1132. {
  1133. sprintf(desc, "%s", t->name);
  1134. }
  1135. KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid,
  1136. drm_get_tv_mode_from_name_valid_tests,
  1137. drm_get_tv_mode_from_name_valid_desc);
  1138. static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test)
  1139. {
  1140. const char *name = "NTS";
  1141. int ret;
  1142. ret = drm_get_tv_mode_from_name(name, strlen(name));
  1143. KUNIT_EXPECT_LT(test, ret, 0);
  1144. };
  1145. static struct kunit_case drm_get_tv_mode_from_name_tests[] = {
  1146. KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid,
  1147. drm_get_tv_mode_from_name_valid_gen_params),
  1148. KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated),
  1149. { }
  1150. };
  1151. static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
  1152. .name = "drm_get_tv_mode_from_name",
  1153. .test_cases = drm_get_tv_mode_from_name_tests,
  1154. };
  1155. struct drm_hdmi_connector_get_broadcast_rgb_name_test {
  1156. unsigned int kind;
  1157. const char *expected_name;
  1158. };
  1159. #define BROADCAST_RGB_TEST(_kind, _name) \
  1160. { \
  1161. .kind = _kind, \
  1162. .expected_name = _name, \
  1163. }
  1164. static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
  1165. {
  1166. const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
  1167. test->param_value;
  1168. KUNIT_EXPECT_STREQ(test,
  1169. drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
  1170. params->expected_name);
  1171. }
  1172. static const
  1173. struct drm_hdmi_connector_get_broadcast_rgb_name_test
  1174. drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
  1175. BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
  1176. BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
  1177. BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
  1178. };
  1179. static void
  1180. drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
  1181. char *desc)
  1182. {
  1183. sprintf(desc, "%s", t->expected_name);
  1184. }
  1185. KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
  1186. drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
  1187. drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
  1188. static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
  1189. {
  1190. KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
  1191. };
  1192. static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
  1193. KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
  1194. drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
  1195. KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
  1196. { }
  1197. };
  1198. static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
  1199. .name = "drm_hdmi_connector_get_broadcast_rgb_name",
  1200. .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
  1201. };
  1202. struct drm_hdmi_connector_get_output_format_name_test {
  1203. unsigned int kind;
  1204. const char *expected_name;
  1205. };
  1206. #define OUTPUT_FORMAT_TEST(_kind, _name) \
  1207. { \
  1208. .kind = _kind, \
  1209. .expected_name = _name, \
  1210. }
  1211. static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
  1212. {
  1213. const struct drm_hdmi_connector_get_output_format_name_test *params =
  1214. test->param_value;
  1215. KUNIT_EXPECT_STREQ(test,
  1216. drm_hdmi_connector_get_output_format_name(params->kind),
  1217. params->expected_name);
  1218. }
  1219. static const
  1220. struct drm_hdmi_connector_get_output_format_name_test
  1221. drm_hdmi_connector_get_output_format_name_valid_tests[] = {
  1222. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
  1223. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
  1224. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
  1225. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
  1226. };
  1227. static void
  1228. drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
  1229. char *desc)
  1230. {
  1231. sprintf(desc, "%s", t->expected_name);
  1232. }
  1233. KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
  1234. drm_hdmi_connector_get_output_format_name_valid_tests,
  1235. drm_hdmi_connector_get_output_format_name_valid_desc);
  1236. static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
  1237. {
  1238. KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
  1239. };
  1240. static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
  1241. KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
  1242. drm_hdmi_connector_get_output_format_name_valid_gen_params),
  1243. KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
  1244. { }
  1245. };
  1246. static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
  1247. .name = "drm_hdmi_connector_get_output_format_name",
  1248. .test_cases = drm_hdmi_connector_get_output_format_name_tests,
  1249. };
  1250. static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
  1251. {
  1252. struct drm_connector_init_priv *priv = test->priv;
  1253. struct drm_connector *connector = &priv->connector;
  1254. struct drm_property *prop;
  1255. int ret;
  1256. ret = drmm_connector_init(&priv->drm, connector,
  1257. &dummy_funcs,
  1258. DRM_MODE_CONNECTOR_HDMIA,
  1259. &priv->ddc);
  1260. KUNIT_ASSERT_EQ(test, ret, 0);
  1261. ret = drm_connector_attach_broadcast_rgb_property(connector);
  1262. KUNIT_ASSERT_EQ(test, ret, 0);
  1263. prop = connector->broadcast_rgb_property;
  1264. KUNIT_ASSERT_NOT_NULL(test, prop);
  1265. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  1266. }
  1267. static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
  1268. {
  1269. struct drm_connector_init_priv *priv = test->priv;
  1270. struct drm_connector *connector = &priv->connector;
  1271. struct drm_property *prop;
  1272. int ret;
  1273. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  1274. "Vendor", "Product",
  1275. &dummy_funcs,
  1276. &dummy_hdmi_funcs,
  1277. DRM_MODE_CONNECTOR_HDMIA,
  1278. &priv->ddc,
  1279. BIT(HDMI_COLORSPACE_RGB),
  1280. 8);
  1281. KUNIT_EXPECT_EQ(test, ret, 0);
  1282. ret = drm_connector_attach_broadcast_rgb_property(connector);
  1283. KUNIT_ASSERT_EQ(test, ret, 0);
  1284. prop = connector->broadcast_rgb_property;
  1285. KUNIT_ASSERT_NOT_NULL(test, prop);
  1286. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  1287. }
  1288. static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
  1289. KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
  1290. KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
  1291. { }
  1292. };
  1293. static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
  1294. .name = "drm_connector_attach_broadcast_rgb_property",
  1295. .init = drm_test_connector_init,
  1296. .test_cases = drm_connector_attach_broadcast_rgb_property_tests,
  1297. };
  1298. /*
  1299. * Test that for a given mode, with 8bpc and an RGB output the TMDS
  1300. * character rate is equal to the mode pixel clock.
  1301. */
  1302. static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
  1303. {
  1304. struct drm_connector_init_priv *priv = test->priv;
  1305. const struct drm_display_mode *mode;
  1306. unsigned long long rate;
  1307. struct drm_device *drm = &priv->drm;
  1308. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1309. KUNIT_ASSERT_NOT_NULL(test, mode);
  1310. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1311. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
  1312. KUNIT_ASSERT_GT(test, rate, 0);
  1313. KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
  1314. }
  1315. /*
  1316. * Test that for a given mode, with 10bpc and an RGB output the TMDS
  1317. * character rate is equal to 1.25 times the mode pixel clock.
  1318. */
  1319. static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
  1320. {
  1321. struct drm_connector_init_priv *priv = test->priv;
  1322. const struct drm_display_mode *mode;
  1323. unsigned long long rate;
  1324. struct drm_device *drm = &priv->drm;
  1325. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1326. KUNIT_ASSERT_NOT_NULL(test, mode);
  1327. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1328. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
  1329. KUNIT_ASSERT_GT(test, rate, 0);
  1330. KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
  1331. }
  1332. /*
  1333. * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
  1334. * character rate computation fails.
  1335. */
  1336. static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
  1337. {
  1338. struct drm_connector_init_priv *priv = test->priv;
  1339. const struct drm_display_mode *mode;
  1340. unsigned long long rate;
  1341. struct drm_device *drm = &priv->drm;
  1342. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
  1343. KUNIT_ASSERT_NOT_NULL(test, mode);
  1344. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
  1345. KUNIT_EXPECT_EQ(test, rate, 0);
  1346. }
  1347. /*
  1348. * Test that for a given mode, with 12bpc and an RGB output the TMDS
  1349. * character rate is equal to 1.5 times the mode pixel clock.
  1350. */
  1351. static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
  1352. {
  1353. struct drm_connector_init_priv *priv = test->priv;
  1354. const struct drm_display_mode *mode;
  1355. unsigned long long rate;
  1356. struct drm_device *drm = &priv->drm;
  1357. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1358. KUNIT_ASSERT_NOT_NULL(test, mode);
  1359. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1360. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
  1361. KUNIT_ASSERT_GT(test, rate, 0);
  1362. KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
  1363. }
  1364. /*
  1365. * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
  1366. * character rate computation fails.
  1367. */
  1368. static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
  1369. {
  1370. struct drm_connector_init_priv *priv = test->priv;
  1371. const struct drm_display_mode *mode;
  1372. unsigned long long rate;
  1373. struct drm_device *drm = &priv->drm;
  1374. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
  1375. KUNIT_ASSERT_NOT_NULL(test, mode);
  1376. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
  1377. KUNIT_EXPECT_EQ(test, rate, 0);
  1378. }
  1379. /*
  1380. * Test that for a mode with the pixel repetition flag, the TMDS
  1381. * character rate is indeed double the mode pixel clock.
  1382. */
  1383. static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
  1384. {
  1385. struct drm_connector_init_priv *priv = test->priv;
  1386. const struct drm_display_mode *mode;
  1387. unsigned long long rate;
  1388. struct drm_device *drm = &priv->drm;
  1389. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6);
  1390. KUNIT_ASSERT_NOT_NULL(test, mode);
  1391. KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1392. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
  1393. KUNIT_ASSERT_GT(test, rate, 0);
  1394. KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
  1395. }
  1396. /*
  1397. * Test that the TMDS character rate computation for the VIC modes
  1398. * explicitly listed in the spec as supporting YUV420 succeed and return
  1399. * half the mode pixel clock.
  1400. */
  1401. static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
  1402. {
  1403. struct drm_connector_init_priv *priv = test->priv;
  1404. const struct drm_display_mode *mode;
  1405. struct drm_device *drm = &priv->drm;
  1406. unsigned long long rate;
  1407. unsigned int vic = *(unsigned int *)test->param_value;
  1408. mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
  1409. KUNIT_ASSERT_NOT_NULL(test, mode);
  1410. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1411. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
  1412. KUNIT_ASSERT_GT(test, rate, 0);
  1413. KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
  1414. }
  1415. static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
  1416. 96, 97, 101, 102, 106, 107,
  1417. };
  1418. static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
  1419. {
  1420. sprintf(desc, "VIC %u", *vic);
  1421. }
  1422. KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid,
  1423. drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
  1424. drm_hdmi_compute_mode_clock_yuv420_vic_desc);
  1425. /*
  1426. * Test that for a given mode listed supporting it and an YUV420 output
  1427. * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
  1428. * pixel clock.
  1429. */
  1430. static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
  1431. {
  1432. struct drm_connector_init_priv *priv = test->priv;
  1433. const struct drm_display_mode *mode;
  1434. struct drm_device *drm = &priv->drm;
  1435. unsigned int vic =
  1436. drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
  1437. unsigned long long rate;
  1438. mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
  1439. KUNIT_ASSERT_NOT_NULL(test, mode);
  1440. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1441. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
  1442. KUNIT_ASSERT_GT(test, rate, 0);
  1443. KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
  1444. }
  1445. /*
  1446. * Test that for a given mode listed supporting it and an YUV420 output
  1447. * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
  1448. * pixel clock.
  1449. */
  1450. static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
  1451. {
  1452. struct drm_connector_init_priv *priv = test->priv;
  1453. const struct drm_display_mode *mode;
  1454. struct drm_device *drm = &priv->drm;
  1455. unsigned int vic =
  1456. drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
  1457. unsigned long long rate;
  1458. mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
  1459. KUNIT_ASSERT_NOT_NULL(test, mode);
  1460. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1461. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
  1462. KUNIT_ASSERT_GT(test, rate, 0);
  1463. KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
  1464. }
  1465. /*
  1466. * Test that for a given mode, the computation of the TMDS character
  1467. * rate with 8bpc and a YUV422 output succeeds and returns a rate equal
  1468. * to the mode pixel clock.
  1469. */
  1470. static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
  1471. {
  1472. struct drm_connector_init_priv *priv = test->priv;
  1473. const struct drm_display_mode *mode;
  1474. struct drm_device *drm = &priv->drm;
  1475. unsigned long long rate;
  1476. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1477. KUNIT_ASSERT_NOT_NULL(test, mode);
  1478. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1479. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
  1480. KUNIT_ASSERT_GT(test, rate, 0);
  1481. KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
  1482. }
  1483. /*
  1484. * Test that for a given mode, the computation of the TMDS character
  1485. * rate with 10bpc and a YUV422 output succeeds and returns a rate equal
  1486. * to the mode pixel clock.
  1487. */
  1488. static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
  1489. {
  1490. struct drm_connector_init_priv *priv = test->priv;
  1491. const struct drm_display_mode *mode;
  1492. struct drm_device *drm = &priv->drm;
  1493. unsigned long long rate;
  1494. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1495. KUNIT_ASSERT_NOT_NULL(test, mode);
  1496. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1497. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
  1498. KUNIT_ASSERT_GT(test, rate, 0);
  1499. KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
  1500. }
  1501. /*
  1502. * Test that for a given mode, the computation of the TMDS character
  1503. * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
  1504. * to the mode pixel clock.
  1505. */
  1506. static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
  1507. {
  1508. struct drm_connector_init_priv *priv = test->priv;
  1509. const struct drm_display_mode *mode;
  1510. struct drm_device *drm = &priv->drm;
  1511. unsigned long long rate;
  1512. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1513. KUNIT_ASSERT_NOT_NULL(test, mode);
  1514. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1515. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
  1516. KUNIT_ASSERT_GT(test, rate, 0);
  1517. KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
  1518. }
  1519. static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = {
  1520. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb),
  1521. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc),
  1522. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
  1523. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc),
  1524. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
  1525. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double),
  1526. KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
  1527. drm_hdmi_compute_mode_clock_yuv420_valid_gen_params),
  1528. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
  1529. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
  1530. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
  1531. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
  1532. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
  1533. { }
  1534. };
  1535. static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = {
  1536. .name = "drm_test_connector_hdmi_compute_mode_clock",
  1537. .init = drm_test_connector_init,
  1538. .test_cases = drm_hdmi_compute_mode_clock_tests,
  1539. };
  1540. kunit_test_suites(
  1541. &drmm_connector_hdmi_init_test_suite,
  1542. &drmm_connector_init_test_suite,
  1543. &drm_connector_dynamic_init_test_suite,
  1544. &drm_connector_dynamic_register_early_test_suite,
  1545. &drm_connector_dynamic_register_test_suite,
  1546. &drm_connector_attach_broadcast_rgb_property_test_suite,
  1547. &drm_get_tv_mode_from_name_test_suite,
  1548. &drm_hdmi_compute_mode_clock_test_suite,
  1549. &drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
  1550. &drm_hdmi_connector_get_output_format_name_test_suite
  1551. );
  1552. MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
  1553. MODULE_DESCRIPTION("Kunit test for drm_modes functions");
  1554. MODULE_LICENSE("GPL");