drm_connector_test.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295
  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_kunit_helpers.h>
  11. #include <drm/drm_modes.h>
  12. #include <drm/display/drm_hdmi_helper.h>
  13. #include <kunit/test.h>
  14. #include "../drm_crtc_internal.h"
  15. struct drm_connector_init_priv {
  16. struct drm_device drm;
  17. struct drm_connector connector;
  18. struct i2c_adapter ddc;
  19. };
  20. static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
  21. };
  22. static const struct drm_connector_funcs dummy_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 dummy_ddc_xfer(struct i2c_adapter *adapter,
  28. struct i2c_msg *msgs, int num)
  29. {
  30. return num;
  31. }
  32. static u32 dummy_ddc_func(struct i2c_adapter *adapter)
  33. {
  34. return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
  35. }
  36. static const struct i2c_algorithm dummy_ddc_algorithm = {
  37. .master_xfer = dummy_ddc_xfer,
  38. .functionality = dummy_ddc_func,
  39. };
  40. static void i2c_del_adapter_wrapper(void *ptr)
  41. {
  42. struct i2c_adapter *adap = ptr;
  43. i2c_del_adapter(adap);
  44. }
  45. static int drm_test_connector_init(struct kunit *test)
  46. {
  47. struct drm_connector_init_priv *priv;
  48. struct device *dev;
  49. int ret;
  50. dev = drm_kunit_helper_alloc_device(test);
  51. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
  52. priv = drm_kunit_helper_alloc_drm_device(test, dev,
  53. struct drm_connector_init_priv, drm,
  54. DRIVER_MODESET | DRIVER_ATOMIC);
  55. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
  56. strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
  57. priv->ddc.owner = THIS_MODULE;
  58. priv->ddc.algo = &dummy_ddc_algorithm;
  59. priv->ddc.dev.parent = dev;
  60. ret = i2c_add_adapter(&priv->ddc);
  61. KUNIT_ASSERT_EQ(test, ret, 0);
  62. ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
  63. KUNIT_ASSERT_EQ(test, ret, 0);
  64. test->priv = priv;
  65. return 0;
  66. }
  67. /*
  68. * Test that the registration of a bog standard connector works as
  69. * expected and doesn't report any error.
  70. */
  71. static void drm_test_drmm_connector_init(struct kunit *test)
  72. {
  73. struct drm_connector_init_priv *priv = test->priv;
  74. int ret;
  75. ret = drmm_connector_init(&priv->drm, &priv->connector,
  76. &dummy_funcs,
  77. DRM_MODE_CONNECTOR_HDMIA,
  78. &priv->ddc);
  79. KUNIT_EXPECT_EQ(test, ret, 0);
  80. }
  81. /*
  82. * Test that the registration of a connector without a DDC adapter
  83. * doesn't report any error.
  84. */
  85. static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
  86. {
  87. struct drm_connector_init_priv *priv = test->priv;
  88. int ret;
  89. ret = drmm_connector_init(&priv->drm, &priv->connector,
  90. &dummy_funcs,
  91. DRM_MODE_CONNECTOR_HDMIA,
  92. NULL);
  93. KUNIT_EXPECT_EQ(test, ret, 0);
  94. }
  95. /*
  96. * Test that the registration of a connector succeeds for all possible
  97. * connector types.
  98. */
  99. static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
  100. {
  101. struct drm_connector_init_priv *priv = test->priv;
  102. unsigned int connector_type = *(unsigned int *)test->param_value;
  103. int ret;
  104. ret = drmm_connector_init(&priv->drm, &priv->connector,
  105. &dummy_funcs,
  106. connector_type,
  107. &priv->ddc);
  108. KUNIT_EXPECT_EQ(test, ret, 0);
  109. }
  110. static const unsigned int drm_connector_init_type_valid_tests[] = {
  111. DRM_MODE_CONNECTOR_Unknown,
  112. DRM_MODE_CONNECTOR_VGA,
  113. DRM_MODE_CONNECTOR_DVII,
  114. DRM_MODE_CONNECTOR_DVID,
  115. DRM_MODE_CONNECTOR_DVIA,
  116. DRM_MODE_CONNECTOR_Composite,
  117. DRM_MODE_CONNECTOR_SVIDEO,
  118. DRM_MODE_CONNECTOR_LVDS,
  119. DRM_MODE_CONNECTOR_Component,
  120. DRM_MODE_CONNECTOR_9PinDIN,
  121. DRM_MODE_CONNECTOR_DisplayPort,
  122. DRM_MODE_CONNECTOR_HDMIA,
  123. DRM_MODE_CONNECTOR_HDMIB,
  124. DRM_MODE_CONNECTOR_TV,
  125. DRM_MODE_CONNECTOR_eDP,
  126. DRM_MODE_CONNECTOR_VIRTUAL,
  127. DRM_MODE_CONNECTOR_DSI,
  128. DRM_MODE_CONNECTOR_DPI,
  129. DRM_MODE_CONNECTOR_WRITEBACK,
  130. DRM_MODE_CONNECTOR_SPI,
  131. DRM_MODE_CONNECTOR_USB,
  132. };
  133. static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
  134. {
  135. sprintf(desc, "%s", drm_get_connector_type_name(*type));
  136. }
  137. KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
  138. drm_connector_init_type_valid_tests,
  139. drm_connector_init_type_desc);
  140. static struct kunit_case drmm_connector_init_tests[] = {
  141. KUNIT_CASE(drm_test_drmm_connector_init),
  142. KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
  143. KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
  144. drm_connector_init_type_valid_gen_params),
  145. { }
  146. };
  147. static struct kunit_suite drmm_connector_init_test_suite = {
  148. .name = "drmm_connector_init",
  149. .init = drm_test_connector_init,
  150. .test_cases = drmm_connector_init_tests,
  151. };
  152. /*
  153. * Test that the registration of a bog standard connector works as
  154. * expected and doesn't report any error.
  155. */
  156. static void drm_test_connector_hdmi_init_valid(struct kunit *test)
  157. {
  158. struct drm_connector_init_priv *priv = test->priv;
  159. int ret;
  160. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  161. "Vendor", "Product",
  162. &dummy_funcs,
  163. &dummy_hdmi_funcs,
  164. DRM_MODE_CONNECTOR_HDMIA,
  165. &priv->ddc,
  166. BIT(HDMI_COLORSPACE_RGB),
  167. 8);
  168. KUNIT_EXPECT_EQ(test, ret, 0);
  169. }
  170. /*
  171. * Test that the registration of a connector without a DDC adapter
  172. * doesn't report any error.
  173. */
  174. static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
  175. {
  176. struct drm_connector_init_priv *priv = test->priv;
  177. int ret;
  178. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  179. "Vendor", "Product",
  180. &dummy_funcs,
  181. &dummy_hdmi_funcs,
  182. DRM_MODE_CONNECTOR_HDMIA,
  183. NULL,
  184. BIT(HDMI_COLORSPACE_RGB),
  185. 8);
  186. KUNIT_EXPECT_EQ(test, ret, 0);
  187. }
  188. /*
  189. * Test that the registration of an HDMI connector with a NULL vendor
  190. * fails.
  191. */
  192. static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
  193. {
  194. struct drm_connector_init_priv *priv = test->priv;
  195. int ret;
  196. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  197. NULL, "Product",
  198. &dummy_funcs,
  199. &dummy_hdmi_funcs,
  200. DRM_MODE_CONNECTOR_HDMIA,
  201. &priv->ddc,
  202. BIT(HDMI_COLORSPACE_RGB),
  203. 8);
  204. KUNIT_EXPECT_LT(test, ret, 0);
  205. }
  206. /*
  207. * Test that the registration of an HDMI connector with a NULL product
  208. * fails.
  209. */
  210. static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
  211. {
  212. struct drm_connector_init_priv *priv = test->priv;
  213. int ret;
  214. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  215. "Vendor", NULL,
  216. &dummy_funcs,
  217. &dummy_hdmi_funcs,
  218. DRM_MODE_CONNECTOR_HDMIA,
  219. &priv->ddc,
  220. BIT(HDMI_COLORSPACE_RGB),
  221. 8);
  222. KUNIT_EXPECT_LT(test, ret, 0);
  223. }
  224. /*
  225. * Test that the registration of a connector with a valid, shorter than
  226. * the max length, product name succeeds, and is stored padded with 0.
  227. */
  228. static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
  229. {
  230. struct drm_connector_init_priv *priv = test->priv;
  231. const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
  232. 'P', 'r', 'o', 'd',
  233. };
  234. const char *product_name = "Prod";
  235. int ret;
  236. KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
  237. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  238. "Vendor", product_name,
  239. &dummy_funcs,
  240. &dummy_hdmi_funcs,
  241. DRM_MODE_CONNECTOR_HDMIA,
  242. &priv->ddc,
  243. BIT(HDMI_COLORSPACE_RGB),
  244. 8);
  245. KUNIT_EXPECT_EQ(test, ret, 0);
  246. KUNIT_EXPECT_MEMEQ(test,
  247. priv->connector.hdmi.product,
  248. expected_product,
  249. sizeof(priv->connector.hdmi.product));
  250. }
  251. /*
  252. * Test that the registration of a connector with a valid, at max
  253. * length, product name succeeds, and is stored padded without any
  254. * trailing \0.
  255. */
  256. static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
  257. {
  258. struct drm_connector_init_priv *priv = test->priv;
  259. const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
  260. 'P', 'r', 'o', 'd', 'u', 'c', 't',
  261. 'P', 'r', 'o', 'd', 'u', 'c', 't',
  262. 'P', 'r',
  263. };
  264. const char *product_name = "ProductProductPr";
  265. int ret;
  266. KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
  267. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  268. "Vendor", product_name,
  269. &dummy_funcs,
  270. &dummy_hdmi_funcs,
  271. DRM_MODE_CONNECTOR_HDMIA,
  272. &priv->ddc,
  273. BIT(HDMI_COLORSPACE_RGB),
  274. 8);
  275. KUNIT_EXPECT_EQ(test, ret, 0);
  276. KUNIT_EXPECT_MEMEQ(test,
  277. priv->connector.hdmi.product,
  278. expected_product,
  279. sizeof(priv->connector.hdmi.product));
  280. }
  281. /*
  282. * Test that the registration of a connector with a product name larger
  283. * than the maximum length fails.
  284. */
  285. static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
  286. {
  287. struct drm_connector_init_priv *priv = test->priv;
  288. const char *product_name = "ProductProductProduct";
  289. int ret;
  290. KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
  291. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  292. "Vendor", product_name,
  293. &dummy_funcs,
  294. &dummy_hdmi_funcs,
  295. DRM_MODE_CONNECTOR_HDMIA,
  296. &priv->ddc,
  297. BIT(HDMI_COLORSPACE_RGB),
  298. 8);
  299. KUNIT_EXPECT_LT(test, ret, 0);
  300. }
  301. /*
  302. * Test that the registration of a connector with a vendor name smaller
  303. * than the maximum length succeeds, and is stored padded with zeros.
  304. */
  305. static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
  306. {
  307. struct drm_connector_init_priv *priv = test->priv;
  308. const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
  309. 'V', 'e', 'n', 'd',
  310. };
  311. const char *vendor_name = "Vend";
  312. int ret;
  313. KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
  314. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  315. vendor_name, "Product",
  316. &dummy_funcs,
  317. &dummy_hdmi_funcs,
  318. DRM_MODE_CONNECTOR_HDMIA,
  319. &priv->ddc,
  320. BIT(HDMI_COLORSPACE_RGB),
  321. 8);
  322. KUNIT_EXPECT_EQ(test, ret, 0);
  323. KUNIT_EXPECT_MEMEQ(test,
  324. priv->connector.hdmi.vendor,
  325. expected_vendor,
  326. sizeof(priv->connector.hdmi.vendor));
  327. }
  328. /*
  329. * Test that the registration of a connector with a vendor name at the
  330. * maximum length succeeds, and is stored padded without the trailing
  331. * zero.
  332. */
  333. static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
  334. {
  335. struct drm_connector_init_priv *priv = test->priv;
  336. const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
  337. 'V', 'e', 'n', 'd', 'o', 'r',
  338. 'V', 'e',
  339. };
  340. const char *vendor_name = "VendorVe";
  341. int ret;
  342. KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
  343. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  344. vendor_name, "Product",
  345. &dummy_funcs,
  346. &dummy_hdmi_funcs,
  347. DRM_MODE_CONNECTOR_HDMIA,
  348. &priv->ddc,
  349. BIT(HDMI_COLORSPACE_RGB),
  350. 8);
  351. KUNIT_EXPECT_EQ(test, ret, 0);
  352. KUNIT_EXPECT_MEMEQ(test,
  353. priv->connector.hdmi.vendor,
  354. expected_vendor,
  355. sizeof(priv->connector.hdmi.vendor));
  356. }
  357. /*
  358. * Test that the registration of a connector with a vendor name larger
  359. * than the maximum length fails.
  360. */
  361. static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
  362. {
  363. struct drm_connector_init_priv *priv = test->priv;
  364. const char *vendor_name = "VendorVendor";
  365. int ret;
  366. KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
  367. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  368. vendor_name, "Product",
  369. &dummy_funcs,
  370. &dummy_hdmi_funcs,
  371. DRM_MODE_CONNECTOR_HDMIA,
  372. &priv->ddc,
  373. BIT(HDMI_COLORSPACE_RGB),
  374. 8);
  375. KUNIT_EXPECT_LT(test, ret, 0);
  376. }
  377. /*
  378. * Test that the registration of a connector with an invalid maximum bpc
  379. * count fails.
  380. */
  381. static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
  382. {
  383. struct drm_connector_init_priv *priv = test->priv;
  384. int ret;
  385. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  386. "Vendor", "Product",
  387. &dummy_funcs,
  388. &dummy_hdmi_funcs,
  389. DRM_MODE_CONNECTOR_HDMIA,
  390. &priv->ddc,
  391. BIT(HDMI_COLORSPACE_RGB),
  392. 9);
  393. KUNIT_EXPECT_LT(test, ret, 0);
  394. }
  395. /*
  396. * Test that the registration of a connector with a null maximum bpc
  397. * count fails.
  398. */
  399. static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
  400. {
  401. struct drm_connector_init_priv *priv = test->priv;
  402. int ret;
  403. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  404. "Vendor", "Product",
  405. &dummy_funcs,
  406. &dummy_hdmi_funcs,
  407. DRM_MODE_CONNECTOR_HDMIA,
  408. &priv->ddc,
  409. BIT(HDMI_COLORSPACE_RGB),
  410. 0);
  411. KUNIT_EXPECT_LT(test, ret, 0);
  412. }
  413. /*
  414. * Test that the registration of a connector with a maximum bpc count of
  415. * 8 succeeds, registers the max bpc property, but doesn't register the
  416. * HDR output metadata one.
  417. */
  418. static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
  419. {
  420. struct drm_connector_init_priv *priv = test->priv;
  421. struct drm_connector_state *state;
  422. struct drm_connector *connector = &priv->connector;
  423. struct drm_property *prop;
  424. uint64_t val;
  425. int ret;
  426. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  427. "Vendor", "Product",
  428. &dummy_funcs,
  429. &dummy_hdmi_funcs,
  430. DRM_MODE_CONNECTOR_HDMIA,
  431. &priv->ddc,
  432. BIT(HDMI_COLORSPACE_RGB),
  433. 8);
  434. KUNIT_EXPECT_EQ(test, ret, 0);
  435. prop = connector->max_bpc_property;
  436. KUNIT_ASSERT_NOT_NULL(test, prop);
  437. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  438. ret = drm_object_property_get_default_value(&connector->base, prop, &val);
  439. KUNIT_EXPECT_EQ(test, ret, 0);
  440. KUNIT_EXPECT_EQ(test, val, 8);
  441. state = connector->state;
  442. KUNIT_EXPECT_EQ(test, state->max_bpc, 8);
  443. KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8);
  444. prop = priv->drm.mode_config.hdr_output_metadata_property;
  445. KUNIT_ASSERT_NOT_NULL(test, prop);
  446. KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  447. }
  448. /*
  449. * Test that the registration of a connector with a maximum bpc count of
  450. * 10 succeeds and registers the max bpc and HDR output metadata
  451. * properties.
  452. */
  453. static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
  454. {
  455. struct drm_connector_init_priv *priv = test->priv;
  456. struct drm_connector_state *state;
  457. struct drm_connector *connector = &priv->connector;
  458. struct drm_property *prop;
  459. uint64_t val;
  460. int ret;
  461. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  462. "Vendor", "Product",
  463. &dummy_funcs,
  464. &dummy_hdmi_funcs,
  465. DRM_MODE_CONNECTOR_HDMIA,
  466. &priv->ddc,
  467. BIT(HDMI_COLORSPACE_RGB),
  468. 10);
  469. KUNIT_EXPECT_EQ(test, ret, 0);
  470. prop = connector->max_bpc_property;
  471. KUNIT_ASSERT_NOT_NULL(test, prop);
  472. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  473. ret = drm_object_property_get_default_value(&connector->base, prop, &val);
  474. KUNIT_EXPECT_EQ(test, ret, 0);
  475. KUNIT_EXPECT_EQ(test, val, 10);
  476. state = connector->state;
  477. KUNIT_EXPECT_EQ(test, state->max_bpc, 10);
  478. KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10);
  479. prop = priv->drm.mode_config.hdr_output_metadata_property;
  480. KUNIT_ASSERT_NOT_NULL(test, prop);
  481. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  482. }
  483. /*
  484. * Test that the registration of a connector with a maximum bpc count of
  485. * 12 succeeds and registers the max bpc and HDR output metadata
  486. * properties.
  487. */
  488. static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
  489. {
  490. struct drm_connector_init_priv *priv = test->priv;
  491. struct drm_connector_state *state;
  492. struct drm_connector *connector = &priv->connector;
  493. struct drm_property *prop;
  494. uint64_t val;
  495. int ret;
  496. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  497. "Vendor", "Product",
  498. &dummy_funcs,
  499. &dummy_hdmi_funcs,
  500. DRM_MODE_CONNECTOR_HDMIA,
  501. &priv->ddc,
  502. BIT(HDMI_COLORSPACE_RGB),
  503. 12);
  504. KUNIT_EXPECT_EQ(test, ret, 0);
  505. prop = connector->max_bpc_property;
  506. KUNIT_ASSERT_NOT_NULL(test, prop);
  507. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  508. ret = drm_object_property_get_default_value(&connector->base, prop, &val);
  509. KUNIT_EXPECT_EQ(test, ret, 0);
  510. KUNIT_EXPECT_EQ(test, val, 12);
  511. state = connector->state;
  512. KUNIT_EXPECT_EQ(test, state->max_bpc, 12);
  513. KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12);
  514. prop = priv->drm.mode_config.hdr_output_metadata_property;
  515. KUNIT_ASSERT_NOT_NULL(test, prop);
  516. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  517. }
  518. /*
  519. * Test that the registration of an HDMI connector with no supported
  520. * format fails.
  521. */
  522. static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
  523. {
  524. struct drm_connector_init_priv *priv = test->priv;
  525. int ret;
  526. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  527. "Vendor", "Product",
  528. &dummy_funcs,
  529. &dummy_hdmi_funcs,
  530. DRM_MODE_CONNECTOR_HDMIA,
  531. &priv->ddc,
  532. 0,
  533. 8);
  534. KUNIT_EXPECT_LT(test, ret, 0);
  535. }
  536. /*
  537. * Test that the registration of an HDMI connector not listing RGB as a
  538. * supported format fails.
  539. */
  540. static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
  541. {
  542. struct drm_connector_init_priv *priv = test->priv;
  543. int ret;
  544. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  545. "Vendor", "Product",
  546. &dummy_funcs,
  547. &dummy_hdmi_funcs,
  548. DRM_MODE_CONNECTOR_HDMIA,
  549. &priv->ddc,
  550. BIT(HDMI_COLORSPACE_YUV422),
  551. 8);
  552. KUNIT_EXPECT_LT(test, ret, 0);
  553. }
  554. /*
  555. * Test that the registration of an HDMI connector with an HDMI
  556. * connector type succeeds.
  557. */
  558. static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
  559. {
  560. struct drm_connector_init_priv *priv = test->priv;
  561. unsigned int connector_type = *(unsigned int *)test->param_value;
  562. int ret;
  563. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  564. "Vendor", "Product",
  565. &dummy_funcs,
  566. &dummy_hdmi_funcs,
  567. connector_type,
  568. &priv->ddc,
  569. BIT(HDMI_COLORSPACE_RGB),
  570. 8);
  571. KUNIT_EXPECT_EQ(test, ret, 0);
  572. }
  573. static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
  574. DRM_MODE_CONNECTOR_HDMIA,
  575. DRM_MODE_CONNECTOR_HDMIB,
  576. };
  577. static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
  578. {
  579. sprintf(desc, "%s", drm_get_connector_type_name(*type));
  580. }
  581. KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
  582. drm_connector_hdmi_init_type_valid_tests,
  583. drm_connector_hdmi_init_type_desc);
  584. /*
  585. * Test that the registration of an HDMI connector with an !HDMI
  586. * connector type fails.
  587. */
  588. static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
  589. {
  590. struct drm_connector_init_priv *priv = test->priv;
  591. unsigned int connector_type = *(unsigned int *)test->param_value;
  592. int ret;
  593. ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
  594. "Vendor", "Product",
  595. &dummy_funcs,
  596. &dummy_hdmi_funcs,
  597. connector_type,
  598. &priv->ddc,
  599. BIT(HDMI_COLORSPACE_RGB),
  600. 8);
  601. KUNIT_EXPECT_LT(test, ret, 0);
  602. }
  603. static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
  604. DRM_MODE_CONNECTOR_Unknown,
  605. DRM_MODE_CONNECTOR_VGA,
  606. DRM_MODE_CONNECTOR_DVII,
  607. DRM_MODE_CONNECTOR_DVID,
  608. DRM_MODE_CONNECTOR_DVIA,
  609. DRM_MODE_CONNECTOR_Composite,
  610. DRM_MODE_CONNECTOR_SVIDEO,
  611. DRM_MODE_CONNECTOR_LVDS,
  612. DRM_MODE_CONNECTOR_Component,
  613. DRM_MODE_CONNECTOR_9PinDIN,
  614. DRM_MODE_CONNECTOR_DisplayPort,
  615. DRM_MODE_CONNECTOR_TV,
  616. DRM_MODE_CONNECTOR_eDP,
  617. DRM_MODE_CONNECTOR_VIRTUAL,
  618. DRM_MODE_CONNECTOR_DSI,
  619. DRM_MODE_CONNECTOR_DPI,
  620. DRM_MODE_CONNECTOR_WRITEBACK,
  621. DRM_MODE_CONNECTOR_SPI,
  622. DRM_MODE_CONNECTOR_USB,
  623. };
  624. KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
  625. drm_connector_hdmi_init_type_invalid_tests,
  626. drm_connector_hdmi_init_type_desc);
  627. static struct kunit_case drmm_connector_hdmi_init_tests[] = {
  628. KUNIT_CASE(drm_test_connector_hdmi_init_valid),
  629. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
  630. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
  631. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
  632. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
  633. KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
  634. KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
  635. KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
  636. KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
  637. KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
  638. KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
  639. KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
  640. KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
  641. KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
  642. KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
  643. KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
  644. KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
  645. KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
  646. drm_connector_hdmi_init_type_valid_gen_params),
  647. KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
  648. drm_connector_hdmi_init_type_invalid_gen_params),
  649. { }
  650. };
  651. static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
  652. .name = "drmm_connector_hdmi_init",
  653. .init = drm_test_connector_init,
  654. .test_cases = drmm_connector_hdmi_init_tests,
  655. };
  656. struct drm_get_tv_mode_from_name_test {
  657. const char *name;
  658. enum drm_connector_tv_mode expected_mode;
  659. };
  660. #define TV_MODE_NAME(_name, _mode) \
  661. { \
  662. .name = _name, \
  663. .expected_mode = _mode, \
  664. }
  665. static void drm_test_get_tv_mode_from_name_valid(struct kunit *test)
  666. {
  667. const struct drm_get_tv_mode_from_name_test *params = test->param_value;
  668. KUNIT_EXPECT_EQ(test,
  669. drm_get_tv_mode_from_name(params->name, strlen(params->name)),
  670. params->expected_mode);
  671. }
  672. static const
  673. struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = {
  674. TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC),
  675. TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443),
  676. TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J),
  677. TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL),
  678. TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M),
  679. TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N),
  680. TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM),
  681. TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME),
  682. };
  683. static void
  684. drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t,
  685. char *desc)
  686. {
  687. sprintf(desc, "%s", t->name);
  688. }
  689. KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid,
  690. drm_get_tv_mode_from_name_valid_tests,
  691. drm_get_tv_mode_from_name_valid_desc);
  692. static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test)
  693. {
  694. const char *name = "NTS";
  695. int ret;
  696. ret = drm_get_tv_mode_from_name(name, strlen(name));
  697. KUNIT_EXPECT_LT(test, ret, 0);
  698. };
  699. static struct kunit_case drm_get_tv_mode_from_name_tests[] = {
  700. KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid,
  701. drm_get_tv_mode_from_name_valid_gen_params),
  702. KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated),
  703. { }
  704. };
  705. static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
  706. .name = "drm_get_tv_mode_from_name",
  707. .test_cases = drm_get_tv_mode_from_name_tests,
  708. };
  709. struct drm_hdmi_connector_get_broadcast_rgb_name_test {
  710. unsigned int kind;
  711. const char *expected_name;
  712. };
  713. #define BROADCAST_RGB_TEST(_kind, _name) \
  714. { \
  715. .kind = _kind, \
  716. .expected_name = _name, \
  717. }
  718. static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
  719. {
  720. const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
  721. test->param_value;
  722. KUNIT_EXPECT_STREQ(test,
  723. drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
  724. params->expected_name);
  725. }
  726. static const
  727. struct drm_hdmi_connector_get_broadcast_rgb_name_test
  728. drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
  729. BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
  730. BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
  731. BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
  732. };
  733. static void
  734. drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
  735. char *desc)
  736. {
  737. sprintf(desc, "%s", t->expected_name);
  738. }
  739. KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
  740. drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
  741. drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
  742. static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
  743. {
  744. KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
  745. };
  746. static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
  747. KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
  748. drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
  749. KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
  750. { }
  751. };
  752. static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
  753. .name = "drm_hdmi_connector_get_broadcast_rgb_name",
  754. .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
  755. };
  756. struct drm_hdmi_connector_get_output_format_name_test {
  757. unsigned int kind;
  758. const char *expected_name;
  759. };
  760. #define OUTPUT_FORMAT_TEST(_kind, _name) \
  761. { \
  762. .kind = _kind, \
  763. .expected_name = _name, \
  764. }
  765. static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
  766. {
  767. const struct drm_hdmi_connector_get_output_format_name_test *params =
  768. test->param_value;
  769. KUNIT_EXPECT_STREQ(test,
  770. drm_hdmi_connector_get_output_format_name(params->kind),
  771. params->expected_name);
  772. }
  773. static const
  774. struct drm_hdmi_connector_get_output_format_name_test
  775. drm_hdmi_connector_get_output_format_name_valid_tests[] = {
  776. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
  777. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
  778. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
  779. OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
  780. };
  781. static void
  782. drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
  783. char *desc)
  784. {
  785. sprintf(desc, "%s", t->expected_name);
  786. }
  787. KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
  788. drm_hdmi_connector_get_output_format_name_valid_tests,
  789. drm_hdmi_connector_get_output_format_name_valid_desc);
  790. static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
  791. {
  792. KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
  793. };
  794. static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
  795. KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
  796. drm_hdmi_connector_get_output_format_name_valid_gen_params),
  797. KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
  798. { }
  799. };
  800. static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
  801. .name = "drm_hdmi_connector_get_output_format_name",
  802. .test_cases = drm_hdmi_connector_get_output_format_name_tests,
  803. };
  804. static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
  805. {
  806. struct drm_connector_init_priv *priv = test->priv;
  807. struct drm_connector *connector = &priv->connector;
  808. struct drm_property *prop;
  809. int ret;
  810. ret = drmm_connector_init(&priv->drm, connector,
  811. &dummy_funcs,
  812. DRM_MODE_CONNECTOR_HDMIA,
  813. &priv->ddc);
  814. KUNIT_ASSERT_EQ(test, ret, 0);
  815. ret = drm_connector_attach_broadcast_rgb_property(connector);
  816. KUNIT_ASSERT_EQ(test, ret, 0);
  817. prop = connector->broadcast_rgb_property;
  818. KUNIT_ASSERT_NOT_NULL(test, prop);
  819. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  820. }
  821. static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
  822. {
  823. struct drm_connector_init_priv *priv = test->priv;
  824. struct drm_connector *connector = &priv->connector;
  825. struct drm_property *prop;
  826. int ret;
  827. ret = drmm_connector_hdmi_init(&priv->drm, connector,
  828. "Vendor", "Product",
  829. &dummy_funcs,
  830. &dummy_hdmi_funcs,
  831. DRM_MODE_CONNECTOR_HDMIA,
  832. &priv->ddc,
  833. BIT(HDMI_COLORSPACE_RGB),
  834. 8);
  835. KUNIT_EXPECT_EQ(test, ret, 0);
  836. ret = drm_connector_attach_broadcast_rgb_property(connector);
  837. KUNIT_ASSERT_EQ(test, ret, 0);
  838. prop = connector->broadcast_rgb_property;
  839. KUNIT_ASSERT_NOT_NULL(test, prop);
  840. KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
  841. }
  842. static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
  843. KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
  844. KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
  845. { }
  846. };
  847. static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
  848. .name = "drm_connector_attach_broadcast_rgb_property",
  849. .init = drm_test_connector_init,
  850. .test_cases = drm_connector_attach_broadcast_rgb_property_tests,
  851. };
  852. /*
  853. * Test that for a given mode, with 8bpc and an RGB output the TMDS
  854. * character rate is equal to the mode pixel clock.
  855. */
  856. static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
  857. {
  858. struct drm_connector_init_priv *priv = test->priv;
  859. const struct drm_display_mode *mode;
  860. unsigned long long rate;
  861. struct drm_device *drm = &priv->drm;
  862. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  863. KUNIT_ASSERT_NOT_NULL(test, mode);
  864. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  865. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
  866. KUNIT_ASSERT_GT(test, rate, 0);
  867. KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
  868. }
  869. /*
  870. * Test that for a given mode, with 10bpc and an RGB output the TMDS
  871. * character rate is equal to 1.25 times the mode pixel clock.
  872. */
  873. static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
  874. {
  875. struct drm_connector_init_priv *priv = test->priv;
  876. const struct drm_display_mode *mode;
  877. unsigned long long rate;
  878. struct drm_device *drm = &priv->drm;
  879. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  880. KUNIT_ASSERT_NOT_NULL(test, mode);
  881. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  882. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
  883. KUNIT_ASSERT_GT(test, rate, 0);
  884. KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
  885. }
  886. /*
  887. * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
  888. * character rate computation fails.
  889. */
  890. static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
  891. {
  892. struct drm_connector_init_priv *priv = test->priv;
  893. const struct drm_display_mode *mode;
  894. unsigned long long rate;
  895. struct drm_device *drm = &priv->drm;
  896. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
  897. KUNIT_ASSERT_NOT_NULL(test, mode);
  898. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
  899. KUNIT_EXPECT_EQ(test, rate, 0);
  900. }
  901. /*
  902. * Test that for a given mode, with 12bpc and an RGB output the TMDS
  903. * character rate is equal to 1.5 times the mode pixel clock.
  904. */
  905. static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
  906. {
  907. struct drm_connector_init_priv *priv = test->priv;
  908. const struct drm_display_mode *mode;
  909. unsigned long long rate;
  910. struct drm_device *drm = &priv->drm;
  911. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  912. KUNIT_ASSERT_NOT_NULL(test, mode);
  913. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  914. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
  915. KUNIT_ASSERT_GT(test, rate, 0);
  916. KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
  917. }
  918. /*
  919. * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
  920. * character rate computation fails.
  921. */
  922. static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
  923. {
  924. struct drm_connector_init_priv *priv = test->priv;
  925. const struct drm_display_mode *mode;
  926. unsigned long long rate;
  927. struct drm_device *drm = &priv->drm;
  928. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
  929. KUNIT_ASSERT_NOT_NULL(test, mode);
  930. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
  931. KUNIT_EXPECT_EQ(test, rate, 0);
  932. }
  933. /*
  934. * Test that for a mode with the pixel repetition flag, the TMDS
  935. * character rate is indeed double the mode pixel clock.
  936. */
  937. static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
  938. {
  939. struct drm_connector_init_priv *priv = test->priv;
  940. const struct drm_display_mode *mode;
  941. unsigned long long rate;
  942. struct drm_device *drm = &priv->drm;
  943. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6);
  944. KUNIT_ASSERT_NOT_NULL(test, mode);
  945. KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  946. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
  947. KUNIT_ASSERT_GT(test, rate, 0);
  948. KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
  949. }
  950. /*
  951. * Test that the TMDS character rate computation for the VIC modes
  952. * explicitly listed in the spec as supporting YUV420 succeed and return
  953. * half the mode pixel clock.
  954. */
  955. static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
  956. {
  957. struct drm_connector_init_priv *priv = test->priv;
  958. const struct drm_display_mode *mode;
  959. struct drm_device *drm = &priv->drm;
  960. unsigned long long rate;
  961. unsigned int vic = *(unsigned int *)test->param_value;
  962. mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
  963. KUNIT_ASSERT_NOT_NULL(test, mode);
  964. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  965. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
  966. KUNIT_ASSERT_GT(test, rate, 0);
  967. KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
  968. }
  969. static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
  970. 96, 97, 101, 102, 106, 107,
  971. };
  972. static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
  973. {
  974. sprintf(desc, "VIC %u", *vic);
  975. }
  976. KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid,
  977. drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
  978. drm_hdmi_compute_mode_clock_yuv420_vic_desc);
  979. /*
  980. * Test that for a given mode listed supporting it and an YUV420 output
  981. * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
  982. * pixel clock.
  983. */
  984. static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
  985. {
  986. struct drm_connector_init_priv *priv = test->priv;
  987. const struct drm_display_mode *mode;
  988. struct drm_device *drm = &priv->drm;
  989. unsigned int vic =
  990. drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
  991. unsigned long long rate;
  992. mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
  993. KUNIT_ASSERT_NOT_NULL(test, mode);
  994. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  995. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
  996. KUNIT_ASSERT_GT(test, rate, 0);
  997. KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
  998. }
  999. /*
  1000. * Test that for a given mode listed supporting it and an YUV420 output
  1001. * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
  1002. * pixel clock.
  1003. */
  1004. static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
  1005. {
  1006. struct drm_connector_init_priv *priv = test->priv;
  1007. const struct drm_display_mode *mode;
  1008. struct drm_device *drm = &priv->drm;
  1009. unsigned int vic =
  1010. drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
  1011. unsigned long long rate;
  1012. mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
  1013. KUNIT_ASSERT_NOT_NULL(test, mode);
  1014. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1015. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
  1016. KUNIT_ASSERT_GT(test, rate, 0);
  1017. KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
  1018. }
  1019. /*
  1020. * Test that for a given mode, the computation of the TMDS character
  1021. * rate with 8bpc and a YUV422 output succeeds and returns a rate equal
  1022. * to the mode pixel clock.
  1023. */
  1024. static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
  1025. {
  1026. struct drm_connector_init_priv *priv = test->priv;
  1027. const struct drm_display_mode *mode;
  1028. struct drm_device *drm = &priv->drm;
  1029. unsigned long long rate;
  1030. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1031. KUNIT_ASSERT_NOT_NULL(test, mode);
  1032. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1033. rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
  1034. KUNIT_ASSERT_GT(test, rate, 0);
  1035. KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
  1036. }
  1037. /*
  1038. * Test that for a given mode, the computation of the TMDS character
  1039. * rate with 10bpc and a YUV422 output succeeds and returns a rate equal
  1040. * to the mode pixel clock.
  1041. */
  1042. static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
  1043. {
  1044. struct drm_connector_init_priv *priv = test->priv;
  1045. const struct drm_display_mode *mode;
  1046. struct drm_device *drm = &priv->drm;
  1047. unsigned long long rate;
  1048. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1049. KUNIT_ASSERT_NOT_NULL(test, mode);
  1050. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1051. rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
  1052. KUNIT_ASSERT_GT(test, rate, 0);
  1053. KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
  1054. }
  1055. /*
  1056. * Test that for a given mode, the computation of the TMDS character
  1057. * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
  1058. * to the mode pixel clock.
  1059. */
  1060. static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
  1061. {
  1062. struct drm_connector_init_priv *priv = test->priv;
  1063. const struct drm_display_mode *mode;
  1064. struct drm_device *drm = &priv->drm;
  1065. unsigned long long rate;
  1066. mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
  1067. KUNIT_ASSERT_NOT_NULL(test, mode);
  1068. KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
  1069. rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
  1070. KUNIT_ASSERT_GT(test, rate, 0);
  1071. KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
  1072. }
  1073. static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = {
  1074. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb),
  1075. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc),
  1076. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
  1077. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc),
  1078. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
  1079. KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double),
  1080. KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
  1081. drm_hdmi_compute_mode_clock_yuv420_valid_gen_params),
  1082. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
  1083. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
  1084. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
  1085. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
  1086. KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
  1087. { }
  1088. };
  1089. static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = {
  1090. .name = "drm_test_connector_hdmi_compute_mode_clock",
  1091. .init = drm_test_connector_init,
  1092. .test_cases = drm_hdmi_compute_mode_clock_tests,
  1093. };
  1094. kunit_test_suites(
  1095. &drmm_connector_hdmi_init_test_suite,
  1096. &drmm_connector_init_test_suite,
  1097. &drm_connector_attach_broadcast_rgb_property_test_suite,
  1098. &drm_get_tv_mode_from_name_test_suite,
  1099. &drm_hdmi_compute_mode_clock_test_suite,
  1100. &drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
  1101. &drm_hdmi_connector_get_output_format_name_test_suite
  1102. );
  1103. MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
  1104. MODULE_DESCRIPTION("Kunit test for drm_modes functions");
  1105. MODULE_LICENSE("GPL");