drm_atomic_uapi.c 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737
  1. /*
  2. * Copyright (C) 2014 Red Hat
  3. * Copyright (C) 2014 Intel Corp.
  4. * Copyright (C) 2018 Intel Corp.
  5. * Copyright (c) 2020, The Linux Foundation. All rights reserved.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a
  8. * copy of this software and associated documentation files (the "Software"),
  9. * to deal in the Software without restriction, including without limitation
  10. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11. * and/or sell copies of the Software, and to permit persons to whom the
  12. * Software is furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  21. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  22. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. * OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. * Authors:
  26. * Rob Clark <robdclark@gmail.com>
  27. * Daniel Vetter <daniel.vetter@ffwll.ch>
  28. */
  29. #include <drm/drm_atomic.h>
  30. #include <drm/drm_atomic_helper.h>
  31. #include <drm/drm_atomic_uapi.h>
  32. #include <drm/drm_framebuffer.h>
  33. #include <drm/drm_print.h>
  34. #include <drm/drm_drv.h>
  35. #include <drm/drm_writeback.h>
  36. #include <drm/drm_vblank.h>
  37. #include <drm/drm_colorop.h>
  38. #include <linux/export.h>
  39. #include <linux/dma-fence.h>
  40. #include <linux/uaccess.h>
  41. #include <linux/sync_file.h>
  42. #include <linux/file.h>
  43. #include "drm_crtc_internal.h"
  44. /**
  45. * DOC: overview
  46. *
  47. * This file contains the marshalling and demarshalling glue for the atomic UAPI
  48. * in all its forms: The monster ATOMIC IOCTL itself, code for GET_PROPERTY and
  49. * SET_PROPERTY IOCTLs. Plus interface functions for compatibility helpers and
  50. * drivers which have special needs to construct their own atomic updates, e.g.
  51. * for load detect or similar.
  52. */
  53. /**
  54. * drm_atomic_set_mode_for_crtc - set mode for CRTC
  55. * @state: the CRTC whose incoming state to update
  56. * @mode: kernel-internal mode to use for the CRTC, or NULL to disable
  57. *
  58. * Set a mode (originating from the kernel) on the desired CRTC state and update
  59. * the enable property.
  60. *
  61. * RETURNS:
  62. * Zero on success, error code on failure. Cannot return -EDEADLK.
  63. */
  64. int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
  65. const struct drm_display_mode *mode)
  66. {
  67. struct drm_crtc *crtc = state->crtc;
  68. struct drm_mode_modeinfo umode;
  69. /* Early return for no change. */
  70. if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0)
  71. return 0;
  72. drm_property_blob_put(state->mode_blob);
  73. state->mode_blob = NULL;
  74. if (mode) {
  75. struct drm_property_blob *blob;
  76. drm_mode_convert_to_umode(&umode, mode);
  77. blob = drm_property_create_blob(crtc->dev,
  78. sizeof(umode), &umode);
  79. if (IS_ERR(blob))
  80. return PTR_ERR(blob);
  81. drm_mode_copy(&state->mode, mode);
  82. state->mode_blob = blob;
  83. state->enable = true;
  84. drm_dbg_atomic(crtc->dev,
  85. "Set [MODE:%s] for [CRTC:%d:%s] state %p\n",
  86. mode->name, crtc->base.id, crtc->name, state);
  87. } else {
  88. memset(&state->mode, 0, sizeof(state->mode));
  89. state->enable = false;
  90. drm_dbg_atomic(crtc->dev,
  91. "Set [NOMODE] for [CRTC:%d:%s] state %p\n",
  92. crtc->base.id, crtc->name, state);
  93. }
  94. return 0;
  95. }
  96. EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc);
  97. /**
  98. * drm_atomic_set_mode_prop_for_crtc - set mode for CRTC
  99. * @state: the CRTC whose incoming state to update
  100. * @blob: pointer to blob property to use for mode
  101. *
  102. * Set a mode (originating from a blob property) on the desired CRTC state.
  103. * This function will take a reference on the blob property for the CRTC state,
  104. * and release the reference held on the state's existing mode property, if any
  105. * was set.
  106. *
  107. * RETURNS:
  108. * Zero on success, error code on failure. Cannot return -EDEADLK.
  109. */
  110. int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
  111. struct drm_property_blob *blob)
  112. {
  113. struct drm_crtc *crtc = state->crtc;
  114. if (blob == state->mode_blob)
  115. return 0;
  116. drm_property_blob_put(state->mode_blob);
  117. state->mode_blob = NULL;
  118. memset(&state->mode, 0, sizeof(state->mode));
  119. if (blob) {
  120. int ret;
  121. if (blob->length != sizeof(struct drm_mode_modeinfo)) {
  122. drm_dbg_atomic(crtc->dev,
  123. "[CRTC:%d:%s] bad mode blob length: %zu\n",
  124. crtc->base.id, crtc->name,
  125. blob->length);
  126. return -EINVAL;
  127. }
  128. ret = drm_mode_convert_umode(crtc->dev,
  129. &state->mode, blob->data);
  130. if (ret) {
  131. drm_dbg_atomic(crtc->dev,
  132. "[CRTC:%d:%s] invalid mode (%s, %pe): " DRM_MODE_FMT "\n",
  133. crtc->base.id, crtc->name,
  134. drm_get_mode_status_name(state->mode.status),
  135. ERR_PTR(ret), DRM_MODE_ARG(&state->mode));
  136. return -EINVAL;
  137. }
  138. state->mode_blob = drm_property_blob_get(blob);
  139. state->enable = true;
  140. drm_dbg_atomic(crtc->dev,
  141. "Set [MODE:%s] for [CRTC:%d:%s] state %p\n",
  142. state->mode.name, crtc->base.id, crtc->name,
  143. state);
  144. } else {
  145. state->enable = false;
  146. drm_dbg_atomic(crtc->dev,
  147. "Set [NOMODE] for [CRTC:%d:%s] state %p\n",
  148. crtc->base.id, crtc->name, state);
  149. }
  150. return 0;
  151. }
  152. EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
  153. /**
  154. * drm_atomic_set_crtc_for_plane - set CRTC for plane
  155. * @plane_state: the plane whose incoming state to update
  156. * @crtc: CRTC to use for the plane
  157. *
  158. * Changing the assigned CRTC for a plane requires us to grab the lock and state
  159. * for the new CRTC, as needed. This function takes care of all these details
  160. * besides updating the pointer in the state object itself.
  161. *
  162. * Returns:
  163. * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
  164. * then the w/w mutex code has detected a deadlock and the entire atomic
  165. * sequence must be restarted. All other errors are fatal.
  166. */
  167. int
  168. drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
  169. struct drm_crtc *crtc)
  170. {
  171. struct drm_plane *plane = plane_state->plane;
  172. struct drm_crtc_state *crtc_state;
  173. /* Nothing to do for same crtc*/
  174. if (plane_state->crtc == crtc)
  175. return 0;
  176. if (plane_state->crtc) {
  177. crtc_state = drm_atomic_get_crtc_state(plane_state->state,
  178. plane_state->crtc);
  179. if (WARN_ON(IS_ERR(crtc_state)))
  180. return PTR_ERR(crtc_state);
  181. crtc_state->plane_mask &= ~drm_plane_mask(plane);
  182. }
  183. plane_state->crtc = crtc;
  184. if (crtc) {
  185. crtc_state = drm_atomic_get_crtc_state(plane_state->state,
  186. crtc);
  187. if (IS_ERR(crtc_state))
  188. return PTR_ERR(crtc_state);
  189. crtc_state->plane_mask |= drm_plane_mask(plane);
  190. }
  191. if (crtc)
  192. drm_dbg_atomic(plane->dev,
  193. "Link [PLANE:%d:%s] state %p to [CRTC:%d:%s]\n",
  194. plane->base.id, plane->name, plane_state,
  195. crtc->base.id, crtc->name);
  196. else
  197. drm_dbg_atomic(plane->dev,
  198. "Link [PLANE:%d:%s] state %p to [NOCRTC]\n",
  199. plane->base.id, plane->name, plane_state);
  200. return 0;
  201. }
  202. EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane);
  203. /**
  204. * drm_atomic_set_fb_for_plane - set framebuffer for plane
  205. * @plane_state: atomic state object for the plane
  206. * @fb: fb to use for the plane
  207. *
  208. * Changing the assigned framebuffer for a plane requires us to grab a reference
  209. * to the new fb and drop the reference to the old fb, if there is one. This
  210. * function takes care of all these details besides updating the pointer in the
  211. * state object itself.
  212. */
  213. void
  214. drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
  215. struct drm_framebuffer *fb)
  216. {
  217. struct drm_plane *plane = plane_state->plane;
  218. if (fb)
  219. drm_dbg_atomic(plane->dev,
  220. "Set [FB:%d] for [PLANE:%d:%s] state %p\n",
  221. fb->base.id, plane->base.id, plane->name,
  222. plane_state);
  223. else
  224. drm_dbg_atomic(plane->dev,
  225. "Set [NOFB] for [PLANE:%d:%s] state %p\n",
  226. plane->base.id, plane->name, plane_state);
  227. drm_framebuffer_assign(&plane_state->fb, fb);
  228. }
  229. EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
  230. /**
  231. * drm_atomic_set_colorop_for_plane - set colorop for plane
  232. * @plane_state: atomic state object for the plane
  233. * @colorop: colorop to use for the plane
  234. *
  235. * Helper function to select the color pipeline on a plane by setting
  236. * it to the first drm_colorop element of the pipeline.
  237. */
  238. void
  239. drm_atomic_set_colorop_for_plane(struct drm_plane_state *plane_state,
  240. struct drm_colorop *colorop)
  241. {
  242. struct drm_plane *plane = plane_state->plane;
  243. if (colorop)
  244. drm_dbg_atomic(plane->dev,
  245. "Set [COLOROP:%d] for [PLANE:%d:%s] state %p\n",
  246. colorop->base.id, plane->base.id, plane->name,
  247. plane_state);
  248. else
  249. drm_dbg_atomic(plane->dev,
  250. "Set [NOCOLOROP] for [PLANE:%d:%s] state %p\n",
  251. plane->base.id, plane->name, plane_state);
  252. plane_state->color_pipeline = colorop;
  253. }
  254. EXPORT_SYMBOL(drm_atomic_set_colorop_for_plane);
  255. /**
  256. * drm_atomic_set_crtc_for_connector - set CRTC for connector
  257. * @conn_state: atomic state object for the connector
  258. * @crtc: CRTC to use for the connector
  259. *
  260. * Changing the assigned CRTC for a connector requires us to grab the lock and
  261. * state for the new CRTC, as needed. This function takes care of all these
  262. * details besides updating the pointer in the state object itself.
  263. *
  264. * Returns:
  265. * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
  266. * then the w/w mutex code has detected a deadlock and the entire atomic
  267. * sequence must be restarted. All other errors are fatal.
  268. */
  269. int
  270. drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
  271. struct drm_crtc *crtc)
  272. {
  273. struct drm_connector *connector = conn_state->connector;
  274. struct drm_crtc_state *crtc_state;
  275. if (conn_state->crtc == crtc)
  276. return 0;
  277. if (conn_state->crtc) {
  278. crtc_state = drm_atomic_get_new_crtc_state(conn_state->state,
  279. conn_state->crtc);
  280. crtc_state->connector_mask &=
  281. ~drm_connector_mask(conn_state->connector);
  282. drm_connector_put(conn_state->connector);
  283. conn_state->crtc = NULL;
  284. }
  285. if (crtc) {
  286. crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
  287. if (IS_ERR(crtc_state))
  288. return PTR_ERR(crtc_state);
  289. crtc_state->connector_mask |=
  290. drm_connector_mask(conn_state->connector);
  291. drm_connector_get(conn_state->connector);
  292. conn_state->crtc = crtc;
  293. drm_dbg_atomic(connector->dev,
  294. "Link [CONNECTOR:%d:%s] state %p to [CRTC:%d:%s]\n",
  295. connector->base.id, connector->name,
  296. conn_state, crtc->base.id, crtc->name);
  297. } else {
  298. drm_dbg_atomic(connector->dev,
  299. "Link [CONNECTOR:%d:%s] state %p to [NOCRTC]\n",
  300. connector->base.id, connector->name,
  301. conn_state);
  302. }
  303. return 0;
  304. }
  305. EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
  306. static void set_out_fence_for_crtc(struct drm_atomic_state *state,
  307. struct drm_crtc *crtc, s32 __user *fence_ptr)
  308. {
  309. state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = fence_ptr;
  310. }
  311. static s32 __user *get_out_fence_for_crtc(struct drm_atomic_state *state,
  312. struct drm_crtc *crtc)
  313. {
  314. s32 __user *fence_ptr;
  315. fence_ptr = state->crtcs[drm_crtc_index(crtc)].out_fence_ptr;
  316. state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = NULL;
  317. return fence_ptr;
  318. }
  319. static int set_out_fence_for_connector(struct drm_atomic_state *state,
  320. struct drm_connector *connector,
  321. s32 __user *fence_ptr)
  322. {
  323. unsigned int index = drm_connector_index(connector);
  324. if (!fence_ptr)
  325. return 0;
  326. if (put_user(-1, fence_ptr))
  327. return -EFAULT;
  328. state->connectors[index].out_fence_ptr = fence_ptr;
  329. return 0;
  330. }
  331. static s32 __user *get_out_fence_for_connector(struct drm_atomic_state *state,
  332. struct drm_connector *connector)
  333. {
  334. unsigned int index = drm_connector_index(connector);
  335. s32 __user *fence_ptr;
  336. fence_ptr = state->connectors[index].out_fence_ptr;
  337. state->connectors[index].out_fence_ptr = NULL;
  338. return fence_ptr;
  339. }
  340. static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
  341. struct drm_crtc_state *state, struct drm_property *property,
  342. uint64_t val)
  343. {
  344. struct drm_device *dev = crtc->dev;
  345. struct drm_mode_config *config = &dev->mode_config;
  346. bool replaced = false;
  347. int ret;
  348. if (property == config->prop_active)
  349. state->active = val;
  350. else if (property == config->prop_mode_id) {
  351. struct drm_property_blob *mode =
  352. drm_property_lookup_blob(dev, val);
  353. ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
  354. drm_property_blob_put(mode);
  355. return ret;
  356. } else if (property == config->prop_vrr_enabled) {
  357. state->vrr_enabled = val;
  358. } else if (property == config->degamma_lut_property) {
  359. const size_t elem_size = sizeof(struct drm_color_lut);
  360. u64 lut_size;
  361. ret = drm_object_immutable_property_get_value(&crtc->base,
  362. config->degamma_lut_size_property,
  363. &lut_size);
  364. if (ret)
  365. return ret;
  366. ret = drm_property_replace_blob_from_id(dev,
  367. &state->degamma_lut,
  368. val,
  369. elem_size * lut_size, -1, elem_size,
  370. &replaced);
  371. state->color_mgmt_changed |= replaced;
  372. return ret;
  373. } else if (property == config->ctm_property) {
  374. ret = drm_property_replace_blob_from_id(dev,
  375. &state->ctm,
  376. val,
  377. -1, sizeof(struct drm_color_ctm), -1,
  378. &replaced);
  379. state->color_mgmt_changed |= replaced;
  380. return ret;
  381. } else if (property == config->gamma_lut_property) {
  382. const size_t elem_size = sizeof(struct drm_color_lut);
  383. u64 lut_size;
  384. ret = drm_object_immutable_property_get_value(&crtc->base,
  385. config->gamma_lut_size_property,
  386. &lut_size);
  387. if (ret)
  388. return ret;
  389. ret = drm_property_replace_blob_from_id(dev,
  390. &state->gamma_lut,
  391. val,
  392. elem_size * lut_size, -1, elem_size,
  393. &replaced);
  394. state->color_mgmt_changed |= replaced;
  395. return ret;
  396. } else if (property == config->prop_out_fence_ptr) {
  397. s32 __user *fence_ptr = u64_to_user_ptr(val);
  398. if (!fence_ptr)
  399. return 0;
  400. if (put_user(-1, fence_ptr))
  401. return -EFAULT;
  402. set_out_fence_for_crtc(state->state, crtc, fence_ptr);
  403. } else if (property == crtc->scaling_filter_property) {
  404. state->scaling_filter = val;
  405. } else if (property == crtc->sharpness_strength_property) {
  406. state->sharpness_strength = val;
  407. } else if (crtc->funcs->atomic_set_property) {
  408. return crtc->funcs->atomic_set_property(crtc, state, property, val);
  409. } else {
  410. drm_dbg_atomic(crtc->dev,
  411. "[CRTC:%d:%s] unknown property [PROP:%d:%s]\n",
  412. crtc->base.id, crtc->name,
  413. property->base.id, property->name);
  414. return -EINVAL;
  415. }
  416. return 0;
  417. }
  418. static int
  419. drm_atomic_crtc_get_property(struct drm_crtc *crtc,
  420. const struct drm_crtc_state *state,
  421. struct drm_property *property, uint64_t *val)
  422. {
  423. struct drm_device *dev = crtc->dev;
  424. struct drm_mode_config *config = &dev->mode_config;
  425. if (property == config->prop_active)
  426. *val = drm_atomic_crtc_effectively_active(state);
  427. else if (property == config->prop_mode_id)
  428. *val = (state->mode_blob) ? state->mode_blob->base.id : 0;
  429. else if (property == config->prop_vrr_enabled)
  430. *val = state->vrr_enabled;
  431. else if (property == config->degamma_lut_property)
  432. *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
  433. else if (property == config->ctm_property)
  434. *val = (state->ctm) ? state->ctm->base.id : 0;
  435. else if (property == config->gamma_lut_property)
  436. *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
  437. else if (property == config->prop_out_fence_ptr)
  438. *val = 0;
  439. else if (property == crtc->scaling_filter_property)
  440. *val = state->scaling_filter;
  441. else if (property == crtc->sharpness_strength_property)
  442. *val = state->sharpness_strength;
  443. else if (crtc->funcs->atomic_get_property)
  444. return crtc->funcs->atomic_get_property(crtc, state, property, val);
  445. else {
  446. drm_dbg_atomic(dev,
  447. "[CRTC:%d:%s] unknown property [PROP:%d:%s]\n",
  448. crtc->base.id, crtc->name,
  449. property->base.id, property->name);
  450. return -EINVAL;
  451. }
  452. return 0;
  453. }
  454. static int drm_atomic_plane_set_property(struct drm_plane *plane,
  455. struct drm_plane_state *state, struct drm_file *file_priv,
  456. struct drm_property *property, uint64_t val)
  457. {
  458. struct drm_device *dev = plane->dev;
  459. struct drm_mode_config *config = &dev->mode_config;
  460. bool replaced = false;
  461. int ret;
  462. if (property == config->prop_fb_id) {
  463. struct drm_framebuffer *fb;
  464. fb = drm_framebuffer_lookup(dev, file_priv, val);
  465. drm_atomic_set_fb_for_plane(state, fb);
  466. if (fb)
  467. drm_framebuffer_put(fb);
  468. } else if (property == config->prop_in_fence_fd) {
  469. if (state->fence)
  470. return -EINVAL;
  471. if (U642I64(val) == -1)
  472. return 0;
  473. state->fence = sync_file_get_fence(val);
  474. if (!state->fence)
  475. return -EINVAL;
  476. } else if (property == config->prop_crtc_id) {
  477. struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val);
  478. if (val && !crtc) {
  479. drm_dbg_atomic(dev,
  480. "[PROP:%d:%s] cannot find CRTC with ID %llu\n",
  481. property->base.id, property->name, val);
  482. return -EACCES;
  483. }
  484. return drm_atomic_set_crtc_for_plane(state, crtc);
  485. } else if (property == config->prop_crtc_x) {
  486. state->crtc_x = U642I64(val);
  487. } else if (property == config->prop_crtc_y) {
  488. state->crtc_y = U642I64(val);
  489. } else if (property == config->prop_crtc_w) {
  490. state->crtc_w = val;
  491. } else if (property == config->prop_crtc_h) {
  492. state->crtc_h = val;
  493. } else if (property == config->prop_src_x) {
  494. state->src_x = val;
  495. } else if (property == config->prop_src_y) {
  496. state->src_y = val;
  497. } else if (property == config->prop_src_w) {
  498. state->src_w = val;
  499. } else if (property == config->prop_src_h) {
  500. state->src_h = val;
  501. } else if (property == plane->alpha_property) {
  502. state->alpha = val;
  503. } else if (property == plane->blend_mode_property) {
  504. state->pixel_blend_mode = val;
  505. } else if (property == plane->rotation_property) {
  506. if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK)) {
  507. drm_dbg_atomic(plane->dev,
  508. "[PLANE:%d:%s] bad rotation bitmask: 0x%llx\n",
  509. plane->base.id, plane->name, val);
  510. return -EINVAL;
  511. }
  512. state->rotation = val;
  513. } else if (property == plane->zpos_property) {
  514. state->zpos = val;
  515. } else if (property == plane->color_encoding_property) {
  516. state->color_encoding = val;
  517. } else if (property == plane->color_range_property) {
  518. state->color_range = val;
  519. } else if (property == plane->color_pipeline_property) {
  520. /* find DRM colorop object */
  521. struct drm_colorop *colorop = NULL;
  522. colorop = drm_colorop_find(dev, file_priv, val);
  523. if (val && !colorop)
  524. return -EACCES;
  525. drm_atomic_set_colorop_for_plane(state, colorop);
  526. } else if (property == config->prop_fb_damage_clips) {
  527. ret = drm_property_replace_blob_from_id(dev,
  528. &state->fb_damage_clips,
  529. val,
  530. -1, -1, sizeof(struct drm_mode_rect),
  531. &replaced);
  532. return ret;
  533. } else if (property == plane->scaling_filter_property) {
  534. state->scaling_filter = val;
  535. } else if (plane->funcs->atomic_set_property) {
  536. return plane->funcs->atomic_set_property(plane, state,
  537. property, val);
  538. } else if (property == plane->hotspot_x_property) {
  539. if (plane->type != DRM_PLANE_TYPE_CURSOR) {
  540. drm_dbg_atomic(plane->dev,
  541. "[PLANE:%d:%s] is not a cursor plane: 0x%llx\n",
  542. plane->base.id, plane->name, val);
  543. return -EINVAL;
  544. }
  545. state->hotspot_x = val;
  546. } else if (property == plane->hotspot_y_property) {
  547. if (plane->type != DRM_PLANE_TYPE_CURSOR) {
  548. drm_dbg_atomic(plane->dev,
  549. "[PLANE:%d:%s] is not a cursor plane: 0x%llx\n",
  550. plane->base.id, plane->name, val);
  551. return -EINVAL;
  552. }
  553. state->hotspot_y = val;
  554. } else {
  555. drm_dbg_atomic(plane->dev,
  556. "[PLANE:%d:%s] unknown property [PROP:%d:%s]\n",
  557. plane->base.id, plane->name,
  558. property->base.id, property->name);
  559. return -EINVAL;
  560. }
  561. return 0;
  562. }
  563. static int
  564. drm_atomic_plane_get_property(struct drm_plane *plane,
  565. const struct drm_plane_state *state,
  566. struct drm_property *property, uint64_t *val)
  567. {
  568. struct drm_device *dev = plane->dev;
  569. struct drm_mode_config *config = &dev->mode_config;
  570. if (property == config->prop_fb_id) {
  571. *val = (state->fb) ? state->fb->base.id : 0;
  572. } else if (property == config->prop_in_fence_fd) {
  573. *val = -1;
  574. } else if (property == config->prop_crtc_id) {
  575. *val = (state->crtc) ? state->crtc->base.id : 0;
  576. } else if (property == config->prop_crtc_x) {
  577. *val = I642U64(state->crtc_x);
  578. } else if (property == config->prop_crtc_y) {
  579. *val = I642U64(state->crtc_y);
  580. } else if (property == config->prop_crtc_w) {
  581. *val = state->crtc_w;
  582. } else if (property == config->prop_crtc_h) {
  583. *val = state->crtc_h;
  584. } else if (property == config->prop_src_x) {
  585. *val = state->src_x;
  586. } else if (property == config->prop_src_y) {
  587. *val = state->src_y;
  588. } else if (property == config->prop_src_w) {
  589. *val = state->src_w;
  590. } else if (property == config->prop_src_h) {
  591. *val = state->src_h;
  592. } else if (property == plane->alpha_property) {
  593. *val = state->alpha;
  594. } else if (property == plane->blend_mode_property) {
  595. *val = state->pixel_blend_mode;
  596. } else if (property == plane->rotation_property) {
  597. *val = state->rotation;
  598. } else if (property == plane->zpos_property) {
  599. *val = state->zpos;
  600. } else if (property == plane->color_encoding_property) {
  601. *val = state->color_encoding;
  602. } else if (property == plane->color_range_property) {
  603. *val = state->color_range;
  604. } else if (property == plane->color_pipeline_property) {
  605. *val = (state->color_pipeline) ? state->color_pipeline->base.id : 0;
  606. } else if (property == config->prop_fb_damage_clips) {
  607. *val = (state->fb_damage_clips) ?
  608. state->fb_damage_clips->base.id : 0;
  609. } else if (property == plane->scaling_filter_property) {
  610. *val = state->scaling_filter;
  611. } else if (plane->funcs->atomic_get_property) {
  612. return plane->funcs->atomic_get_property(plane, state, property, val);
  613. } else if (property == plane->hotspot_x_property) {
  614. *val = state->hotspot_x;
  615. } else if (property == plane->hotspot_y_property) {
  616. *val = state->hotspot_y;
  617. } else {
  618. drm_dbg_atomic(dev,
  619. "[PLANE:%d:%s] unknown property [PROP:%d:%s]\n",
  620. plane->base.id, plane->name,
  621. property->base.id, property->name);
  622. return -EINVAL;
  623. }
  624. return 0;
  625. }
  626. static int drm_atomic_color_set_data_property(struct drm_colorop *colorop,
  627. struct drm_colorop_state *state,
  628. struct drm_property *property,
  629. uint64_t val)
  630. {
  631. ssize_t elem_size = -1;
  632. ssize_t size = -1;
  633. bool replaced = false;
  634. switch (colorop->type) {
  635. case DRM_COLOROP_1D_LUT:
  636. size = colorop->size * sizeof(struct drm_color_lut32);
  637. break;
  638. case DRM_COLOROP_CTM_3X4:
  639. size = sizeof(struct drm_color_ctm_3x4);
  640. break;
  641. case DRM_COLOROP_3D_LUT:
  642. size = colorop->size * colorop->size * colorop->size *
  643. sizeof(struct drm_color_lut32);
  644. break;
  645. default:
  646. /* should never get here */
  647. return -EINVAL;
  648. }
  649. return drm_property_replace_blob_from_id(colorop->dev,
  650. &state->data,
  651. val,
  652. -1, size, elem_size,
  653. &replaced);
  654. }
  655. static int drm_atomic_colorop_set_property(struct drm_colorop *colorop,
  656. struct drm_colorop_state *state,
  657. struct drm_file *file_priv,
  658. struct drm_property *property,
  659. uint64_t val)
  660. {
  661. if (property == colorop->bypass_property) {
  662. state->bypass = val;
  663. } else if (property == colorop->lut1d_interpolation_property) {
  664. colorop->lut1d_interpolation = val;
  665. } else if (property == colorop->curve_1d_type_property) {
  666. state->curve_1d_type = val;
  667. } else if (property == colorop->multiplier_property) {
  668. state->multiplier = val;
  669. } else if (property == colorop->lut3d_interpolation_property) {
  670. colorop->lut3d_interpolation = val;
  671. } else if (property == colorop->data_property) {
  672. return drm_atomic_color_set_data_property(colorop, state,
  673. property, val);
  674. } else {
  675. drm_dbg_atomic(colorop->dev,
  676. "[COLOROP:%d:%d] unknown property [PROP:%d:%s]\n",
  677. colorop->base.id, colorop->type,
  678. property->base.id, property->name);
  679. return -EINVAL;
  680. }
  681. return 0;
  682. }
  683. static int
  684. drm_atomic_colorop_get_property(struct drm_colorop *colorop,
  685. const struct drm_colorop_state *state,
  686. struct drm_property *property, uint64_t *val)
  687. {
  688. if (property == colorop->type_property)
  689. *val = colorop->type;
  690. else if (property == colorop->bypass_property)
  691. *val = state->bypass;
  692. else if (property == colorop->lut1d_interpolation_property)
  693. *val = colorop->lut1d_interpolation;
  694. else if (property == colorop->curve_1d_type_property)
  695. *val = state->curve_1d_type;
  696. else if (property == colorop->multiplier_property)
  697. *val = state->multiplier;
  698. else if (property == colorop->size_property)
  699. *val = colorop->size;
  700. else if (property == colorop->lut3d_interpolation_property)
  701. *val = colorop->lut3d_interpolation;
  702. else if (property == colorop->data_property)
  703. *val = (state->data) ? state->data->base.id : 0;
  704. else
  705. return -EINVAL;
  706. return 0;
  707. }
  708. static int drm_atomic_set_writeback_fb_for_connector(
  709. struct drm_connector_state *conn_state,
  710. struct drm_framebuffer *fb)
  711. {
  712. int ret;
  713. struct drm_connector *conn = conn_state->connector;
  714. ret = drm_writeback_set_fb(conn_state, fb);
  715. if (ret < 0)
  716. return ret;
  717. if (fb)
  718. drm_dbg_atomic(conn->dev,
  719. "Set [FB:%d] for connector state %p\n",
  720. fb->base.id, conn_state);
  721. else
  722. drm_dbg_atomic(conn->dev,
  723. "Set [NOFB] for connector state %p\n",
  724. conn_state);
  725. return 0;
  726. }
  727. static int drm_atomic_connector_set_property(struct drm_connector *connector,
  728. struct drm_connector_state *state, struct drm_file *file_priv,
  729. struct drm_property *property, uint64_t val)
  730. {
  731. struct drm_device *dev = connector->dev;
  732. struct drm_mode_config *config = &dev->mode_config;
  733. bool replaced = false;
  734. int ret;
  735. if (property == config->prop_crtc_id) {
  736. struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val);
  737. if (val && !crtc) {
  738. drm_dbg_atomic(dev,
  739. "[PROP:%d:%s] cannot find CRTC with ID %llu\n",
  740. property->base.id, property->name, val);
  741. return -EACCES;
  742. }
  743. return drm_atomic_set_crtc_for_connector(state, crtc);
  744. } else if (property == config->dpms_property) {
  745. /* setting DPMS property requires special handling, which
  746. * is done in legacy setprop path for us. Disallow (for
  747. * now?) atomic writes to DPMS property:
  748. */
  749. drm_dbg_atomic(dev,
  750. "legacy [PROP:%d:%s] can only be set via legacy uAPI\n",
  751. property->base.id, property->name);
  752. return -EINVAL;
  753. } else if (property == config->tv_select_subconnector_property) {
  754. state->tv.select_subconnector = val;
  755. } else if (property == config->tv_subconnector_property) {
  756. state->tv.subconnector = val;
  757. } else if (property == config->tv_left_margin_property) {
  758. state->tv.margins.left = val;
  759. } else if (property == config->tv_right_margin_property) {
  760. state->tv.margins.right = val;
  761. } else if (property == config->tv_top_margin_property) {
  762. state->tv.margins.top = val;
  763. } else if (property == config->tv_bottom_margin_property) {
  764. state->tv.margins.bottom = val;
  765. } else if (property == config->legacy_tv_mode_property) {
  766. state->tv.legacy_mode = val;
  767. } else if (property == config->tv_mode_property) {
  768. state->tv.mode = val;
  769. } else if (property == config->tv_brightness_property) {
  770. state->tv.brightness = val;
  771. } else if (property == config->tv_contrast_property) {
  772. state->tv.contrast = val;
  773. } else if (property == config->tv_flicker_reduction_property) {
  774. state->tv.flicker_reduction = val;
  775. } else if (property == config->tv_overscan_property) {
  776. state->tv.overscan = val;
  777. } else if (property == config->tv_saturation_property) {
  778. state->tv.saturation = val;
  779. } else if (property == config->tv_hue_property) {
  780. state->tv.hue = val;
  781. } else if (property == config->link_status_property) {
  782. /* Never downgrade from GOOD to BAD on userspace's request here,
  783. * only hw issues can do that.
  784. *
  785. * For an atomic property the userspace doesn't need to be able
  786. * to understand all the properties, but needs to be able to
  787. * restore the state it wants on VT switch. So if the userspace
  788. * tries to change the link_status from GOOD to BAD, driver
  789. * silently rejects it and returns a 0. This prevents userspace
  790. * from accidentally breaking the display when it restores the
  791. * state.
  792. */
  793. if (state->link_status != DRM_LINK_STATUS_GOOD)
  794. state->link_status = val;
  795. } else if (property == config->hdr_output_metadata_property) {
  796. ret = drm_property_replace_blob_from_id(dev,
  797. &state->hdr_output_metadata,
  798. val,
  799. -1, sizeof(struct hdr_output_metadata), -1,
  800. &replaced);
  801. return ret;
  802. } else if (property == config->aspect_ratio_property) {
  803. state->picture_aspect_ratio = val;
  804. } else if (property == config->content_type_property) {
  805. state->content_type = val;
  806. } else if (property == connector->scaling_mode_property) {
  807. state->scaling_mode = val;
  808. } else if (property == config->content_protection_property) {
  809. if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
  810. drm_dbg_kms(dev, "only drivers can set CP Enabled\n");
  811. return -EINVAL;
  812. }
  813. state->content_protection = val;
  814. } else if (property == config->hdcp_content_type_property) {
  815. state->hdcp_content_type = val;
  816. } else if (property == connector->colorspace_property) {
  817. state->colorspace = val;
  818. } else if (property == config->writeback_fb_id_property) {
  819. struct drm_framebuffer *fb;
  820. int ret;
  821. fb = drm_framebuffer_lookup(dev, file_priv, val);
  822. ret = drm_atomic_set_writeback_fb_for_connector(state, fb);
  823. if (fb)
  824. drm_framebuffer_put(fb);
  825. return ret;
  826. } else if (property == config->writeback_out_fence_ptr_property) {
  827. s32 __user *fence_ptr = u64_to_user_ptr(val);
  828. return set_out_fence_for_connector(state->state, connector,
  829. fence_ptr);
  830. } else if (property == connector->max_bpc_property) {
  831. state->max_requested_bpc = val;
  832. } else if (property == connector->privacy_screen_sw_state_property) {
  833. state->privacy_screen_sw_state = val;
  834. } else if (property == connector->broadcast_rgb_property) {
  835. state->hdmi.broadcast_rgb = val;
  836. } else if (connector->funcs->atomic_set_property) {
  837. return connector->funcs->atomic_set_property(connector,
  838. state, property, val);
  839. } else {
  840. drm_dbg_atomic(connector->dev,
  841. "[CONNECTOR:%d:%s] unknown property [PROP:%d:%s]\n",
  842. connector->base.id, connector->name,
  843. property->base.id, property->name);
  844. return -EINVAL;
  845. }
  846. return 0;
  847. }
  848. static int
  849. drm_atomic_connector_get_property(struct drm_connector *connector,
  850. const struct drm_connector_state *state,
  851. struct drm_property *property, uint64_t *val)
  852. {
  853. struct drm_device *dev = connector->dev;
  854. struct drm_mode_config *config = &dev->mode_config;
  855. if (property == config->prop_crtc_id) {
  856. *val = (state->crtc) ? state->crtc->base.id : 0;
  857. } else if (property == config->dpms_property) {
  858. if (state->crtc && state->crtc->state->self_refresh_active)
  859. *val = DRM_MODE_DPMS_ON;
  860. else
  861. *val = connector->dpms;
  862. } else if (property == config->tv_select_subconnector_property) {
  863. *val = state->tv.select_subconnector;
  864. } else if (property == config->tv_subconnector_property) {
  865. *val = state->tv.subconnector;
  866. } else if (property == config->tv_left_margin_property) {
  867. *val = state->tv.margins.left;
  868. } else if (property == config->tv_right_margin_property) {
  869. *val = state->tv.margins.right;
  870. } else if (property == config->tv_top_margin_property) {
  871. *val = state->tv.margins.top;
  872. } else if (property == config->tv_bottom_margin_property) {
  873. *val = state->tv.margins.bottom;
  874. } else if (property == config->legacy_tv_mode_property) {
  875. *val = state->tv.legacy_mode;
  876. } else if (property == config->tv_mode_property) {
  877. *val = state->tv.mode;
  878. } else if (property == config->tv_brightness_property) {
  879. *val = state->tv.brightness;
  880. } else if (property == config->tv_contrast_property) {
  881. *val = state->tv.contrast;
  882. } else if (property == config->tv_flicker_reduction_property) {
  883. *val = state->tv.flicker_reduction;
  884. } else if (property == config->tv_overscan_property) {
  885. *val = state->tv.overscan;
  886. } else if (property == config->tv_saturation_property) {
  887. *val = state->tv.saturation;
  888. } else if (property == config->tv_hue_property) {
  889. *val = state->tv.hue;
  890. } else if (property == config->link_status_property) {
  891. *val = state->link_status;
  892. } else if (property == config->aspect_ratio_property) {
  893. *val = state->picture_aspect_ratio;
  894. } else if (property == config->content_type_property) {
  895. *val = state->content_type;
  896. } else if (property == connector->colorspace_property) {
  897. *val = state->colorspace;
  898. } else if (property == connector->scaling_mode_property) {
  899. *val = state->scaling_mode;
  900. } else if (property == config->hdr_output_metadata_property) {
  901. *val = state->hdr_output_metadata ?
  902. state->hdr_output_metadata->base.id : 0;
  903. } else if (property == config->content_protection_property) {
  904. *val = state->content_protection;
  905. } else if (property == config->hdcp_content_type_property) {
  906. *val = state->hdcp_content_type;
  907. } else if (property == config->writeback_fb_id_property) {
  908. /* Writeback framebuffer is one-shot, write and forget */
  909. *val = 0;
  910. } else if (property == config->writeback_out_fence_ptr_property) {
  911. *val = 0;
  912. } else if (property == connector->max_bpc_property) {
  913. *val = state->max_requested_bpc;
  914. } else if (property == connector->privacy_screen_sw_state_property) {
  915. *val = state->privacy_screen_sw_state;
  916. } else if (property == connector->broadcast_rgb_property) {
  917. *val = state->hdmi.broadcast_rgb;
  918. } else if (connector->funcs->atomic_get_property) {
  919. return connector->funcs->atomic_get_property(connector,
  920. state, property, val);
  921. } else {
  922. drm_dbg_atomic(dev,
  923. "[CONNECTOR:%d:%s] unknown property [PROP:%d:%s]\n",
  924. connector->base.id, connector->name,
  925. property->base.id, property->name);
  926. return -EINVAL;
  927. }
  928. return 0;
  929. }
  930. int drm_atomic_get_property(struct drm_mode_object *obj,
  931. struct drm_property *property, uint64_t *val)
  932. {
  933. struct drm_device *dev = property->dev;
  934. int ret;
  935. switch (obj->type) {
  936. case DRM_MODE_OBJECT_CONNECTOR: {
  937. struct drm_connector *connector = obj_to_connector(obj);
  938. WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
  939. ret = drm_atomic_connector_get_property(connector,
  940. connector->state, property, val);
  941. break;
  942. }
  943. case DRM_MODE_OBJECT_CRTC: {
  944. struct drm_crtc *crtc = obj_to_crtc(obj);
  945. WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
  946. ret = drm_atomic_crtc_get_property(crtc,
  947. crtc->state, property, val);
  948. break;
  949. }
  950. case DRM_MODE_OBJECT_PLANE: {
  951. struct drm_plane *plane = obj_to_plane(obj);
  952. WARN_ON(!drm_modeset_is_locked(&plane->mutex));
  953. ret = drm_atomic_plane_get_property(plane,
  954. plane->state, property, val);
  955. break;
  956. }
  957. case DRM_MODE_OBJECT_COLOROP: {
  958. struct drm_colorop *colorop = obj_to_colorop(obj);
  959. if (colorop->plane)
  960. WARN_ON(!drm_modeset_is_locked(&colorop->plane->mutex));
  961. ret = drm_atomic_colorop_get_property(colorop, colorop->state, property, val);
  962. break;
  963. }
  964. default:
  965. drm_dbg_atomic(dev, "[OBJECT:%d] has no properties\n", obj->id);
  966. ret = -EINVAL;
  967. break;
  968. }
  969. return ret;
  970. }
  971. /*
  972. * The big monster ioctl
  973. */
  974. static struct drm_pending_vblank_event *create_vblank_event(
  975. struct drm_crtc *crtc, uint64_t user_data)
  976. {
  977. struct drm_pending_vblank_event *e = NULL;
  978. e = kzalloc_obj(*e);
  979. if (!e)
  980. return NULL;
  981. e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
  982. e->event.base.length = sizeof(e->event);
  983. e->event.vbl.crtc_id = crtc->base.id;
  984. e->event.vbl.user_data = user_data;
  985. return e;
  986. }
  987. int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
  988. struct drm_connector *connector,
  989. int mode)
  990. {
  991. struct drm_connector *tmp_connector;
  992. struct drm_connector_state *new_conn_state;
  993. struct drm_crtc *crtc;
  994. struct drm_crtc_state *crtc_state;
  995. int i, ret, old_mode = connector->dpms;
  996. bool active = false;
  997. ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
  998. state->acquire_ctx);
  999. if (ret)
  1000. return ret;
  1001. if (mode != DRM_MODE_DPMS_ON)
  1002. mode = DRM_MODE_DPMS_OFF;
  1003. if (connector->dpms == mode)
  1004. goto out;
  1005. connector->dpms = mode;
  1006. crtc = connector->state->crtc;
  1007. if (!crtc)
  1008. goto out;
  1009. ret = drm_atomic_add_affected_connectors(state, crtc);
  1010. if (ret)
  1011. goto out;
  1012. crtc_state = drm_atomic_get_crtc_state(state, crtc);
  1013. if (IS_ERR(crtc_state)) {
  1014. ret = PTR_ERR(crtc_state);
  1015. goto out;
  1016. }
  1017. for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) {
  1018. if (new_conn_state->crtc != crtc)
  1019. continue;
  1020. if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
  1021. active = true;
  1022. break;
  1023. }
  1024. }
  1025. crtc_state->active = active;
  1026. ret = drm_atomic_commit(state);
  1027. out:
  1028. if (ret != 0)
  1029. connector->dpms = old_mode;
  1030. return ret;
  1031. }
  1032. static int drm_atomic_check_prop_changes(int ret, uint64_t old_val, uint64_t prop_value,
  1033. struct drm_property *prop)
  1034. {
  1035. if (ret != 0 || old_val != prop_value) {
  1036. drm_dbg_atomic(prop->dev,
  1037. "[PROP:%d:%s] No prop can be changed during async flip\n",
  1038. prop->base.id, prop->name);
  1039. return -EINVAL;
  1040. }
  1041. return 0;
  1042. }
  1043. int drm_atomic_set_property(struct drm_atomic_state *state,
  1044. struct drm_file *file_priv,
  1045. struct drm_mode_object *obj,
  1046. struct drm_property *prop,
  1047. u64 prop_value,
  1048. bool async_flip)
  1049. {
  1050. struct drm_mode_object *ref;
  1051. u64 old_val;
  1052. int ret;
  1053. if (!drm_property_change_valid_get(prop, prop_value, &ref))
  1054. return -EINVAL;
  1055. switch (obj->type) {
  1056. case DRM_MODE_OBJECT_CONNECTOR: {
  1057. struct drm_connector *connector = obj_to_connector(obj);
  1058. struct drm_connector_state *connector_state;
  1059. connector_state = drm_atomic_get_connector_state(state, connector);
  1060. if (IS_ERR(connector_state)) {
  1061. ret = PTR_ERR(connector_state);
  1062. break;
  1063. }
  1064. if (async_flip) {
  1065. ret = drm_atomic_connector_get_property(connector, connector_state,
  1066. prop, &old_val);
  1067. ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
  1068. break;
  1069. }
  1070. ret = drm_atomic_connector_set_property(connector,
  1071. connector_state, file_priv,
  1072. prop, prop_value);
  1073. break;
  1074. }
  1075. case DRM_MODE_OBJECT_CRTC: {
  1076. struct drm_crtc *crtc = obj_to_crtc(obj);
  1077. struct drm_crtc_state *crtc_state;
  1078. crtc_state = drm_atomic_get_crtc_state(state, crtc);
  1079. if (IS_ERR(crtc_state)) {
  1080. ret = PTR_ERR(crtc_state);
  1081. break;
  1082. }
  1083. if (async_flip) {
  1084. ret = drm_atomic_crtc_get_property(crtc, crtc_state,
  1085. prop, &old_val);
  1086. ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
  1087. break;
  1088. }
  1089. ret = drm_atomic_crtc_set_property(crtc,
  1090. crtc_state, prop, prop_value);
  1091. break;
  1092. }
  1093. case DRM_MODE_OBJECT_PLANE: {
  1094. struct drm_plane *plane = obj_to_plane(obj);
  1095. struct drm_plane_state *plane_state;
  1096. struct drm_mode_config *config = &plane->dev->mode_config;
  1097. const struct drm_plane_helper_funcs *plane_funcs = plane->helper_private;
  1098. plane_state = drm_atomic_get_plane_state(state, plane);
  1099. if (IS_ERR(plane_state)) {
  1100. ret = PTR_ERR(plane_state);
  1101. break;
  1102. }
  1103. if (async_flip) {
  1104. /* no-op changes are always allowed */
  1105. ret = drm_atomic_plane_get_property(plane, plane_state,
  1106. prop, &old_val);
  1107. ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop);
  1108. /* fail everything that isn't no-op or a pure flip */
  1109. if (ret && prop != config->prop_fb_id &&
  1110. prop != config->prop_in_fence_fd &&
  1111. prop != config->prop_fb_damage_clips) {
  1112. break;
  1113. }
  1114. if (ret && plane->type != DRM_PLANE_TYPE_PRIMARY) {
  1115. /* ask the driver if this non-primary plane is supported */
  1116. if (plane_funcs && plane_funcs->atomic_async_check)
  1117. ret = plane_funcs->atomic_async_check(plane, state, true);
  1118. if (ret) {
  1119. drm_dbg_atomic(prop->dev,
  1120. "[PLANE:%d:%s] does not support async flips\n",
  1121. obj->id, plane->name);
  1122. break;
  1123. }
  1124. }
  1125. }
  1126. ret = drm_atomic_plane_set_property(plane,
  1127. plane_state, file_priv,
  1128. prop, prop_value);
  1129. break;
  1130. }
  1131. case DRM_MODE_OBJECT_COLOROP: {
  1132. struct drm_colorop *colorop = obj_to_colorop(obj);
  1133. struct drm_colorop_state *colorop_state;
  1134. colorop_state = drm_atomic_get_colorop_state(state, colorop);
  1135. if (IS_ERR(colorop_state)) {
  1136. ret = PTR_ERR(colorop_state);
  1137. break;
  1138. }
  1139. ret = drm_atomic_colorop_set_property(colorop, colorop_state,
  1140. file_priv, prop, prop_value);
  1141. break;
  1142. }
  1143. default:
  1144. drm_dbg_atomic(prop->dev, "[OBJECT:%d] has no properties\n", obj->id);
  1145. ret = -EINVAL;
  1146. break;
  1147. }
  1148. drm_property_change_valid_put(prop, ref);
  1149. return ret;
  1150. }
  1151. /**
  1152. * DOC: explicit fencing properties
  1153. *
  1154. * Explicit fencing allows userspace to control the buffer synchronization
  1155. * between devices. A Fence or a group of fences are transferred to/from
  1156. * userspace using Sync File fds and there are two DRM properties for that.
  1157. * IN_FENCE_FD on each DRM Plane to send fences to the kernel and
  1158. * OUT_FENCE_PTR on each DRM CRTC to receive fences from the kernel.
  1159. *
  1160. * As a contrast, with implicit fencing the kernel keeps track of any
  1161. * ongoing rendering, and automatically ensures that the atomic update waits
  1162. * for any pending rendering to complete. This is usually tracked in &struct
  1163. * dma_resv which can also contain mandatory kernel fences. Implicit syncing
  1164. * is how Linux traditionally worked (e.g. DRI2/3 on X.org), whereas explicit
  1165. * fencing is what Android wants.
  1166. *
  1167. * "IN_FENCE_FD”:
  1168. * Use this property to pass a fence that DRM should wait on before
  1169. * proceeding with the Atomic Commit request and show the framebuffer for
  1170. * the plane on the screen. The fence can be either a normal fence or a
  1171. * merged one, the sync_file framework will handle both cases and use a
  1172. * fence_array if a merged fence is received. Passing -1 here means no
  1173. * fences to wait on.
  1174. *
  1175. * If the Atomic Commit request has the DRM_MODE_ATOMIC_TEST_ONLY flag
  1176. * it will only check if the Sync File is a valid one.
  1177. *
  1178. * On the driver side the fence is stored on the @fence parameter of
  1179. * &struct drm_plane_state. Drivers which also support implicit fencing
  1180. * should extract the implicit fence using drm_gem_plane_helper_prepare_fb(),
  1181. * to make sure there's consistent behaviour between drivers in precedence
  1182. * of implicit vs. explicit fencing.
  1183. *
  1184. * "OUT_FENCE_PTR”:
  1185. * Use this property to pass a file descriptor pointer to DRM. Once the
  1186. * Atomic Commit request call returns OUT_FENCE_PTR will be filled with
  1187. * the file descriptor number of a Sync File. This Sync File contains the
  1188. * CRTC fence that will be signaled when all framebuffers present on the
  1189. * Atomic Commit * request for that given CRTC are scanned out on the
  1190. * screen.
  1191. *
  1192. * The Atomic Commit request fails if a invalid pointer is passed. If the
  1193. * Atomic Commit request fails for any other reason the out fence fd
  1194. * returned will be -1. On a Atomic Commit with the
  1195. * DRM_MODE_ATOMIC_TEST_ONLY flag the out fence will also be set to -1.
  1196. *
  1197. * Note that out-fences don't have a special interface to drivers and are
  1198. * internally represented by a &struct drm_pending_vblank_event in struct
  1199. * &drm_crtc_state, which is also used by the nonblocking atomic commit
  1200. * helpers and for the DRM event handling for existing userspace.
  1201. */
  1202. struct drm_out_fence_state {
  1203. s32 __user *out_fence_ptr;
  1204. struct sync_file *sync_file;
  1205. int fd;
  1206. };
  1207. static int setup_out_fence(struct drm_out_fence_state *fence_state,
  1208. struct dma_fence *fence)
  1209. {
  1210. fence_state->fd = get_unused_fd_flags(O_CLOEXEC);
  1211. if (fence_state->fd < 0)
  1212. return fence_state->fd;
  1213. if (put_user(fence_state->fd, fence_state->out_fence_ptr))
  1214. return -EFAULT;
  1215. fence_state->sync_file = sync_file_create(fence);
  1216. if (!fence_state->sync_file)
  1217. return -ENOMEM;
  1218. return 0;
  1219. }
  1220. static int prepare_signaling(struct drm_device *dev,
  1221. struct drm_atomic_state *state,
  1222. struct drm_mode_atomic *arg,
  1223. struct drm_file *file_priv,
  1224. struct drm_out_fence_state **fence_state,
  1225. unsigned int *num_fences)
  1226. {
  1227. struct drm_crtc *crtc;
  1228. struct drm_crtc_state *crtc_state;
  1229. struct drm_connector *conn;
  1230. struct drm_connector_state *conn_state;
  1231. int i, c = 0, ret;
  1232. if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
  1233. return 0;
  1234. for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
  1235. s32 __user *fence_ptr;
  1236. fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc);
  1237. if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) {
  1238. struct drm_pending_vblank_event *e;
  1239. e = create_vblank_event(crtc, arg->user_data);
  1240. if (!e)
  1241. return -ENOMEM;
  1242. crtc_state->event = e;
  1243. }
  1244. if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
  1245. struct drm_pending_vblank_event *e = crtc_state->event;
  1246. if (!file_priv)
  1247. continue;
  1248. ret = drm_event_reserve_init(dev, file_priv, &e->base,
  1249. &e->event.base);
  1250. if (ret) {
  1251. kfree(e);
  1252. crtc_state->event = NULL;
  1253. return ret;
  1254. }
  1255. }
  1256. if (fence_ptr) {
  1257. struct dma_fence *fence;
  1258. struct drm_out_fence_state *f;
  1259. f = krealloc(*fence_state, sizeof(**fence_state) *
  1260. (*num_fences + 1), GFP_KERNEL);
  1261. if (!f)
  1262. return -ENOMEM;
  1263. memset(&f[*num_fences], 0, sizeof(*f));
  1264. f[*num_fences].out_fence_ptr = fence_ptr;
  1265. *fence_state = f;
  1266. fence = drm_crtc_create_fence(crtc);
  1267. if (!fence)
  1268. return -ENOMEM;
  1269. ret = setup_out_fence(&f[(*num_fences)++], fence);
  1270. if (ret) {
  1271. dma_fence_put(fence);
  1272. return ret;
  1273. }
  1274. crtc_state->event->base.fence = fence;
  1275. }
  1276. c++;
  1277. }
  1278. for_each_new_connector_in_state(state, conn, conn_state, i) {
  1279. struct drm_writeback_connector *wb_conn;
  1280. struct drm_out_fence_state *f;
  1281. struct dma_fence *fence;
  1282. s32 __user *fence_ptr;
  1283. if (!conn_state->writeback_job)
  1284. continue;
  1285. fence_ptr = get_out_fence_for_connector(state, conn);
  1286. if (!fence_ptr)
  1287. continue;
  1288. f = krealloc(*fence_state, sizeof(**fence_state) *
  1289. (*num_fences + 1), GFP_KERNEL);
  1290. if (!f)
  1291. return -ENOMEM;
  1292. memset(&f[*num_fences], 0, sizeof(*f));
  1293. f[*num_fences].out_fence_ptr = fence_ptr;
  1294. *fence_state = f;
  1295. wb_conn = drm_connector_to_writeback(conn);
  1296. fence = drm_writeback_get_out_fence(wb_conn);
  1297. if (!fence)
  1298. return -ENOMEM;
  1299. ret = setup_out_fence(&f[(*num_fences)++], fence);
  1300. if (ret) {
  1301. dma_fence_put(fence);
  1302. return ret;
  1303. }
  1304. conn_state->writeback_job->out_fence = fence;
  1305. }
  1306. /*
  1307. * Having this flag means user mode pends on event which will never
  1308. * reach due to lack of at least one CRTC for signaling
  1309. */
  1310. if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) {
  1311. drm_dbg_atomic(dev, "need at least one CRTC for DRM_MODE_PAGE_FLIP_EVENT");
  1312. return -EINVAL;
  1313. }
  1314. return 0;
  1315. }
  1316. static void complete_signaling(struct drm_device *dev,
  1317. struct drm_atomic_state *state,
  1318. struct drm_out_fence_state *fence_state,
  1319. unsigned int num_fences,
  1320. bool install_fds)
  1321. {
  1322. struct drm_crtc *crtc;
  1323. struct drm_crtc_state *crtc_state;
  1324. int i;
  1325. if (install_fds) {
  1326. for (i = 0; i < num_fences; i++)
  1327. fd_install(fence_state[i].fd,
  1328. fence_state[i].sync_file->file);
  1329. kfree(fence_state);
  1330. return;
  1331. }
  1332. for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
  1333. struct drm_pending_vblank_event *event = crtc_state->event;
  1334. /*
  1335. * Free the allocated event. drm_atomic_helper_setup_commit
  1336. * can allocate an event too, so only free it if it's ours
  1337. * to prevent a double free in drm_atomic_state_clear.
  1338. */
  1339. if (event && (event->base.fence || event->base.file_priv)) {
  1340. drm_event_cancel_free(dev, &event->base);
  1341. crtc_state->event = NULL;
  1342. }
  1343. }
  1344. if (!fence_state)
  1345. return;
  1346. for (i = 0; i < num_fences; i++) {
  1347. if (fence_state[i].sync_file)
  1348. fput(fence_state[i].sync_file->file);
  1349. if (fence_state[i].fd >= 0)
  1350. put_unused_fd(fence_state[i].fd);
  1351. /* If this fails log error to the user */
  1352. if (fence_state[i].out_fence_ptr &&
  1353. put_user(-1, fence_state[i].out_fence_ptr))
  1354. drm_dbg_atomic(dev, "Couldn't clear out_fence_ptr\n");
  1355. }
  1356. kfree(fence_state);
  1357. }
  1358. static void
  1359. set_async_flip(struct drm_atomic_state *state)
  1360. {
  1361. struct drm_crtc *crtc;
  1362. struct drm_crtc_state *crtc_state;
  1363. int i;
  1364. for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
  1365. crtc_state->async_flip = true;
  1366. }
  1367. }
  1368. int drm_mode_atomic_ioctl(struct drm_device *dev,
  1369. void *data, struct drm_file *file_priv)
  1370. {
  1371. struct drm_mode_atomic *arg = data;
  1372. uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr);
  1373. uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr);
  1374. uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
  1375. uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr);
  1376. unsigned int copied_objs, copied_props;
  1377. struct drm_atomic_state *state;
  1378. struct drm_modeset_acquire_ctx ctx;
  1379. struct drm_out_fence_state *fence_state;
  1380. int ret = 0;
  1381. unsigned int i, j, num_fences;
  1382. bool async_flip = false;
  1383. /* disallow for drivers not supporting atomic: */
  1384. if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
  1385. return -EOPNOTSUPP;
  1386. /* disallow for userspace that has not enabled atomic cap (even
  1387. * though this may be a bit overkill, since legacy userspace
  1388. * wouldn't know how to call this ioctl)
  1389. */
  1390. if (!file_priv->atomic) {
  1391. drm_dbg_atomic(dev,
  1392. "commit failed: atomic cap not enabled\n");
  1393. return -EINVAL;
  1394. }
  1395. if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS) {
  1396. drm_dbg_atomic(dev, "commit failed: invalid flag\n");
  1397. return -EINVAL;
  1398. }
  1399. if (arg->reserved) {
  1400. drm_dbg_atomic(dev, "commit failed: reserved field set\n");
  1401. return -EINVAL;
  1402. }
  1403. if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) {
  1404. if (!dev->mode_config.async_page_flip) {
  1405. drm_dbg_atomic(dev,
  1406. "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported\n");
  1407. return -EINVAL;
  1408. }
  1409. async_flip = true;
  1410. }
  1411. /* can't test and expect an event at the same time. */
  1412. if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
  1413. (arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) {
  1414. drm_dbg_atomic(dev,
  1415. "commit failed: page-flip event requested with test-only commit\n");
  1416. return -EINVAL;
  1417. }
  1418. state = drm_atomic_state_alloc(dev);
  1419. if (!state)
  1420. return -ENOMEM;
  1421. drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
  1422. state->acquire_ctx = &ctx;
  1423. state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
  1424. state->plane_color_pipeline = file_priv->plane_color_pipeline;
  1425. retry:
  1426. copied_objs = 0;
  1427. copied_props = 0;
  1428. fence_state = NULL;
  1429. num_fences = 0;
  1430. for (i = 0; i < arg->count_objs; i++) {
  1431. uint32_t obj_id, count_props;
  1432. struct drm_mode_object *obj;
  1433. if (get_user(obj_id, objs_ptr + copied_objs)) {
  1434. ret = -EFAULT;
  1435. goto out;
  1436. }
  1437. obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY);
  1438. if (!obj) {
  1439. drm_dbg_atomic(dev, "cannot find object ID %d", obj_id);
  1440. ret = -ENOENT;
  1441. goto out;
  1442. }
  1443. if (!obj->properties) {
  1444. drm_dbg_atomic(dev, "[OBJECT:%d] has no properties", obj_id);
  1445. drm_mode_object_put(obj);
  1446. ret = -ENOENT;
  1447. goto out;
  1448. }
  1449. if (get_user(count_props, count_props_ptr + copied_objs)) {
  1450. drm_mode_object_put(obj);
  1451. ret = -EFAULT;
  1452. goto out;
  1453. }
  1454. copied_objs++;
  1455. for (j = 0; j < count_props; j++) {
  1456. uint32_t prop_id;
  1457. uint64_t prop_value;
  1458. struct drm_property *prop;
  1459. if (get_user(prop_id, props_ptr + copied_props)) {
  1460. drm_mode_object_put(obj);
  1461. ret = -EFAULT;
  1462. goto out;
  1463. }
  1464. prop = drm_mode_obj_find_prop_id(obj, prop_id);
  1465. if (!prop) {
  1466. drm_dbg_atomic(dev,
  1467. "[OBJECT:%d] cannot find property ID %d",
  1468. obj_id, prop_id);
  1469. drm_mode_object_put(obj);
  1470. ret = -ENOENT;
  1471. goto out;
  1472. }
  1473. if (copy_from_user(&prop_value,
  1474. prop_values_ptr + copied_props,
  1475. sizeof(prop_value))) {
  1476. drm_mode_object_put(obj);
  1477. ret = -EFAULT;
  1478. goto out;
  1479. }
  1480. ret = drm_atomic_set_property(state, file_priv, obj,
  1481. prop, prop_value, async_flip);
  1482. if (ret) {
  1483. drm_mode_object_put(obj);
  1484. goto out;
  1485. }
  1486. copied_props++;
  1487. }
  1488. drm_mode_object_put(obj);
  1489. }
  1490. ret = prepare_signaling(dev, state, arg, file_priv, &fence_state,
  1491. &num_fences);
  1492. if (ret)
  1493. goto out;
  1494. if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC)
  1495. set_async_flip(state);
  1496. if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
  1497. ret = drm_atomic_check_only(state);
  1498. } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
  1499. ret = drm_atomic_nonblocking_commit(state);
  1500. } else {
  1501. ret = drm_atomic_commit(state);
  1502. }
  1503. out:
  1504. complete_signaling(dev, state, fence_state, num_fences, !ret);
  1505. if (ret == -EDEADLK) {
  1506. drm_atomic_state_clear(state);
  1507. ret = drm_modeset_backoff(&ctx);
  1508. if (!ret)
  1509. goto retry;
  1510. }
  1511. drm_atomic_state_put(state);
  1512. drm_modeset_drop_locks(&ctx);
  1513. drm_modeset_acquire_fini(&ctx);
  1514. return ret;
  1515. }