mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Merge tag 'topic/drm-misc-2016-06-07' of git://anongit.freedesktop.org/drm-intel into drm-next
As promised, piles of prep work all around:
- drm_atomic_state rework, prep for nonblocking commit helpers
- fence patches from Gustavo and Christian to prep for atomic fences and
some cool work in ttm/amdgpu from Christian
- drm event prep for both nonblocking commit and atomic fences
- Gustavo seems on a crusade against the non-kms-native version of the
vblank functions.
- prep work from Boris to nuke all the silly ->best_encoder
implementations we have (we really only need that for truly dynamic
cases like dvi-i vs dvi-d or dp mst selecting the right transcoder on
intel)
- prep work from Laurent to rework the format handling functions
- and few small things all over
* tag 'topic/drm-misc-2016-06-07' of git://anongit.freedesktop.org/drm-intel: (47 commits)
drm/dsi: Implement set tear scanline
drm/fb_cma_helper: Implement fb_mmap callback
drm/qxl: Remove useless drm_fb_get_bpp_depth() call
drm/ast: Remove useless drm_fb_get_bpp_depth() call
drm/atomic: Fix remaining places where !funcs->best_encoder is valid
drm/core: Change declaration for gamma_set.
Documentation: add fence-array to kernel DocBook
drm/shmobile: use drm_crtc_vblank_{get,put}()
drm/radeon: use drm_crtc_vblank_{get,put}()
drm/qxl: use drm_crtc_vblank_{get,put}()
drm/atmel: use drm_crtc_vblank_{get,put}()
drm/armada: use drm_crtc_vblank_{get,put}()
drm/amdgpu: use drm_crtc_vblank_{get,put}()
drm/virtio: use drm_crtc_send_vblank_event()
drm/udl: use drm_crtc_send_vblank_event()
drm/qxl: use drm_crtc_send_vblank_event()
drm/atmel: use drm_crtc_send_vblank_event()
drm/armada: use drm_crtc_send_vblank_event()
drm/doc: Switch to sphinx/rst fixed-width quoting
drm/doc: Drop kerneldoc for static functions in drm_irq.c
...
This commit is contained in:
commit
2cca455740
82 changed files with 849 additions and 517 deletions
|
|
@ -1,2 +1,2 @@
|
|||
obj-y := dma-buf.o fence.o reservation.o seqno-fence.o
|
||||
obj-y := dma-buf.o fence.o reservation.o seqno-fence.o fence-array.o
|
||||
obj-$(CONFIG_SYNC_FILE) += sync_file.o
|
||||
|
|
|
|||
144
drivers/dma-buf/fence-array.c
Normal file
144
drivers/dma-buf/fence-array.c
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* fence-array: aggregate fences to be waited together
|
||||
*
|
||||
* Copyright (C) 2016 Collabora Ltd
|
||||
* Copyright (C) 2016 Advanced Micro Devices, Inc.
|
||||
* Authors:
|
||||
* Gustavo Padovan <gustavo@padovan.org>
|
||||
* Christian König <christian.koenig@amd.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include <linux/export.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fence-array.h>
|
||||
|
||||
static void fence_array_cb_func(struct fence *f, struct fence_cb *cb);
|
||||
|
||||
static const char *fence_array_get_driver_name(struct fence *fence)
|
||||
{
|
||||
return "fence_array";
|
||||
}
|
||||
|
||||
static const char *fence_array_get_timeline_name(struct fence *fence)
|
||||
{
|
||||
return "unbound";
|
||||
}
|
||||
|
||||
static void fence_array_cb_func(struct fence *f, struct fence_cb *cb)
|
||||
{
|
||||
struct fence_array_cb *array_cb =
|
||||
container_of(cb, struct fence_array_cb, cb);
|
||||
struct fence_array *array = array_cb->array;
|
||||
|
||||
if (atomic_dec_and_test(&array->num_pending))
|
||||
fence_signal(&array->base);
|
||||
fence_put(&array->base);
|
||||
}
|
||||
|
||||
static bool fence_array_enable_signaling(struct fence *fence)
|
||||
{
|
||||
struct fence_array *array = to_fence_array(fence);
|
||||
struct fence_array_cb *cb = (void *)(&array[1]);
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < array->num_fences; ++i) {
|
||||
cb[i].array = array;
|
||||
/*
|
||||
* As we may report that the fence is signaled before all
|
||||
* callbacks are complete, we need to take an additional
|
||||
* reference count on the array so that we do not free it too
|
||||
* early. The core fence handling will only hold the reference
|
||||
* until we signal the array as complete (but that is now
|
||||
* insufficient).
|
||||
*/
|
||||
fence_get(&array->base);
|
||||
if (fence_add_callback(array->fences[i], &cb[i].cb,
|
||||
fence_array_cb_func)) {
|
||||
fence_put(&array->base);
|
||||
if (atomic_dec_and_test(&array->num_pending))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool fence_array_signaled(struct fence *fence)
|
||||
{
|
||||
struct fence_array *array = to_fence_array(fence);
|
||||
|
||||
return atomic_read(&array->num_pending) <= 0;
|
||||
}
|
||||
|
||||
static void fence_array_release(struct fence *fence)
|
||||
{
|
||||
struct fence_array *array = to_fence_array(fence);
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < array->num_fences; ++i)
|
||||
fence_put(array->fences[i]);
|
||||
|
||||
kfree(array->fences);
|
||||
fence_free(fence);
|
||||
}
|
||||
|
||||
const struct fence_ops fence_array_ops = {
|
||||
.get_driver_name = fence_array_get_driver_name,
|
||||
.get_timeline_name = fence_array_get_timeline_name,
|
||||
.enable_signaling = fence_array_enable_signaling,
|
||||
.signaled = fence_array_signaled,
|
||||
.wait = fence_default_wait,
|
||||
.release = fence_array_release,
|
||||
};
|
||||
|
||||
/**
|
||||
* fence_array_create - Create a custom fence array
|
||||
* @num_fences: [in] number of fences to add in the array
|
||||
* @fences: [in] array containing the fences
|
||||
* @context: [in] fence context to use
|
||||
* @seqno: [in] sequence number to use
|
||||
* @signal_on_any [in] signal on any fence in the array
|
||||
*
|
||||
* Allocate a fence_array object and initialize the base fence with fence_init().
|
||||
* In case of error it returns NULL.
|
||||
*
|
||||
* The caller should allocte the fences array with num_fences size
|
||||
* and fill it with the fences it wants to add to the object. Ownership of this
|
||||
* array is take and fence_put() is used on each fence on release.
|
||||
*
|
||||
* If @signal_on_any is true the fence array signals if any fence in the array
|
||||
* signals, otherwise it signals when all fences in the array signal.
|
||||
*/
|
||||
struct fence_array *fence_array_create(int num_fences, struct fence **fences,
|
||||
u64 context, unsigned seqno,
|
||||
bool signal_on_any)
|
||||
{
|
||||
struct fence_array *array;
|
||||
size_t size = sizeof(*array);
|
||||
|
||||
/* Allocate the callback structures behind the array. */
|
||||
size += num_fences * sizeof(struct fence_array_cb);
|
||||
array = kzalloc(size, GFP_KERNEL);
|
||||
if (!array)
|
||||
return NULL;
|
||||
|
||||
spin_lock_init(&array->lock);
|
||||
fence_init(&array->base, &fence_array_ops, &array->lock,
|
||||
context, seqno);
|
||||
|
||||
array->num_fences = num_fences;
|
||||
atomic_set(&array->num_pending, signal_on_any ? 1 : num_fences);
|
||||
array->fences = fences;
|
||||
|
||||
return array;
|
||||
}
|
||||
EXPORT_SYMBOL(fence_array_create);
|
||||
|
|
@ -35,7 +35,7 @@ EXPORT_TRACEPOINT_SYMBOL(fence_emit);
|
|||
* context or not. One device can have multiple separate contexts,
|
||||
* and they're used if some engine can run independently of another.
|
||||
*/
|
||||
static atomic_t fence_context_counter = ATOMIC_INIT(0);
|
||||
static atomic64_t fence_context_counter = ATOMIC64_INIT(0);
|
||||
|
||||
/**
|
||||
* fence_context_alloc - allocate an array of fence contexts
|
||||
|
|
@ -44,10 +44,10 @@ static atomic_t fence_context_counter = ATOMIC_INIT(0);
|
|||
* This function will return the first index of the number of fences allocated.
|
||||
* The fence context is used for setting fence->context to a unique number.
|
||||
*/
|
||||
unsigned fence_context_alloc(unsigned num)
|
||||
u64 fence_context_alloc(unsigned num)
|
||||
{
|
||||
BUG_ON(!num);
|
||||
return atomic_add_return(num, &fence_context_counter) - num;
|
||||
return atomic64_add_return(num, &fence_context_counter) - num;
|
||||
}
|
||||
EXPORT_SYMBOL(fence_context_alloc);
|
||||
|
||||
|
|
@ -513,7 +513,7 @@ EXPORT_SYMBOL(fence_wait_any_timeout);
|
|||
*/
|
||||
void
|
||||
fence_init(struct fence *fence, const struct fence_ops *ops,
|
||||
spinlock_t *lock, unsigned context, unsigned seqno)
|
||||
spinlock_t *lock, u64 context, unsigned seqno)
|
||||
{
|
||||
BUG_ON(!lock);
|
||||
BUG_ON(!ops || !ops->wait || !ops->enable_signaling ||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ struct sync_file *sync_file_create(struct fence *fence)
|
|||
|
||||
sync_file->num_fences = 1;
|
||||
atomic_set(&sync_file->status, 1);
|
||||
snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%d-%d",
|
||||
snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d",
|
||||
fence->ops->get_driver_name(fence),
|
||||
fence->ops->get_timeline_name(fence), fence->context,
|
||||
fence->seqno);
|
||||
|
|
|
|||
Loading…
Reference in a new issue