diff options
| author | Dhaval Patel <pdhaval@quicinc.com> | 2016-08-11 09:52:52 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-08-11 09:52:52 -0700 |
| commit | a7e7d08a9bf598881ba51ead85e453feb2d7064b (patch) | |
| tree | 02486fb638473adbc10ea717815e48b6eb254fc3 /drivers/gpu | |
| parent | e61b02b35bc3b2b93f7db12be9e039350b9cacd1 (diff) | |
| parent | a578cd5a27ba6f4445bacfb74fa5c093565a6bb6 (diff) | |
Merge "drm/msm/sde: add support for dirty properties" into dev/msm-4.4-drm_kms
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_prop.c | 66 | ||||
| -rw-r--r-- | drivers/gpu/drm/msm/msm_prop.h | 54 |
2 files changed, 120 insertions, 0 deletions
diff --git a/drivers/gpu/drm/msm/msm_prop.c b/drivers/gpu/drm/msm/msm_prop.c index 2191674ac924..5c930b861822 100644 --- a/drivers/gpu/drm/msm/msm_prop.c +++ b/drivers/gpu/drm/msm/msm_prop.c @@ -21,6 +21,8 @@ void msm_property_init(struct msm_property_info *info, uint32_t blob_count, uint32_t state_size) { + int i; + /* prevent access if any of these are NULL */ if (!base || !dev || !property_array || !property_data) { property_count = 0; @@ -49,6 +51,7 @@ void msm_property_init(struct msm_property_info *info, info->install_request = 0; info->install_count = 0; info->recent_idx = 0; + info->is_active = false; info->state_size = state_size; info->state_cache_size = 0; mutex_init(&info->property_lock); @@ -57,6 +60,10 @@ void msm_property_init(struct msm_property_info *info, 0, sizeof(struct msm_property_data) * property_count); + INIT_LIST_HEAD(&info->dirty_list); + + for (i = 0; i < property_count; ++i) + INIT_LIST_HEAD(&property_data[i].dirty_node); } } @@ -65,6 +72,9 @@ void msm_property_destroy(struct msm_property_info *info) if (!info) return; + /* reset dirty list */ + INIT_LIST_HEAD(&info->dirty_list); + /* free state cache */ while (info->state_cache_size > 0) kfree(info->state_cache[--(info->state_cache_size)]); @@ -72,6 +82,58 @@ void msm_property_destroy(struct msm_property_info *info) mutex_destroy(&info->property_lock); } +int msm_property_pop_dirty(struct msm_property_info *info) +{ + struct list_head *item; + int rc = 0; + + if (!info) { + DRM_ERROR("invalid info\n"); + return -EINVAL; + } + + mutex_lock(&info->property_lock); + if (list_empty(&info->dirty_list)) { + rc = -EAGAIN; + } else { + item = info->dirty_list.next; + list_del_init(item); + rc = container_of(item, struct msm_property_data, dirty_node) + - info->property_data; + DRM_DEBUG_KMS("property %d dirty\n", rc); + } + mutex_unlock(&info->property_lock); + + return rc; +} + +/** + * _msm_property_set_dirty_no_lock - flag given property as being dirty + * This function doesn't mutex protect the + * dirty linked list. + * @info: Pointer to property info container struct + * @property_idx: Property index + */ +static void _msm_property_set_dirty_no_lock( + struct msm_property_info *info, + uint32_t property_idx) +{ + if (!info || property_idx >= info->property_count) { + DRM_ERROR("invalid argument(s), info %pK, idx %u\n", + info, property_idx); + return; + } + + /* avoid re-inserting if already dirty */ + if (!list_empty(&info->property_data[property_idx].dirty_node)) { + DRM_DEBUG_KMS("property %u already dirty\n", property_idx); + return; + } + + list_add_tail(&info->property_data[property_idx].dirty_node, + &info->dirty_list); +} + void msm_property_install_range(struct msm_property_info *info, const char *name, int flags, uint64_t min, uint64_t max, uint64_t init, uint32_t property_idx) @@ -312,8 +374,12 @@ int msm_property_atomic_set(struct msm_property_info *info, property_blobs[property_idx] = blob; } } + + /* update value and flag as dirty */ property_values[property_idx] = val; + _msm_property_set_dirty_no_lock(info, property_idx); mutex_unlock(&info->property_lock); + DBG("%s - %lld", property->name, val); rc = 0; } diff --git a/drivers/gpu/drm/msm/msm_prop.h b/drivers/gpu/drm/msm/msm_prop.h index f83013f87e32..c53b6dbd33f7 100644 --- a/drivers/gpu/drm/msm/msm_prop.h +++ b/drivers/gpu/drm/msm/msm_prop.h @@ -13,6 +13,7 @@ #ifndef _MSM_PROP_H_ #define _MSM_PROP_H_ +#include <linux/list.h> #include "msm_drv.h" #define MSM_PROP_STATE_CACHE_SIZE 2 @@ -21,9 +22,11 @@ * struct msm_property_data - opaque structure for tracking per * drm-object per property stuff * @default_value: Default property value for this drm object + * @dirty_node: Linked list node to track if property is dirty or not */ struct msm_property_data { uint64_t default_value; + struct list_head dirty_node; }; /** @@ -37,6 +40,9 @@ struct msm_property_data { * @install_request: Total number of property 'install' requests * @install_count: Total number of successful 'install' requests * @recent_idx: Index of property most recently accessed by set/get + * @dirty_list: List of all properties that have been 'atomic_set' but not + * yet cleared with 'msm_property_pop_dirty' + * @is_active: Whether or not drm component properties are 'active' * @state_cache: Cache of local states, to prevent alloc/free thrashing * @state_size: Size of local state structures * @state_cache_size: Number of state structures currently stored in state_cache @@ -55,6 +61,9 @@ struct msm_property_info { int32_t recent_idx; + struct list_head dirty_list; + bool is_active; + void *state_cache[MSM_PROP_STATE_CACHE_SIZE]; uint32_t state_size; int32_t state_cache_size; @@ -85,6 +94,51 @@ uint64_t msm_property_get_default(struct msm_property_info *info, } /** + * msm_property_set_is_active - set overall 'active' status for all properties + * @info: Pointer to property info container struct + * @is_active: New 'is active' status + */ +static inline +void msm_property_set_is_active(struct msm_property_info *info, bool is_active) +{ + if (info) { + mutex_lock(&info->property_lock); + info->is_active = is_active; + mutex_unlock(&info->property_lock); + } +} + +/** + * msm_property_get_is_active - query property 'is active' status + * @info: Pointer to property info container struct + * Returns: Current 'is active's status + */ +static inline +bool msm_property_get_is_active(struct msm_property_info *info) +{ + bool rc = false; + + if (info) { + mutex_lock(&info->property_lock); + rc = info->is_active; + mutex_unlock(&info->property_lock); + } + + return rc; +} + +/** + * msm_property_pop_dirty - determine next dirty property and clear + * its dirty flag + * @info: Pointer to property info container struct + * Returns: Valid msm property index on success, + * -EAGAIN if no dirty properties are available + * Property indicies returned from this function are similar + * to those returned by the msm_property_index function. + */ +int msm_property_pop_dirty(struct msm_property_info *info); + +/** * msm_property_init - initialize property info structure * @info: Pointer to property info container struct * @base: Pointer to base drm object (plane/crtc/etc.) |
