aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-05-17 22:57:06 -0400
committerDave Airlie <airlied@redhat.com>2017-05-17 22:57:06 -0400
commite98c58e55f68f8785aebfab1f8c9a03d8de0afe1 (patch)
tree8357e8fda6efb0867ac39fc6b9211a579721d00a /drivers/gpu/drm/drm_atomic.c
parent2ea659a9ef488125eb46da6eb571de5eae5c43f6 (diff)
parent9cf8f5802f39d9991158b29033c852bccfc3a4d4 (diff)
Merge tag 'drm-misc-next-2017-05-16' of git://anongit.freedesktop.org/git/drm-misc into drm-next
UAPI Changes: - Return -ENODEV instead of -ENXIO when creating cma fb w/o valid gem (Daniel) - Add aspect ratio and custom scaling propertis to connector state (Maarten) Cross-subsystem Changes: - None Core Changes: - Add Laurent as bridge reviewer and Andrzej as bridge maintainer (Archit) - Maintain new STM driver through -misc (Yannick) - Misc doc improvements (as is tradition) (Daniel) - Add driver-private objects to atomic state (Dhinakaran) - Deprecate preclose hook in modern drivers (use postclose) (Daniel) - Add hwmode to vblank struct. This fixes mode access in irq context and reduced a bunch of boilerplate (Daniel) Driver Changes: - vc4: Add out-fence support to vc4 V3D rendering (Eric) - stm: Add stm32f429 display hw and am-480272h3tmqw-t01h panel support (Yannick) - vc4: Remove 256MB cma limit from vc4 (Eric) - dw-hdmi: Disable audio when inactive, instead of always enabled (Romain) - zte: Add support for VGA to the ZTE driver (Shawn) - i915: Track DP MST bandwidth and check it in atomic_check (Dhinakaran) - vgem: Enable gem dmabuf import iface to facilitate ion testing (Laura) - vc4: Add support for Cygnus (new dt compat string + couple bug fixes) (Eric) - pl111: Add driver for pl111 CLCD display controller (Eric/Tom) - vgem: Subclass drm_device instead of standalone platform device (Chris) Cc: Archit Taneja <architt@codeaurora.org> Cc: Eric Anholt <eric@anholt.net> Cc: Yannick Fertre <yannick.fertre@st.com> Cc: Romain Perier <romain.perier@collabora.com> Cc: Navare, Manasi D <manasi.d.navare@intel.com> Cc: Shawn Guo <shawn.guo@linaro.org> Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Cc: Laura Abbott <labbott@redhat.com> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Tom Cooksey <tom.cooksey@arm.com> Cc: Daniel Vetter <daniel.vetter@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> * tag 'drm-misc-next-2017-05-16' of git://anongit.freedesktop.org/git/drm-misc: (72 commits) drm: add missing declaration to drm_blend.h drm/dp: Wait up all outstanding tx waiters drm/dp: Read the tx msg state once after checking for an event drm/prime: Forward declare struct device drm/vblank: Lock down vblank->hwmode more drm/vblank: drop the mode argument from drm_calc_vbltimestamp_from_scanoutpos drm/vblank: Add FIXME comments about moving the vblank ts hooks drm/vblank: Switch to bool in_vblank_irq in get_vblank_timestamp drm/vblank: Switch drm_driver->get_vblank_timestamp to return a bool drm/vgem: Convert to a struct drm_device subclass gpu: drm: gma500: remove dead code drm/sti: Adjust two checks for null pointers in sti_hqvdp_probe() drm/sti: Fix typos in a comment line drm/sti: Fix a typo in a comment line drm/sti: Replace 17 seq_puts() calls by seq_putc() drm/sti: Reduce function calls for sequence output at five places drm/sti: use seq_puts to display a string drm: Nerf the preclose callback for modern drivers drm/exynos: Merge pre/postclose hooks drm/tegra: switch to postclose ...
Diffstat (limited to 'drivers/gpu/drm/drm_atomic.c')
-rw-r--r--drivers/gpu/drm/drm_atomic.c87
1 files changed, 80 insertions, 7 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index f32506a7c1d6..cdec19a86af3 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -57,6 +57,7 @@ void drm_atomic_state_default_release(struct drm_atomic_state *state)
57 kfree(state->connectors); 57 kfree(state->connectors);
58 kfree(state->crtcs); 58 kfree(state->crtcs);
59 kfree(state->planes); 59 kfree(state->planes);
60 kfree(state->private_objs);
60} 61}
61EXPORT_SYMBOL(drm_atomic_state_default_release); 62EXPORT_SYMBOL(drm_atomic_state_default_release);
62 63
@@ -184,6 +185,17 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
184 state->planes[i].ptr = NULL; 185 state->planes[i].ptr = NULL;
185 state->planes[i].state = NULL; 186 state->planes[i].state = NULL;
186 } 187 }
188
189 for (i = 0; i < state->num_private_objs; i++) {
190 void *obj_state = state->private_objs[i].obj_state;
191
192 state->private_objs[i].funcs->destroy_state(obj_state);
193 state->private_objs[i].obj = NULL;
194 state->private_objs[i].obj_state = NULL;
195 state->private_objs[i].funcs = NULL;
196 }
197 state->num_private_objs = 0;
198
187} 199}
188EXPORT_SYMBOL(drm_atomic_state_default_clear); 200EXPORT_SYMBOL(drm_atomic_state_default_clear);
189 201
@@ -425,7 +437,7 @@ drm_atomic_replace_property_blob(struct drm_property_blob **blob,
425} 437}
426 438
427static int 439static int
428drm_atomic_replace_property_blob_from_id(struct drm_crtc *crtc, 440drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
429 struct drm_property_blob **blob, 441 struct drm_property_blob **blob,
430 uint64_t blob_id, 442 uint64_t blob_id,
431 ssize_t expected_size, 443 ssize_t expected_size,
@@ -434,7 +446,7 @@ drm_atomic_replace_property_blob_from_id(struct drm_crtc *crtc,
434 struct drm_property_blob *new_blob = NULL; 446 struct drm_property_blob *new_blob = NULL;
435 447
436 if (blob_id != 0) { 448 if (blob_id != 0) {
437 new_blob = drm_property_lookup_blob(crtc->dev, blob_id); 449 new_blob = drm_property_lookup_blob(dev, blob_id);
438 if (new_blob == NULL) 450 if (new_blob == NULL)
439 return -EINVAL; 451 return -EINVAL;
440 452
@@ -483,7 +495,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
483 drm_property_blob_put(mode); 495 drm_property_blob_put(mode);
484 return ret; 496 return ret;
485 } else if (property == config->degamma_lut_property) { 497 } else if (property == config->degamma_lut_property) {
486 ret = drm_atomic_replace_property_blob_from_id(crtc, 498 ret = drm_atomic_replace_property_blob_from_id(dev,
487 &state->degamma_lut, 499 &state->degamma_lut,
488 val, 500 val,
489 -1, 501 -1,
@@ -491,7 +503,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
491 state->color_mgmt_changed |= replaced; 503 state->color_mgmt_changed |= replaced;
492 return ret; 504 return ret;
493 } else if (property == config->ctm_property) { 505 } else if (property == config->ctm_property) {
494 ret = drm_atomic_replace_property_blob_from_id(crtc, 506 ret = drm_atomic_replace_property_blob_from_id(dev,
495 &state->ctm, 507 &state->ctm,
496 val, 508 val,
497 sizeof(struct drm_color_ctm), 509 sizeof(struct drm_color_ctm),
@@ -499,7 +511,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
499 state->color_mgmt_changed |= replaced; 511 state->color_mgmt_changed |= replaced;
500 return ret; 512 return ret;
501 } else if (property == config->gamma_lut_property) { 513 } else if (property == config->gamma_lut_property) {
502 ret = drm_atomic_replace_property_blob_from_id(crtc, 514 ret = drm_atomic_replace_property_blob_from_id(dev,
503 &state->gamma_lut, 515 &state->gamma_lut,
504 val, 516 val,
505 -1, 517 -1,
@@ -978,6 +990,59 @@ static void drm_atomic_plane_print_state(struct drm_printer *p,
978} 990}
979 991
980/** 992/**
993 * drm_atomic_get_private_obj_state - get private object state
994 * @state: global atomic state
995 * @obj: private object to get the state for
996 * @funcs: pointer to the struct of function pointers that identify the object
997 * type
998 *
999 * This function returns the private object state for the given private object,
1000 * allocating the state if needed. It does not grab any locks as the caller is
1001 * expected to care of any required locking.
1002 *
1003 * RETURNS:
1004 *
1005 * Either the allocated state or the error code encoded into a pointer.
1006 */
1007void *
1008drm_atomic_get_private_obj_state(struct drm_atomic_state *state, void *obj,
1009 const struct drm_private_state_funcs *funcs)
1010{
1011 int index, num_objs, i;
1012 size_t size;
1013 struct __drm_private_objs_state *arr;
1014
1015 for (i = 0; i < state->num_private_objs; i++)
1016 if (obj == state->private_objs[i].obj &&
1017 state->private_objs[i].obj_state)
1018 return state->private_objs[i].obj_state;
1019
1020 num_objs = state->num_private_objs + 1;
1021 size = sizeof(*state->private_objs) * num_objs;
1022 arr = krealloc(state->private_objs, size, GFP_KERNEL);
1023 if (!arr)
1024 return ERR_PTR(-ENOMEM);
1025
1026 state->private_objs = arr;
1027 index = state->num_private_objs;
1028 memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
1029
1030 state->private_objs[index].obj_state = funcs->duplicate_state(state, obj);
1031 if (!state->private_objs[index].obj_state)
1032 return ERR_PTR(-ENOMEM);
1033
1034 state->private_objs[index].obj = obj;
1035 state->private_objs[index].funcs = funcs;
1036 state->num_private_objs = num_objs;
1037
1038 DRM_DEBUG_ATOMIC("Added new private object state %p to %p\n",
1039 state->private_objs[index].obj_state, state);
1040
1041 return state->private_objs[index].obj_state;
1042}
1043EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
1044
1045/**
981 * drm_atomic_get_connector_state - get connector state 1046 * drm_atomic_get_connector_state - get connector state
982 * @state: global atomic state object 1047 * @state: global atomic state object
983 * @connector: connector to get state object for 1048 * @connector: connector to get state object for
@@ -1123,6 +1188,10 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
1123 */ 1188 */
1124 if (state->link_status != DRM_LINK_STATUS_GOOD) 1189 if (state->link_status != DRM_LINK_STATUS_GOOD)
1125 state->link_status = val; 1190 state->link_status = val;
1191 } else if (property == config->aspect_ratio_property) {
1192 state->picture_aspect_ratio = val;
1193 } else if (property == connector->scaling_mode_property) {
1194 state->scaling_mode = val;
1126 } else if (connector->funcs->atomic_set_property) { 1195 } else if (connector->funcs->atomic_set_property) {
1127 return connector->funcs->atomic_set_property(connector, 1196 return connector->funcs->atomic_set_property(connector,
1128 state, property, val); 1197 state, property, val);
@@ -1199,6 +1268,10 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
1199 *val = state->tv.hue; 1268 *val = state->tv.hue;
1200 } else if (property == config->link_status_property) { 1269 } else if (property == config->link_status_property) {
1201 *val = state->link_status; 1270 *val = state->link_status;
1271 } else if (property == config->aspect_ratio_property) {
1272 *val = state->picture_aspect_ratio;
1273 } else if (property == connector->scaling_mode_property) {
1274 *val = state->scaling_mode;
1202 } else if (connector->funcs->atomic_get_property) { 1275 } else if (connector->funcs->atomic_get_property) {
1203 return connector->funcs->atomic_get_property(connector, 1276 return connector->funcs->atomic_get_property(connector,
1204 state, property, val); 1277 state, property, val);
@@ -1618,7 +1691,7 @@ int drm_atomic_commit(struct drm_atomic_state *state)
1618 if (ret) 1691 if (ret)
1619 return ret; 1692 return ret;
1620 1693
1621 DRM_DEBUG_ATOMIC("commiting %p\n", state); 1694 DRM_DEBUG_ATOMIC("committing %p\n", state);
1622 1695
1623 return config->funcs->atomic_commit(state->dev, state, false); 1696 return config->funcs->atomic_commit(state->dev, state, false);
1624} 1697}
@@ -1647,7 +1720,7 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1647 if (ret) 1720 if (ret)
1648 return ret; 1721 return ret;
1649 1722
1650 DRM_DEBUG_ATOMIC("commiting %p nonblocking\n", state); 1723 DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
1651 1724
1652 return config->funcs->atomic_commit(state->dev, state, true); 1725 return config->funcs->atomic_commit(state->dev, state, true);
1653} 1726}