aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_atomic.c
diff options
context:
space:
mode:
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}