drm_atomic_state_helper.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. /*
  2. * Copyright (C) 2018 Intel Corp.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. * OTHER DEALINGS IN THE SOFTWARE.
  21. *
  22. * Authors:
  23. * Rob Clark <robdclark@gmail.com>
  24. * Daniel Vetter <daniel.vetter@ffwll.ch>
  25. */
  26. #include <drm/drm_atomic.h>
  27. #include <drm/drm_atomic_state_helper.h>
  28. #include <drm/drm_blend.h>
  29. #include <drm/drm_bridge.h>
  30. #include <drm/drm_connector.h>
  31. #include <drm/drm_crtc.h>
  32. #include <drm/drm_device.h>
  33. #include <drm/drm_framebuffer.h>
  34. #include <drm/drm_plane.h>
  35. #include <drm/drm_print.h>
  36. #include <drm/drm_vblank.h>
  37. #include <drm/drm_writeback.h>
  38. #include <linux/slab.h>
  39. #include <linux/dma-fence.h>
  40. /**
  41. * DOC: atomic state reset and initialization
  42. *
  43. * Both the drm core and the atomic helpers assume that there is always the full
  44. * and correct atomic software state for all connectors, CRTCs and planes
  45. * available. Which is a bit a problem on driver load and also after system
  46. * suspend. One way to solve this is to have a hardware state read-out
  47. * infrastructure which reconstructs the full software state (e.g. the i915
  48. * driver).
  49. *
  50. * The simpler solution is to just reset the software state to everything off,
  51. * which is easiest to do by calling drm_mode_config_reset(). To facilitate this
  52. * the atomic helpers provide default reset implementations for all hooks.
  53. *
  54. * On the upside the precise state tracking of atomic simplifies system suspend
  55. * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe
  56. * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume().
  57. * For other drivers the building blocks are split out, see the documentation
  58. * for these functions.
  59. */
  60. /**
  61. * __drm_atomic_helper_crtc_state_reset - reset the CRTC state
  62. * @crtc_state: atomic CRTC state, must not be NULL
  63. * @crtc: CRTC object, must not be NULL
  64. *
  65. * Initializes the newly allocated @crtc_state with default
  66. * values. This is useful for drivers that subclass the CRTC state.
  67. */
  68. void
  69. __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
  70. struct drm_crtc *crtc)
  71. {
  72. crtc_state->crtc = crtc;
  73. }
  74. EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
  75. /**
  76. * __drm_atomic_helper_crtc_reset - reset state on CRTC
  77. * @crtc: drm CRTC
  78. * @crtc_state: CRTC state to assign
  79. *
  80. * Initializes the newly allocated @crtc_state and assigns it to
  81. * the &drm_crtc->state pointer of @crtc, usually required when
  82. * initializing the drivers or when called from the &drm_crtc_funcs.reset
  83. * hook.
  84. *
  85. * This is useful for drivers that subclass the CRTC state.
  86. */
  87. void
  88. __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
  89. struct drm_crtc_state *crtc_state)
  90. {
  91. if (crtc_state)
  92. __drm_atomic_helper_crtc_state_reset(crtc_state, crtc);
  93. if (drm_dev_has_vblank(crtc->dev))
  94. drm_crtc_vblank_reset(crtc);
  95. crtc->state = crtc_state;
  96. }
  97. EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
  98. /**
  99. * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
  100. * @crtc: drm CRTC
  101. *
  102. * Resets the atomic state for @crtc by freeing the state pointer (which might
  103. * be NULL, e.g. at driver load time) and allocating a new empty state object.
  104. */
  105. void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
  106. {
  107. struct drm_crtc_state *crtc_state =
  108. kzalloc(sizeof(*crtc->state), GFP_KERNEL);
  109. if (crtc->state)
  110. crtc->funcs->atomic_destroy_state(crtc, crtc->state);
  111. __drm_atomic_helper_crtc_reset(crtc, crtc_state);
  112. }
  113. EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
  114. /**
  115. * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
  116. * @crtc: CRTC object
  117. * @state: atomic CRTC state
  118. *
  119. * Copies atomic state from a CRTC's current state and resets inferred values.
  120. * This is useful for drivers that subclass the CRTC state.
  121. */
  122. void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
  123. struct drm_crtc_state *state)
  124. {
  125. memcpy(state, crtc->state, sizeof(*state));
  126. if (state->mode_blob)
  127. drm_property_blob_get(state->mode_blob);
  128. if (state->degamma_lut)
  129. drm_property_blob_get(state->degamma_lut);
  130. if (state->ctm)
  131. drm_property_blob_get(state->ctm);
  132. if (state->gamma_lut)
  133. drm_property_blob_get(state->gamma_lut);
  134. state->mode_changed = false;
  135. state->active_changed = false;
  136. state->planes_changed = false;
  137. state->connectors_changed = false;
  138. state->color_mgmt_changed = false;
  139. state->zpos_changed = false;
  140. state->commit = NULL;
  141. state->event = NULL;
  142. state->async_flip = false;
  143. /* Self refresh should be canceled when a new update is available */
  144. state->active = drm_atomic_crtc_effectively_active(state);
  145. state->self_refresh_active = false;
  146. }
  147. EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
  148. /**
  149. * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
  150. * @crtc: drm CRTC
  151. *
  152. * Default CRTC state duplicate hook for drivers which don't have their own
  153. * subclassed CRTC state structure.
  154. */
  155. struct drm_crtc_state *
  156. drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
  157. {
  158. struct drm_crtc_state *state;
  159. if (WARN_ON(!crtc->state))
  160. return NULL;
  161. state = kmalloc(sizeof(*state), GFP_KERNEL);
  162. if (state)
  163. __drm_atomic_helper_crtc_duplicate_state(crtc, state);
  164. return state;
  165. }
  166. EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
  167. /**
  168. * __drm_atomic_helper_crtc_destroy_state - release CRTC state
  169. * @state: CRTC state object to release
  170. *
  171. * Releases all resources stored in the CRTC state without actually freeing
  172. * the memory of the CRTC state. This is useful for drivers that subclass the
  173. * CRTC state.
  174. */
  175. void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
  176. {
  177. if (state->commit) {
  178. /*
  179. * In the event that a non-blocking commit returns
  180. * -ERESTARTSYS before the commit_tail work is queued, we will
  181. * have an extra reference to the commit object. Release it, if
  182. * the event has not been consumed by the worker.
  183. *
  184. * state->event may be freed, so we can't directly look at
  185. * state->event->base.completion.
  186. */
  187. if (state->event && state->commit->abort_completion)
  188. drm_crtc_commit_put(state->commit);
  189. kfree(state->commit->event);
  190. state->commit->event = NULL;
  191. drm_crtc_commit_put(state->commit);
  192. }
  193. drm_property_blob_put(state->mode_blob);
  194. drm_property_blob_put(state->degamma_lut);
  195. drm_property_blob_put(state->ctm);
  196. drm_property_blob_put(state->gamma_lut);
  197. }
  198. EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
  199. /**
  200. * drm_atomic_helper_crtc_destroy_state - default state destroy hook
  201. * @crtc: drm CRTC
  202. * @state: CRTC state object to release
  203. *
  204. * Default CRTC state destroy hook for drivers which don't have their own
  205. * subclassed CRTC state structure.
  206. */
  207. void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
  208. struct drm_crtc_state *state)
  209. {
  210. __drm_atomic_helper_crtc_destroy_state(state);
  211. kfree(state);
  212. }
  213. EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
  214. /**
  215. * __drm_atomic_helper_plane_state_reset - resets plane state to default values
  216. * @plane_state: atomic plane state, must not be NULL
  217. * @plane: plane object, must not be NULL
  218. *
  219. * Initializes the newly allocated @plane_state with default
  220. * values. This is useful for drivers that subclass the CRTC state.
  221. */
  222. void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
  223. struct drm_plane *plane)
  224. {
  225. u64 val;
  226. plane_state->plane = plane;
  227. plane_state->rotation = DRM_MODE_ROTATE_0;
  228. plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
  229. plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
  230. if (plane->color_encoding_property) {
  231. if (!drm_object_property_get_default_value(&plane->base,
  232. plane->color_encoding_property,
  233. &val))
  234. plane_state->color_encoding = val;
  235. }
  236. if (plane->color_range_property) {
  237. if (!drm_object_property_get_default_value(&plane->base,
  238. plane->color_range_property,
  239. &val))
  240. plane_state->color_range = val;
  241. }
  242. if (plane->zpos_property) {
  243. if (!drm_object_property_get_default_value(&plane->base,
  244. plane->zpos_property,
  245. &val)) {
  246. plane_state->zpos = val;
  247. plane_state->normalized_zpos = val;
  248. }
  249. }
  250. if (plane->hotspot_x_property) {
  251. if (!drm_object_property_get_default_value(&plane->base,
  252. plane->hotspot_x_property,
  253. &val))
  254. plane_state->hotspot_x = val;
  255. }
  256. if (plane->hotspot_y_property) {
  257. if (!drm_object_property_get_default_value(&plane->base,
  258. plane->hotspot_y_property,
  259. &val))
  260. plane_state->hotspot_y = val;
  261. }
  262. }
  263. EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
  264. /**
  265. * __drm_atomic_helper_plane_reset - reset state on plane
  266. * @plane: drm plane
  267. * @plane_state: plane state to assign
  268. *
  269. * Initializes the newly allocated @plane_state and assigns it to
  270. * the &drm_crtc->state pointer of @plane, usually required when
  271. * initializing the drivers or when called from the &drm_plane_funcs.reset
  272. * hook.
  273. *
  274. * This is useful for drivers that subclass the plane state.
  275. */
  276. void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
  277. struct drm_plane_state *plane_state)
  278. {
  279. if (plane_state)
  280. __drm_atomic_helper_plane_state_reset(plane_state, plane);
  281. plane->state = plane_state;
  282. }
  283. EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
  284. /**
  285. * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes
  286. * @plane: drm plane
  287. *
  288. * Resets the atomic state for @plane by freeing the state pointer (which might
  289. * be NULL, e.g. at driver load time) and allocating a new empty state object.
  290. */
  291. void drm_atomic_helper_plane_reset(struct drm_plane *plane)
  292. {
  293. if (plane->state)
  294. __drm_atomic_helper_plane_destroy_state(plane->state);
  295. kfree(plane->state);
  296. plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
  297. if (plane->state)
  298. __drm_atomic_helper_plane_reset(plane, plane->state);
  299. }
  300. EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
  301. /**
  302. * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
  303. * @plane: plane object
  304. * @state: atomic plane state
  305. *
  306. * Copies atomic state from a plane's current state. This is useful for
  307. * drivers that subclass the plane state.
  308. */
  309. void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
  310. struct drm_plane_state *state)
  311. {
  312. memcpy(state, plane->state, sizeof(*state));
  313. if (state->fb)
  314. drm_framebuffer_get(state->fb);
  315. state->fence = NULL;
  316. state->commit = NULL;
  317. state->fb_damage_clips = NULL;
  318. state->color_mgmt_changed = false;
  319. }
  320. EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
  321. /**
  322. * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
  323. * @plane: drm plane
  324. *
  325. * Default plane state duplicate hook for drivers which don't have their own
  326. * subclassed plane state structure.
  327. */
  328. struct drm_plane_state *
  329. drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
  330. {
  331. struct drm_plane_state *state;
  332. if (WARN_ON(!plane->state))
  333. return NULL;
  334. state = kmalloc(sizeof(*state), GFP_KERNEL);
  335. if (state)
  336. __drm_atomic_helper_plane_duplicate_state(plane, state);
  337. return state;
  338. }
  339. EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
  340. /**
  341. * __drm_atomic_helper_plane_destroy_state - release plane state
  342. * @state: plane state object to release
  343. *
  344. * Releases all resources stored in the plane state without actually freeing
  345. * the memory of the plane state. This is useful for drivers that subclass the
  346. * plane state.
  347. */
  348. void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
  349. {
  350. if (state->fb)
  351. drm_framebuffer_put(state->fb);
  352. if (state->fence)
  353. dma_fence_put(state->fence);
  354. if (state->commit)
  355. drm_crtc_commit_put(state->commit);
  356. drm_property_blob_put(state->fb_damage_clips);
  357. }
  358. EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
  359. /**
  360. * drm_atomic_helper_plane_destroy_state - default state destroy hook
  361. * @plane: drm plane
  362. * @state: plane state object to release
  363. *
  364. * Default plane state destroy hook for drivers which don't have their own
  365. * subclassed plane state structure.
  366. */
  367. void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
  368. struct drm_plane_state *state)
  369. {
  370. __drm_atomic_helper_plane_destroy_state(state);
  371. kfree(state);
  372. }
  373. EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
  374. /**
  375. * __drm_atomic_helper_connector_state_reset - reset the connector state
  376. * @conn_state: atomic connector state, must not be NULL
  377. * @connector: connectotr object, must not be NULL
  378. *
  379. * Initializes the newly allocated @conn_state with default
  380. * values. This is useful for drivers that subclass the connector state.
  381. */
  382. void
  383. __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state,
  384. struct drm_connector *connector)
  385. {
  386. conn_state->connector = connector;
  387. }
  388. EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset);
  389. /**
  390. * __drm_atomic_helper_connector_reset - reset state on connector
  391. * @connector: drm connector
  392. * @conn_state: connector state to assign
  393. *
  394. * Initializes the newly allocated @conn_state and assigns it to
  395. * the &drm_connector->state pointer of @connector, usually required when
  396. * initializing the drivers or when called from the &drm_connector_funcs.reset
  397. * hook.
  398. *
  399. * This is useful for drivers that subclass the connector state.
  400. */
  401. void
  402. __drm_atomic_helper_connector_reset(struct drm_connector *connector,
  403. struct drm_connector_state *conn_state)
  404. {
  405. if (conn_state)
  406. __drm_atomic_helper_connector_state_reset(conn_state, connector);
  407. connector->state = conn_state;
  408. }
  409. EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
  410. /**
  411. * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors
  412. * @connector: drm connector
  413. *
  414. * Resets the atomic state for @connector by freeing the state pointer (which
  415. * might be NULL, e.g. at driver load time) and allocating a new empty state
  416. * object.
  417. */
  418. void drm_atomic_helper_connector_reset(struct drm_connector *connector)
  419. {
  420. struct drm_connector_state *conn_state =
  421. kzalloc(sizeof(*conn_state), GFP_KERNEL);
  422. if (connector->state)
  423. __drm_atomic_helper_connector_destroy_state(connector->state);
  424. kfree(connector->state);
  425. __drm_atomic_helper_connector_reset(connector, conn_state);
  426. }
  427. EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
  428. /**
  429. * drm_atomic_helper_connector_tv_margins_reset - Resets TV connector properties
  430. * @connector: DRM connector
  431. *
  432. * Resets the TV-related properties attached to a connector.
  433. */
  434. void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector)
  435. {
  436. struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
  437. struct drm_connector_state *state = connector->state;
  438. state->tv.margins.left = cmdline->tv_margins.left;
  439. state->tv.margins.right = cmdline->tv_margins.right;
  440. state->tv.margins.top = cmdline->tv_margins.top;
  441. state->tv.margins.bottom = cmdline->tv_margins.bottom;
  442. }
  443. EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
  444. /**
  445. * drm_atomic_helper_connector_tv_reset - Resets Analog TV connector properties
  446. * @connector: DRM connector
  447. *
  448. * Resets the analog TV properties attached to a connector
  449. */
  450. void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
  451. {
  452. struct drm_device *dev = connector->dev;
  453. struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
  454. struct drm_connector_state *state = connector->state;
  455. struct drm_property *prop;
  456. uint64_t val;
  457. prop = dev->mode_config.tv_mode_property;
  458. if (prop)
  459. if (!drm_object_property_get_default_value(&connector->base,
  460. prop, &val))
  461. state->tv.mode = val;
  462. if (cmdline->tv_mode_specified)
  463. state->tv.mode = cmdline->tv_mode;
  464. prop = dev->mode_config.tv_select_subconnector_property;
  465. if (prop)
  466. if (!drm_object_property_get_default_value(&connector->base,
  467. prop, &val))
  468. state->tv.select_subconnector = val;
  469. prop = dev->mode_config.tv_subconnector_property;
  470. if (prop)
  471. if (!drm_object_property_get_default_value(&connector->base,
  472. prop, &val))
  473. state->tv.subconnector = val;
  474. prop = dev->mode_config.tv_brightness_property;
  475. if (prop)
  476. if (!drm_object_property_get_default_value(&connector->base,
  477. prop, &val))
  478. state->tv.brightness = val;
  479. prop = dev->mode_config.tv_contrast_property;
  480. if (prop)
  481. if (!drm_object_property_get_default_value(&connector->base,
  482. prop, &val))
  483. state->tv.contrast = val;
  484. prop = dev->mode_config.tv_flicker_reduction_property;
  485. if (prop)
  486. if (!drm_object_property_get_default_value(&connector->base,
  487. prop, &val))
  488. state->tv.flicker_reduction = val;
  489. prop = dev->mode_config.tv_overscan_property;
  490. if (prop)
  491. if (!drm_object_property_get_default_value(&connector->base,
  492. prop, &val))
  493. state->tv.overscan = val;
  494. prop = dev->mode_config.tv_saturation_property;
  495. if (prop)
  496. if (!drm_object_property_get_default_value(&connector->base,
  497. prop, &val))
  498. state->tv.saturation = val;
  499. prop = dev->mode_config.tv_hue_property;
  500. if (prop)
  501. if (!drm_object_property_get_default_value(&connector->base,
  502. prop, &val))
  503. state->tv.hue = val;
  504. drm_atomic_helper_connector_tv_margins_reset(connector);
  505. }
  506. EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
  507. /**
  508. * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
  509. * @connector: DRM Connector
  510. * @state: the DRM State object
  511. *
  512. * Checks the state object to see if the requested state is valid for an
  513. * analog TV connector.
  514. *
  515. * Return:
  516. * %0 for success, a negative error code on error.
  517. */
  518. int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
  519. struct drm_atomic_state *state)
  520. {
  521. struct drm_connector_state *old_conn_state =
  522. drm_atomic_get_old_connector_state(state, connector);
  523. struct drm_connector_state *new_conn_state =
  524. drm_atomic_get_new_connector_state(state, connector);
  525. struct drm_crtc_state *crtc_state;
  526. struct drm_crtc *crtc;
  527. crtc = new_conn_state->crtc;
  528. if (!crtc)
  529. return 0;
  530. crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
  531. if (!crtc_state)
  532. return -EINVAL;
  533. if (old_conn_state->tv.mode != new_conn_state->tv.mode)
  534. crtc_state->mode_changed = true;
  535. if (old_conn_state->tv.margins.left != new_conn_state->tv.margins.left ||
  536. old_conn_state->tv.margins.right != new_conn_state->tv.margins.right ||
  537. old_conn_state->tv.margins.top != new_conn_state->tv.margins.top ||
  538. old_conn_state->tv.margins.bottom != new_conn_state->tv.margins.bottom ||
  539. old_conn_state->tv.mode != new_conn_state->tv.mode ||
  540. old_conn_state->tv.brightness != new_conn_state->tv.brightness ||
  541. old_conn_state->tv.contrast != new_conn_state->tv.contrast ||
  542. old_conn_state->tv.flicker_reduction != new_conn_state->tv.flicker_reduction ||
  543. old_conn_state->tv.overscan != new_conn_state->tv.overscan ||
  544. old_conn_state->tv.saturation != new_conn_state->tv.saturation ||
  545. old_conn_state->tv.hue != new_conn_state->tv.hue)
  546. crtc_state->connectors_changed = true;
  547. return 0;
  548. }
  549. EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
  550. /**
  551. * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
  552. * @connector: connector object
  553. * @state: atomic connector state
  554. *
  555. * Copies atomic state from a connector's current state. This is useful for
  556. * drivers that subclass the connector state.
  557. */
  558. void
  559. __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
  560. struct drm_connector_state *state)
  561. {
  562. memcpy(state, connector->state, sizeof(*state));
  563. if (state->crtc)
  564. drm_connector_get(connector);
  565. state->commit = NULL;
  566. if (state->hdr_output_metadata)
  567. drm_property_blob_get(state->hdr_output_metadata);
  568. /* Don't copy over a writeback job, they are used only once */
  569. state->writeback_job = NULL;
  570. }
  571. EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
  572. /**
  573. * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
  574. * @connector: drm connector
  575. *
  576. * Default connector state duplicate hook for drivers which don't have their own
  577. * subclassed connector state structure.
  578. */
  579. struct drm_connector_state *
  580. drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
  581. {
  582. struct drm_connector_state *state;
  583. if (WARN_ON(!connector->state))
  584. return NULL;
  585. state = kmalloc(sizeof(*state), GFP_KERNEL);
  586. if (state)
  587. __drm_atomic_helper_connector_duplicate_state(connector, state);
  588. return state;
  589. }
  590. EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
  591. /**
  592. * __drm_atomic_helper_connector_destroy_state - release connector state
  593. * @state: connector state object to release
  594. *
  595. * Releases all resources stored in the connector state without actually
  596. * freeing the memory of the connector state. This is useful for drivers that
  597. * subclass the connector state.
  598. */
  599. void
  600. __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
  601. {
  602. if (state->crtc)
  603. drm_connector_put(state->connector);
  604. if (state->commit)
  605. drm_crtc_commit_put(state->commit);
  606. if (state->writeback_job)
  607. drm_writeback_cleanup_job(state->writeback_job);
  608. drm_property_blob_put(state->hdr_output_metadata);
  609. }
  610. EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
  611. /**
  612. * drm_atomic_helper_connector_destroy_state - default state destroy hook
  613. * @connector: drm connector
  614. * @state: connector state object to release
  615. *
  616. * Default connector state destroy hook for drivers which don't have their own
  617. * subclassed connector state structure.
  618. */
  619. void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
  620. struct drm_connector_state *state)
  621. {
  622. __drm_atomic_helper_connector_destroy_state(state);
  623. kfree(state);
  624. }
  625. EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
  626. /**
  627. * __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state
  628. * @obj: CRTC object
  629. * @state: new private object state
  630. *
  631. * Copies atomic state from a private objects's current state and resets inferred values.
  632. * This is useful for drivers that subclass the private state.
  633. */
  634. void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
  635. struct drm_private_state *state)
  636. {
  637. memcpy(state, obj->state, sizeof(*state));
  638. }
  639. EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
  640. /**
  641. * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state
  642. * @bridge: bridge object
  643. * @state: atomic bridge state
  644. *
  645. * Copies atomic state from a bridge's current state and resets inferred values.
  646. * This is useful for drivers that subclass the bridge state.
  647. */
  648. void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
  649. struct drm_bridge_state *state)
  650. {
  651. __drm_atomic_helper_private_obj_duplicate_state(&bridge->base,
  652. &state->base);
  653. state->bridge = bridge;
  654. }
  655. EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state);
  656. /**
  657. * drm_atomic_helper_bridge_duplicate_state() - Duplicate a bridge state object
  658. * @bridge: bridge object
  659. *
  660. * Allocates a new bridge state and initializes it with the current bridge
  661. * state values. This helper is meant to be used as a bridge
  662. * &drm_bridge_funcs.atomic_duplicate_state hook for bridges that don't
  663. * subclass the bridge state.
  664. */
  665. struct drm_bridge_state *
  666. drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)
  667. {
  668. struct drm_bridge_state *new;
  669. if (WARN_ON(!bridge->base.state))
  670. return NULL;
  671. new = kzalloc(sizeof(*new), GFP_KERNEL);
  672. if (new)
  673. __drm_atomic_helper_bridge_duplicate_state(bridge, new);
  674. return new;
  675. }
  676. EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
  677. /**
  678. * drm_atomic_helper_bridge_destroy_state() - Destroy a bridge state object
  679. * @bridge: the bridge this state refers to
  680. * @state: bridge state to destroy
  681. *
  682. * Destroys a bridge state previously created by
  683. * &drm_atomic_helper_bridge_reset() or
  684. * &drm_atomic_helper_bridge_duplicate_state(). This helper is meant to be
  685. * used as a bridge &drm_bridge_funcs.atomic_destroy_state hook for bridges
  686. * that don't subclass the bridge state.
  687. */
  688. void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
  689. struct drm_bridge_state *state)
  690. {
  691. kfree(state);
  692. }
  693. EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
  694. /**
  695. * __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its
  696. * default
  697. * @bridge: the bridge this state refers to
  698. * @state: bridge state to initialize
  699. *
  700. * Initializes the bridge state to default values. This is meant to be called
  701. * by the bridge &drm_bridge_funcs.atomic_reset hook for bridges that subclass
  702. * the bridge state.
  703. */
  704. void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
  705. struct drm_bridge_state *state)
  706. {
  707. memset(state, 0, sizeof(*state));
  708. state->bridge = bridge;
  709. }
  710. EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset);
  711. /**
  712. * drm_atomic_helper_bridge_reset() - Allocate and initialize a bridge state
  713. * to its default
  714. * @bridge: the bridge this state refers to
  715. *
  716. * Allocates the bridge state and initializes it to default values. This helper
  717. * is meant to be used as a bridge &drm_bridge_funcs.atomic_reset hook for
  718. * bridges that don't subclass the bridge state.
  719. */
  720. struct drm_bridge_state *
  721. drm_atomic_helper_bridge_reset(struct drm_bridge *bridge)
  722. {
  723. struct drm_bridge_state *bridge_state;
  724. bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL);
  725. if (!bridge_state)
  726. return ERR_PTR(-ENOMEM);
  727. __drm_atomic_helper_bridge_reset(bridge, bridge_state);
  728. return bridge_state;
  729. }
  730. EXPORT_SYMBOL(drm_atomic_helper_bridge_reset);