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
|
@ -161,6 +161,10 @@ X!Edrivers/base/interface.c
|
|||
!Iinclude/linux/fence.h
|
||||
!Edrivers/dma-buf/seqno-fence.c
|
||||
!Iinclude/linux/seqno-fence.h
|
||||
!Edrivers/dma-buf/fence-array.c
|
||||
!Iinclude/linux/fence-array.h
|
||||
!Edrivers/dma-buf/reservation.c
|
||||
!Iinclude/linux/reservation.h
|
||||
!Edrivers/dma-buf/sync_file.c
|
||||
!Iinclude/linux/sync_file.h
|
||||
</sect2>
|
||||
|
|
|
@ -1570,7 +1570,7 @@ void intel_crt_init(struct drm_device *dev)
|
|||
</sect3>
|
||||
<sect3>
|
||||
<title>Implementing Asynchronous Atomic Commit</title>
|
||||
!Pdrivers/gpu/drm/drm_atomic_helper.c implementing async commit
|
||||
!Pdrivers/gpu/drm/drm_atomic_helper.c implementing nonblocking commit
|
||||
</sect3>
|
||||
<sect3>
|
||||
<title>Atomic State Reset and Initialization</title>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -2032,7 +2032,7 @@ struct amdgpu_device {
|
|||
struct amdgpu_irq_src hpd_irq;
|
||||
|
||||
/* rings */
|
||||
unsigned fence_context;
|
||||
u64 fence_context;
|
||||
unsigned num_rings;
|
||||
struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
|
||||
bool ib_pool_ready;
|
||||
|
|
|
@ -240,7 +240,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
|
|||
|
||||
work->base = base;
|
||||
|
||||
r = drm_vblank_get(crtc->dev, amdgpu_crtc->crtc_id);
|
||||
r = drm_crtc_vblank_get(crtc);
|
||||
if (r) {
|
||||
DRM_ERROR("failed to get vblank before flip\n");
|
||||
goto pflip_cleanup;
|
||||
|
@ -268,7 +268,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
|
|||
return 0;
|
||||
|
||||
vblank_cleanup:
|
||||
drm_vblank_put(crtc->dev, amdgpu_crtc->crtc_id);
|
||||
drm_crtc_vblank_put(&amdgpu_crtc->base);
|
||||
|
||||
pflip_cleanup:
|
||||
if (unlikely(amdgpu_bo_reserve(new_rbo, false) != 0)) {
|
||||
|
|
|
@ -427,7 +427,7 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
|
|||
soffset, eoffset, eoffset - soffset);
|
||||
|
||||
if (i->fence)
|
||||
seq_printf(m, " protected by 0x%08x on context %d",
|
||||
seq_printf(m, " protected by 0x%08x on context %llu",
|
||||
i->fence->seqno, i->fence->context);
|
||||
|
||||
seq_printf(m, "\n");
|
||||
|
|
|
@ -2667,19 +2667,21 @@ static void dce_v10_0_cursor_reset(struct drm_crtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
static void dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t start, uint32_t size)
|
||||
static int dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int end = (start + size > 256) ? 256 : start + size, i;
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
dce_v10_0_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dce_v10_0_crtc_destroy(struct drm_crtc *crtc)
|
||||
|
@ -3372,7 +3374,7 @@ static int dce_v10_0_pageflip_irq(struct amdgpu_device *adev,
|
|||
|
||||
spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
|
||||
|
||||
drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
|
||||
drm_crtc_vblank_put(&amdgpu_crtc->base);
|
||||
schedule_work(&works->unpin_work);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2678,19 +2678,21 @@ static void dce_v11_0_cursor_reset(struct drm_crtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
static void dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t start, uint32_t size)
|
||||
static int dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int end = (start + size > 256) ? 256 : start + size, i;
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
dce_v11_0_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dce_v11_0_crtc_destroy(struct drm_crtc *crtc)
|
||||
|
@ -3433,7 +3435,7 @@ static int dce_v11_0_pageflip_irq(struct amdgpu_device *adev,
|
|||
|
||||
spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
|
||||
|
||||
drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
|
||||
drm_crtc_vblank_put(&amdgpu_crtc->base);
|
||||
schedule_work(&works->unpin_work);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2574,19 +2574,21 @@ static void dce_v8_0_cursor_reset(struct drm_crtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
static void dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t start, uint32_t size)
|
||||
static int dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
|
||||
int end = (start + size > 256) ? 256 : start + size, i;
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
amdgpu_crtc->lut_r[i] = red[i] >> 6;
|
||||
amdgpu_crtc->lut_g[i] = green[i] >> 6;
|
||||
amdgpu_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
dce_v8_0_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dce_v8_0_crtc_destroy(struct drm_crtc *crtc)
|
||||
|
@ -3376,7 +3378,7 @@ static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev,
|
|||
|
||||
spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
|
||||
|
||||
drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id);
|
||||
drm_crtc_vblank_put(&amdgpu_crtc->base);
|
||||
schedule_work(&works->unpin_work);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -92,7 +92,7 @@ static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file)
|
|||
if (e->base.file_priv != file)
|
||||
continue;
|
||||
list_del(&e->base.link);
|
||||
e->base.destroy(&e->base);
|
||||
kfree(&e->base);
|
||||
}
|
||||
spin_unlock_irqrestore(&drm->event_lock, flags);
|
||||
}
|
||||
|
|
|
@ -196,30 +196,11 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
|
|||
}
|
||||
}
|
||||
|
||||
static void hdlcd_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
}
|
||||
|
||||
static bool hdlcd_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
const struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
|
||||
.mode_fixup = hdlcd_crtc_mode_fixup,
|
||||
.mode_set = drm_helper_crtc_mode_set,
|
||||
.mode_set_base = drm_helper_crtc_mode_set_base,
|
||||
.mode_set_nofb = hdlcd_crtc_mode_set_nofb,
|
||||
.enable = hdlcd_crtc_enable,
|
||||
.disable = hdlcd_crtc_disable,
|
||||
.prepare = hdlcd_crtc_disable,
|
||||
.commit = hdlcd_crtc_enable,
|
||||
.atomic_check = hdlcd_crtc_atomic_check,
|
||||
.atomic_begin = hdlcd_crtc_atomic_begin,
|
||||
.atomic_flush = hdlcd_crtc_atomic_flush,
|
||||
};
|
||||
|
||||
static int hdlcd_plane_atomic_check(struct drm_plane *plane,
|
||||
|
|
|
@ -199,7 +199,7 @@ static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
|
|||
/* Handle any pending frame work. */
|
||||
if (work) {
|
||||
work->fn(dcrtc, plane, work);
|
||||
drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
|
||||
drm_crtc_vblank_put(&dcrtc->crtc);
|
||||
}
|
||||
|
||||
wake_up(&plane->frame_wait);
|
||||
|
@ -210,7 +210,7 @@ int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
|
|||
{
|
||||
int ret;
|
||||
|
||||
ret = drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
|
||||
ret = drm_crtc_vblank_get(&dcrtc->crtc);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to acquire vblank counter\n");
|
||||
return ret;
|
||||
|
@ -218,7 +218,7 @@ int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
|
|||
|
||||
ret = cmpxchg(&plane->work, NULL, work) ? -EBUSY : 0;
|
||||
if (ret)
|
||||
drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
|
||||
drm_crtc_vblank_put(&dcrtc->crtc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ struct armada_plane_work *armada_drm_plane_work_cancel(
|
|||
struct armada_plane_work *work = xchg(&plane->work, NULL);
|
||||
|
||||
if (work)
|
||||
drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
|
||||
drm_crtc_vblank_put(&dcrtc->crtc);
|
||||
|
||||
return work;
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
|
|||
|
||||
if (fwork->event) {
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
drm_send_vblank_event(dev, dcrtc->num, fwork->event);
|
||||
drm_crtc_send_vblank_event(&dcrtc->crtc, fwork->event);
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -592,9 +592,9 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
|
|||
|
||||
if (interlaced ^ dcrtc->interlaced) {
|
||||
if (adj->flags & DRM_MODE_FLAG_INTERLACE)
|
||||
drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
|
||||
drm_crtc_vblank_get(&dcrtc->crtc);
|
||||
else
|
||||
drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
|
||||
drm_crtc_vblank_put(&dcrtc->crtc);
|
||||
dcrtc->interlaced = interlaced;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,12 +167,9 @@ static int astfb_create_object(struct ast_fbdev *afbdev,
|
|||
struct drm_gem_object **gobj_p)
|
||||
{
|
||||
struct drm_device *dev = afbdev->helper.dev;
|
||||
u32 bpp, depth;
|
||||
u32 size;
|
||||
struct drm_gem_object *gobj;
|
||||
|
||||
int ret = 0;
|
||||
drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
|
||||
|
||||
size = mode_cmd->pitches[0] * mode_cmd->height;
|
||||
ret = ast_gem_create(dev, size, true, &gobj);
|
||||
|
|
|
@ -624,19 +624,21 @@ static void ast_crtc_reset(struct drm_crtc *crtc)
|
|||
|
||||
}
|
||||
|
||||
static void ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t start, uint32_t size)
|
||||
static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
|
||||
int end = (start + size > 256) ? 256 : start + size, i;
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
ast_crtc->lut_r[i] = red[i] >> 8;
|
||||
ast_crtc->lut_g[i] = green[i] >> 8;
|
||||
ast_crtc->lut_b[i] = blue[i] >> 8;
|
||||
}
|
||||
ast_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -374,8 +374,8 @@ static void atmel_hlcdc_crtc_finish_page_flip(struct atmel_hlcdc_crtc *crtc)
|
|||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
if (crtc->event) {
|
||||
drm_send_vblank_event(dev, crtc->id, crtc->event);
|
||||
drm_vblank_put(dev, crtc->id);
|
||||
drm_crtc_send_vblank_event(&crtc->base, crtc->event);
|
||||
drm_crtc_vblank_put(&crtc->base);
|
||||
crtc->event = NULL;
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
|
|
@ -325,18 +325,20 @@ static void cirrus_crtc_commit(struct drm_crtc *crtc)
|
|||
* use this for 8-bit mode so can't perform smooth fades on deeper modes,
|
||||
* but it's a requirement that we provide the function
|
||||
*/
|
||||
static void cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t start, uint32_t size)
|
||||
static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CIRRUS_LUT_SIZE; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
cirrus_crtc->lut_r[i] = red[i];
|
||||
cirrus_crtc->lut_g[i] = green[i];
|
||||
cirrus_crtc->lut_b[i] = blue[i];
|
||||
}
|
||||
cirrus_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Simple cleanup function */
|
||||
|
|
|
@ -44,11 +44,8 @@
|
|||
void drm_atomic_state_default_release(struct drm_atomic_state *state)
|
||||
{
|
||||
kfree(state->connectors);
|
||||
kfree(state->connector_states);
|
||||
kfree(state->crtcs);
|
||||
kfree(state->crtc_states);
|
||||
kfree(state->planes);
|
||||
kfree(state->plane_states);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_state_default_release);
|
||||
|
||||
|
@ -72,18 +69,10 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
|
|||
sizeof(*state->crtcs), GFP_KERNEL);
|
||||
if (!state->crtcs)
|
||||
goto fail;
|
||||
state->crtc_states = kcalloc(dev->mode_config.num_crtc,
|
||||
sizeof(*state->crtc_states), GFP_KERNEL);
|
||||
if (!state->crtc_states)
|
||||
goto fail;
|
||||
state->planes = kcalloc(dev->mode_config.num_total_plane,
|
||||
sizeof(*state->planes), GFP_KERNEL);
|
||||
if (!state->planes)
|
||||
goto fail;
|
||||
state->plane_states = kcalloc(dev->mode_config.num_total_plane,
|
||||
sizeof(*state->plane_states), GFP_KERNEL);
|
||||
if (!state->plane_states)
|
||||
goto fail;
|
||||
|
||||
state->dev = dev;
|
||||
|
||||
|
@ -139,40 +128,40 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
|
|||
DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
|
||||
|
||||
for (i = 0; i < state->num_connector; i++) {
|
||||
struct drm_connector *connector = state->connectors[i];
|
||||
struct drm_connector *connector = state->connectors[i].ptr;
|
||||
|
||||
if (!connector)
|
||||
continue;
|
||||
|
||||
connector->funcs->atomic_destroy_state(connector,
|
||||
state->connector_states[i]);
|
||||
state->connectors[i] = NULL;
|
||||
state->connector_states[i] = NULL;
|
||||
state->connectors[i].state);
|
||||
state->connectors[i].ptr = NULL;
|
||||
state->connectors[i].state = NULL;
|
||||
drm_connector_unreference(connector);
|
||||
}
|
||||
|
||||
for (i = 0; i < config->num_crtc; i++) {
|
||||
struct drm_crtc *crtc = state->crtcs[i];
|
||||
struct drm_crtc *crtc = state->crtcs[i].ptr;
|
||||
|
||||
if (!crtc)
|
||||
continue;
|
||||
|
||||
crtc->funcs->atomic_destroy_state(crtc,
|
||||
state->crtc_states[i]);
|
||||
state->crtcs[i] = NULL;
|
||||
state->crtc_states[i] = NULL;
|
||||
state->crtcs[i].state);
|
||||
state->crtcs[i].ptr = NULL;
|
||||
state->crtcs[i].state = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < config->num_total_plane; i++) {
|
||||
struct drm_plane *plane = state->planes[i];
|
||||
struct drm_plane *plane = state->planes[i].ptr;
|
||||
|
||||
if (!plane)
|
||||
continue;
|
||||
|
||||
plane->funcs->atomic_destroy_state(plane,
|
||||
state->plane_states[i]);
|
||||
state->planes[i] = NULL;
|
||||
state->plane_states[i] = NULL;
|
||||
state->planes[i].state);
|
||||
state->planes[i].ptr = NULL;
|
||||
state->planes[i].state = NULL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_atomic_state_default_clear);
|
||||
|
@ -270,8 +259,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
|
|||
if (!crtc_state)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
state->crtc_states[index] = crtc_state;
|
||||
state->crtcs[index] = crtc;
|
||||
state->crtcs[index].state = crtc_state;
|
||||
state->crtcs[index].ptr = crtc;
|
||||
crtc_state->state = state;
|
||||
|
||||
DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
|
||||
|
@ -632,8 +621,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
|
|||
if (!plane_state)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
state->plane_states[index] = plane_state;
|
||||
state->planes[index] = plane;
|
||||
state->planes[index].state = plane_state;
|
||||
state->planes[index].ptr = plane;
|
||||
plane_state->state = state;
|
||||
|
||||
DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
|
||||
|
@ -897,8 +886,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
|
|||
index = drm_connector_index(connector);
|
||||
|
||||
if (index >= state->num_connector) {
|
||||
struct drm_connector **c;
|
||||
struct drm_connector_state **cs;
|
||||
struct __drm_connnectors_state *c;
|
||||
int alloc = max(index + 1, config->num_connector);
|
||||
|
||||
c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
|
||||
|
@ -909,26 +897,19 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
|
|||
memset(&state->connectors[state->num_connector], 0,
|
||||
sizeof(*state->connectors) * (alloc - state->num_connector));
|
||||
|
||||
cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL);
|
||||
if (!cs)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
state->connector_states = cs;
|
||||
memset(&state->connector_states[state->num_connector], 0,
|
||||
sizeof(*state->connector_states) * (alloc - state->num_connector));
|
||||
state->num_connector = alloc;
|
||||
}
|
||||
|
||||
if (state->connector_states[index])
|
||||
return state->connector_states[index];
|
||||
if (state->connectors[index].state)
|
||||
return state->connectors[index].state;
|
||||
|
||||
connector_state = connector->funcs->atomic_duplicate_state(connector);
|
||||
if (!connector_state)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
drm_connector_reference(connector);
|
||||
state->connector_states[index] = connector_state;
|
||||
state->connectors[index] = connector;
|
||||
state->connectors[index].state = connector_state;
|
||||
state->connectors[index].ptr = connector;
|
||||
connector_state->state = state;
|
||||
|
||||
DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
|
||||
|
@ -1432,7 +1413,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
|
|||
*/
|
||||
|
||||
static struct drm_pending_vblank_event *create_vblank_event(
|
||||
struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
|
||||
struct drm_device *dev, struct drm_file *file_priv,
|
||||
struct fence *fence, uint64_t user_data)
|
||||
{
|
||||
struct drm_pending_vblank_event *e = NULL;
|
||||
int ret;
|
||||
|
@ -1445,12 +1427,17 @@ static struct drm_pending_vblank_event *create_vblank_event(
|
|||
e->event.base.length = sizeof(e->event);
|
||||
e->event.user_data = user_data;
|
||||
|
||||
ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base);
|
||||
if (ret) {
|
||||
kfree(e);
|
||||
return NULL;
|
||||
if (file_priv) {
|
||||
ret = drm_event_reserve_init(dev, file_priv, &e->base,
|
||||
&e->event.base);
|
||||
if (ret) {
|
||||
kfree(e);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
e->base.fence = fence;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
@ -1690,7 +1677,8 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
|
|||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
struct drm_pending_vblank_event *e;
|
||||
|
||||
e = create_vblank_event(dev, file_priv, arg->user_data);
|
||||
e = create_vblank_event(dev, file_priv, NULL,
|
||||
arg->user_data);
|
||||
if (!e) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
|
|
|
@ -110,8 +110,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
|
|||
|
||||
if (funcs->atomic_best_encoder)
|
||||
new_encoder = funcs->atomic_best_encoder(connector, conn_state);
|
||||
else
|
||||
else if (funcs->best_encoder)
|
||||
new_encoder = funcs->best_encoder(connector);
|
||||
else
|
||||
new_encoder = drm_atomic_helper_best_encoder(connector);
|
||||
|
||||
if (new_encoder) {
|
||||
if (encoder_mask & (1 << drm_encoder_index(new_encoder))) {
|
||||
|
@ -298,8 +300,10 @@ update_connector_routing(struct drm_atomic_state *state,
|
|||
if (funcs->atomic_best_encoder)
|
||||
new_encoder = funcs->atomic_best_encoder(connector,
|
||||
connector_state);
|
||||
else
|
||||
else if (funcs->best_encoder)
|
||||
new_encoder = funcs->best_encoder(connector);
|
||||
else
|
||||
new_encoder = drm_atomic_helper_best_encoder(connector);
|
||||
|
||||
if (!new_encoder) {
|
||||
DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n",
|
||||
|
@ -614,7 +618,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
|
|||
if (!funcs || !funcs->atomic_check)
|
||||
continue;
|
||||
|
||||
ret = funcs->atomic_check(crtc, state->crtc_states[i]);
|
||||
ret = funcs->atomic_check(crtc, crtc_state);
|
||||
if (ret) {
|
||||
DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
|
||||
crtc->base.id, crtc->name);
|
||||
|
@ -1252,16 +1256,12 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
|
|||
int drm_atomic_helper_prepare_planes(struct drm_device *dev,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
int nplanes = dev->mode_config.num_total_plane;
|
||||
int ret, i;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *plane_state;
|
||||
int ret, i, j;
|
||||
|
||||
for (i = 0; i < nplanes; i++) {
|
||||
for_each_plane_in_state(state, plane, plane_state, i) {
|
||||
const struct drm_plane_helper_funcs *funcs;
|
||||
struct drm_plane *plane = state->planes[i];
|
||||
struct drm_plane_state *plane_state = state->plane_states[i];
|
||||
|
||||
if (!plane)
|
||||
continue;
|
||||
|
||||
funcs = plane->helper_private;
|
||||
|
||||
|
@ -1275,12 +1275,10 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
for (i--; i >= 0; i--) {
|
||||
for_each_plane_in_state(state, plane, plane_state, j) {
|
||||
const struct drm_plane_helper_funcs *funcs;
|
||||
struct drm_plane *plane = state->planes[i];
|
||||
struct drm_plane_state *plane_state = state->plane_states[i];
|
||||
|
||||
if (!plane)
|
||||
if (j >= i)
|
||||
continue;
|
||||
|
||||
funcs = plane->helper_private;
|
||||
|
@ -1567,37 +1565,28 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
|
|||
struct drm_atomic_state *state)
|
||||
{
|
||||
int i;
|
||||
struct drm_connector *connector;
|
||||
struct drm_connector_state *conn_state;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *plane_state;
|
||||
|
||||
for (i = 0; i < state->num_connector; i++) {
|
||||
struct drm_connector *connector = state->connectors[i];
|
||||
|
||||
if (!connector)
|
||||
continue;
|
||||
|
||||
for_each_connector_in_state(state, connector, conn_state, i) {
|
||||
connector->state->state = state;
|
||||
swap(state->connector_states[i], connector->state);
|
||||
swap(state->connectors[i].state, connector->state);
|
||||
connector->state->state = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < dev->mode_config.num_crtc; i++) {
|
||||
struct drm_crtc *crtc = state->crtcs[i];
|
||||
|
||||
if (!crtc)
|
||||
continue;
|
||||
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i) {
|
||||
crtc->state->state = state;
|
||||
swap(state->crtc_states[i], crtc->state);
|
||||
swap(state->crtcs[i].state, crtc->state);
|
||||
crtc->state->state = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < dev->mode_config.num_total_plane; i++) {
|
||||
struct drm_plane *plane = state->planes[i];
|
||||
|
||||
if (!plane)
|
||||
continue;
|
||||
|
||||
for_each_plane_in_state(state, plane, plane_state, i) {
|
||||
plane->state->state = state;
|
||||
swap(state->plane_states[i], plane->state);
|
||||
swap(state->planes[i].state, plane->state);
|
||||
plane->state->state = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2412,7 +2401,7 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
|
|||
* This is the main helper function provided by the atomic helper framework for
|
||||
* implementing the legacy DPMS connector interface. It computes the new desired
|
||||
* ->active state for the corresponding CRTC (if the connector is enabled) and
|
||||
* updates it.
|
||||
* updates it.
|
||||
*
|
||||
* Returns:
|
||||
* Returns 0 on success, negative errno numbers on failure.
|
||||
|
@ -2933,16 +2922,15 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
|
|||
* @red: red correction table
|
||||
* @green: green correction table
|
||||
* @blue: green correction table
|
||||
* @start:
|
||||
* @size: size of the tables
|
||||
*
|
||||
* Implements support for legacy gamma correction table for drivers
|
||||
* that support color management through the DEGAMMA_LUT/GAMMA_LUT
|
||||
* properties.
|
||||
*/
|
||||
void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
||||
u16 *red, u16 *green, u16 *blue,
|
||||
uint32_t start, uint32_t size)
|
||||
int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
||||
u16 *red, u16 *green, u16 *blue,
|
||||
uint32_t size)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_mode_config *config = &dev->mode_config;
|
||||
|
@ -2954,7 +2942,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
|||
|
||||
state = drm_atomic_state_alloc(crtc->dev);
|
||||
if (!state)
|
||||
return;
|
||||
return -ENOMEM;
|
||||
|
||||
blob = drm_property_create_blob(dev,
|
||||
sizeof(struct drm_color_lut) * size,
|
||||
|
@ -3005,7 +2993,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
|||
|
||||
drm_property_unreference_blob(blob);
|
||||
|
||||
return;
|
||||
return 0;
|
||||
fail:
|
||||
if (ret == -EDEADLK)
|
||||
goto backoff;
|
||||
|
@ -3013,7 +3001,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
|||
drm_atomic_state_free(state);
|
||||
drm_property_unreference_blob(blob);
|
||||
|
||||
return;
|
||||
return ret;
|
||||
backoff:
|
||||
drm_atomic_state_clear(state);
|
||||
drm_atomic_legacy_backoff(state);
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* encoder chain.
|
||||
*
|
||||
* A bridge is always attached to a single &drm_encoder at a time, but can be
|
||||
* either connected to it directly, or through an intermediate bridge:
|
||||
* either connected to it directly, or through an intermediate bridge::
|
||||
*
|
||||
* encoder ---> bridge B ---> bridge A
|
||||
*
|
||||
|
|
|
@ -535,7 +535,7 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);
|
|||
*
|
||||
* Cleanup framebuffer. This function is intended to be used from the drivers
|
||||
* ->destroy callback. It can also be used to clean up driver private
|
||||
* framebuffers embedded into a larger structure.
|
||||
* framebuffers embedded into a larger structure.
|
||||
*
|
||||
* Note that this function does not remove the fb from active usuage - if it is
|
||||
* still used anywhere, hilarity can ensue since userspace could call getfb on
|
||||
|
@ -692,7 +692,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
|
|||
crtc->base.properties = &crtc->properties;
|
||||
|
||||
list_add_tail(&crtc->head, &config->crtc_list);
|
||||
config->num_crtc++;
|
||||
crtc->index = config->num_crtc++;
|
||||
|
||||
crtc->primary = primary;
|
||||
crtc->cursor = cursor;
|
||||
|
@ -722,6 +722,11 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
|
|||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
|
||||
/* Note that the crtc_list is considered to be static; should we
|
||||
* remove the drm_crtc at runtime we would have to decrement all
|
||||
* the indices on the drm_crtc after us in the crtc_list.
|
||||
*/
|
||||
|
||||
kfree(crtc->gamma_store);
|
||||
crtc->gamma_store = NULL;
|
||||
|
||||
|
@ -741,29 +746,6 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_crtc_cleanup);
|
||||
|
||||
/**
|
||||
* drm_crtc_index - find the index of a registered CRTC
|
||||
* @crtc: CRTC to find index for
|
||||
*
|
||||
* Given a registered CRTC, return the index of that CRTC within a DRM
|
||||
* device's list of CRTCs.
|
||||
*/
|
||||
unsigned int drm_crtc_index(struct drm_crtc *crtc)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
struct drm_crtc *tmp;
|
||||
|
||||
drm_for_each_crtc(tmp, crtc->dev) {
|
||||
if (tmp == crtc)
|
||||
return index;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
BUG();
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_index);
|
||||
|
||||
/*
|
||||
* drm_mode_remove - remove and free a mode
|
||||
* @connector: connector list to modify
|
||||
|
@ -1166,7 +1148,7 @@ int drm_encoder_init(struct drm_device *dev,
|
|||
}
|
||||
|
||||
list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
|
||||
dev->mode_config.num_encoder++;
|
||||
encoder->index = dev->mode_config.num_encoder++;
|
||||
|
||||
out_put:
|
||||
if (ret)
|
||||
|
@ -1179,29 +1161,6 @@ int drm_encoder_init(struct drm_device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL(drm_encoder_init);
|
||||
|
||||
/**
|
||||
* drm_encoder_index - find the index of a registered encoder
|
||||
* @encoder: encoder to find index for
|
||||
*
|
||||
* Given a registered encoder, return the index of that encoder within a DRM
|
||||
* device's list of encoders.
|
||||
*/
|
||||
unsigned int drm_encoder_index(struct drm_encoder *encoder)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
struct drm_encoder *tmp;
|
||||
|
||||
drm_for_each_encoder(tmp, encoder->dev) {
|
||||
if (tmp == encoder)
|
||||
return index;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
BUG();
|
||||
}
|
||||
EXPORT_SYMBOL(drm_encoder_index);
|
||||
|
||||
/**
|
||||
* drm_encoder_cleanup - cleans up an initialised encoder
|
||||
* @encoder: encoder to cleanup
|
||||
|
@ -1212,6 +1171,11 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
|
|||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
|
||||
/* Note that the encoder_list is considered to be static; should we
|
||||
* remove the drm_encoder at runtime we would have to decrement all
|
||||
* the indices on the drm_encoder after us in the encoder_list.
|
||||
*/
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
drm_mode_object_unregister(dev, &encoder->base);
|
||||
kfree(encoder->name);
|
||||
|
@ -1300,7 +1264,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
|
|||
plane->type = type;
|
||||
|
||||
list_add_tail(&plane->head, &config->plane_list);
|
||||
config->num_total_plane++;
|
||||
plane->index = config->num_total_plane++;
|
||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY)
|
||||
config->num_overlay_plane++;
|
||||
|
||||
|
@ -1374,6 +1338,11 @@ void drm_plane_cleanup(struct drm_plane *plane)
|
|||
|
||||
BUG_ON(list_empty(&plane->head));
|
||||
|
||||
/* Note that the plane_list is considered to be static; should we
|
||||
* remove the drm_plane at runtime we would have to decrement all
|
||||
* the indices on the drm_plane after us in the plane_list.
|
||||
*/
|
||||
|
||||
list_del(&plane->head);
|
||||
dev->mode_config.num_total_plane--;
|
||||
if (plane->type == DRM_PLANE_TYPE_OVERLAY)
|
||||
|
@ -1390,29 +1359,6 @@ void drm_plane_cleanup(struct drm_plane *plane)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_plane_cleanup);
|
||||
|
||||
/**
|
||||
* drm_plane_index - find the index of a registered plane
|
||||
* @plane: plane to find index for
|
||||
*
|
||||
* Given a registered plane, return the index of that CRTC within a DRM
|
||||
* device's list of planes.
|
||||
*/
|
||||
unsigned int drm_plane_index(struct drm_plane *plane)
|
||||
{
|
||||
unsigned int index = 0;
|
||||
struct drm_plane *tmp;
|
||||
|
||||
drm_for_each_plane(tmp, plane->dev) {
|
||||
if (tmp == plane)
|
||||
return index;
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
BUG();
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_index);
|
||||
|
||||
/**
|
||||
* drm_plane_from_index - find the registered plane at an index
|
||||
* @dev: DRM device
|
||||
|
@ -1425,13 +1371,11 @@ struct drm_plane *
|
|||
drm_plane_from_index(struct drm_device *dev, int idx)
|
||||
{
|
||||
struct drm_plane *plane;
|
||||
unsigned int i = 0;
|
||||
|
||||
drm_for_each_plane(plane, dev) {
|
||||
if (i == idx)
|
||||
drm_for_each_plane(plane, dev)
|
||||
if (idx == plane->index)
|
||||
return plane;
|
||||
i++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_plane_from_index);
|
||||
|
@ -5227,7 +5171,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
|
||||
ret = crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
|
||||
|
||||
out:
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_gem_cma_helper.h>
|
||||
#include <drm/drm_fb_cma_helper.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#define DEFAULT_FBDEFIO_DELAY_MS 50
|
||||
|
@ -52,7 +53,7 @@ struct drm_fbdev_cma {
|
|||
* will be set up automatically. dirty() is called by
|
||||
* drm_fb_helper_deferred_io() in process context (struct delayed_work).
|
||||
*
|
||||
* Example fbdev deferred io code:
|
||||
* Example fbdev deferred io code::
|
||||
*
|
||||
* static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb,
|
||||
* struct drm_file *file_priv,
|
||||
|
@ -162,6 +163,10 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
|
|||
* drm_fb_cma_create_with_funcs() - helper function for the
|
||||
* &drm_mode_config_funcs ->fb_create
|
||||
* callback function
|
||||
* @dev: DRM device
|
||||
* @file_priv: drm file for the ioctl call
|
||||
* @mode_cmd: metadata from the userspace fb creation request
|
||||
* @funcs: vtable to be used for the new framebuffer object
|
||||
*
|
||||
* This can be used to set &drm_framebuffer_funcs for drivers that need the
|
||||
* dirty() callback. Use drm_fb_cma_create() if you don't need to change
|
||||
|
@ -223,6 +228,9 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs);
|
|||
|
||||
/**
|
||||
* drm_fb_cma_create() - &drm_mode_config_funcs ->fb_create callback function
|
||||
* @dev: DRM device
|
||||
* @file_priv: drm file for the ioctl call
|
||||
* @mode_cmd: metadata from the userspace fb creation request
|
||||
*
|
||||
* If your hardware has special alignment or pitch requirements these should be
|
||||
* checked before calling this function. Use drm_fb_cma_create_with_funcs() if
|
||||
|
@ -246,7 +254,7 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create);
|
|||
* This function will usually be called from the CRTC callback functions.
|
||||
*/
|
||||
struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
|
||||
unsigned int plane)
|
||||
unsigned int plane)
|
||||
{
|
||||
struct drm_fb_cma *fb_cma = to_fb_cma(fb);
|
||||
|
||||
|
@ -258,10 +266,6 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
|
|||
EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
/*
|
||||
* drm_fb_cma_describe() - Helper to dump information about a single
|
||||
* CMA framebuffer object
|
||||
*/
|
||||
static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
|
||||
{
|
||||
struct drm_fb_cma *fb_cma = to_fb_cma(fb);
|
||||
|
@ -279,7 +283,9 @@ static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
|
|||
|
||||
/**
|
||||
* drm_fb_cma_debugfs_show() - Helper to list CMA framebuffer objects
|
||||
* in debugfs.
|
||||
* in debugfs.
|
||||
* @m: output file
|
||||
* @arg: private data for the callback
|
||||
*/
|
||||
int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg)
|
||||
{
|
||||
|
@ -297,6 +303,12 @@ int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg)
|
|||
EXPORT_SYMBOL_GPL(drm_fb_cma_debugfs_show);
|
||||
#endif
|
||||
|
||||
static int drm_fb_cma_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
||||
{
|
||||
return dma_mmap_writecombine(info->device, vma, info->screen_base,
|
||||
info->fix.smem_start, info->fix.smem_len);
|
||||
}
|
||||
|
||||
static struct fb_ops drm_fbdev_cma_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_fillrect = drm_fb_helper_sys_fillrect,
|
||||
|
@ -307,6 +319,7 @@ static struct fb_ops drm_fbdev_cma_ops = {
|
|||
.fb_blank = drm_fb_helper_blank,
|
||||
.fb_pan_display = drm_fb_helper_pan_display,
|
||||
.fb_setcmap = drm_fb_helper_setcmap,
|
||||
.fb_mmap = drm_fb_cma_mmap,
|
||||
};
|
||||
|
||||
static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info,
|
||||
|
|
|
@ -227,7 +227,7 @@ static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
|
|||
g_base = r_base + crtc->gamma_size;
|
||||
b_base = g_base + crtc->gamma_size;
|
||||
|
||||
crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
|
||||
crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1971,7 +1971,18 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
|
|||
my_score++;
|
||||
|
||||
connector_funcs = connector->helper_private;
|
||||
encoder = connector_funcs->best_encoder(connector);
|
||||
|
||||
/*
|
||||
* If the DRM device implements atomic hooks and ->best_encoder() is
|
||||
* NULL we fallback to the default drm_atomic_helper_best_encoder()
|
||||
* helper.
|
||||
*/
|
||||
if (fb_helper->dev->mode_config.funcs->atomic_commit &&
|
||||
!connector_funcs->best_encoder)
|
||||
encoder = drm_atomic_helper_best_encoder(connector);
|
||||
else
|
||||
encoder = connector_funcs->best_encoder(connector);
|
||||
|
||||
if (!encoder)
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ DEFINE_MUTEX(drm_global_mutex);
|
|||
* specific implementations. For GEM-based drivers this is drm_gem_mmap().
|
||||
*
|
||||
* No other file operations are supported by the DRM userspace API. Overall the
|
||||
* following is an example #file_operations structure:
|
||||
* following is an example #file_operations structure::
|
||||
*
|
||||
* static const example_drm_fops = {
|
||||
* .owner = THIS_MODULE,
|
||||
|
@ -368,7 +368,7 @@ static void drm_events_release(struct drm_file *file_priv)
|
|||
/* Remove unconsumed events */
|
||||
list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
|
||||
list_del(&e->link);
|
||||
e->destroy(e);
|
||||
kfree(e);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
@ -636,7 +636,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer,
|
|||
}
|
||||
|
||||
ret += length;
|
||||
e->destroy(e);
|
||||
kfree(e);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&file_priv->event_read_lock);
|
||||
|
@ -713,9 +713,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev,
|
|||
list_add(&p->pending_link, &file_priv->pending_event_list);
|
||||
p->file_priv = file_priv;
|
||||
|
||||
/* we *could* pass this in as arg, but everyone uses kfree: */
|
||||
p->destroy = (void (*) (struct drm_pending_event *)) kfree;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_event_reserve_init_locked);
|
||||
|
@ -778,7 +775,7 @@ void drm_event_cancel_free(struct drm_device *dev,
|
|||
list_del(&p->pending_link);
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
p->destroy(p);
|
||||
kfree(p);
|
||||
}
|
||||
EXPORT_SYMBOL(drm_event_cancel_free);
|
||||
|
||||
|
@ -800,8 +797,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
|
|||
{
|
||||
assert_spin_locked(&dev->event_lock);
|
||||
|
||||
if (e->fence) {
|
||||
fence_signal(e->fence);
|
||||
fence_put(e->fence);
|
||||
}
|
||||
|
||||
if (!e->file_priv) {
|
||||
e->destroy(e);
|
||||
kfree(e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -787,7 +787,7 @@ EXPORT_SYMBOL(drm_gem_object_release);
|
|||
* @kref: kref of the object to free
|
||||
*
|
||||
* Called after the last reference to the object has been lost.
|
||||
* Must be called holding struct_ mutex
|
||||
* Must be called holding &drm_device->struct_mutex.
|
||||
*
|
||||
* Frees the object
|
||||
*/
|
||||
|
|
|
@ -89,11 +89,7 @@ static void store_vblank(struct drm_device *dev, unsigned int pipe,
|
|||
write_sequnlock(&vblank->seqlock);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_reset_vblank_timestamp - reset the last timestamp to the last vblank
|
||||
* @dev: DRM device
|
||||
* @pipe: index of CRTC for which to reset the timestamp
|
||||
*
|
||||
/*
|
||||
* Reset the stored timestamp for the current vblank count to correspond
|
||||
* to the last vblank occurred.
|
||||
*
|
||||
|
@ -137,11 +133,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe
|
|||
spin_unlock(&dev->vblank_time_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_update_vblank_count - update the master vblank counter
|
||||
* @dev: DRM device
|
||||
* @pipe: counter to update
|
||||
*
|
||||
/*
|
||||
* Call back into the driver to update the appropriate vblank counter
|
||||
* (specified by @pipe). Deal with wraparound, if it occurred, and
|
||||
* update the last read value so we can deal with wraparound on the next
|
||||
|
|
|
@ -982,6 +982,28 @@ int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
|
|||
}
|
||||
EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
|
||||
|
||||
/**
|
||||
* mipi_dsi_set_tear_scanline() - turn on the display module's Tearing Effect
|
||||
* output signal on the TE signal line when display module reaches line N
|
||||
* defined by STS[n:0].
|
||||
* @dsi: DSI peripheral device
|
||||
* @param: STS[10:0]
|
||||
* Return: 0 on success or a negative error code on failure
|
||||
*/
|
||||
int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi, u16 param)
|
||||
{
|
||||
u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, param >> 8,
|
||||
param & 0xff };
|
||||
ssize_t err;
|
||||
|
||||
err = mipi_dsi_generic_write(dsi, payload, sizeof(payload));
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(mipi_dsi_set_tear_scanline);
|
||||
|
||||
/**
|
||||
* mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
|
||||
* data used by the interface
|
||||
|
|
|
@ -544,6 +544,7 @@ EXPORT_SYMBOL(drm_gtf_mode_complex);
|
|||
*
|
||||
* This function is to create the modeline based on the GTF algorithm.
|
||||
* Generalized Timing Formula is derived from:
|
||||
*
|
||||
* GTF Spreadsheet by Andy Morrish (1/5/97)
|
||||
* available at http://www.vesa.org
|
||||
*
|
||||
|
@ -552,7 +553,8 @@ EXPORT_SYMBOL(drm_gtf_mode_complex);
|
|||
* I also refer to the function of fb_get_mode in the file of
|
||||
* drivers/video/fbmon.c
|
||||
*
|
||||
* Standard GTF parameters:
|
||||
* Standard GTF parameters::
|
||||
*
|
||||
* M = 600
|
||||
* C = 40
|
||||
* K = 128
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
*
|
||||
* For basic principles of &ww_mutex, see: Documentation/locking/ww-mutex-design.txt
|
||||
*
|
||||
* The basic usage pattern is to:
|
||||
* The basic usage pattern is to::
|
||||
*
|
||||
* drm_modeset_acquire_init(&ctx)
|
||||
* retry:
|
||||
|
|
|
@ -219,10 +219,12 @@ EXPORT_SYMBOL(drm_plane_helper_check_update);
|
|||
*
|
||||
* Note that we make some assumptions about hardware limitations that may not be
|
||||
* true for all hardware --
|
||||
* 1) Primary plane cannot be repositioned.
|
||||
* 2) Primary plane cannot be scaled.
|
||||
* 3) Primary plane must cover the entire CRTC.
|
||||
* 4) Subpixel positioning is not supported.
|
||||
*
|
||||
* 1. Primary plane cannot be repositioned.
|
||||
* 2. Primary plane cannot be scaled.
|
||||
* 3. Primary plane must cover the entire CRTC.
|
||||
* 4. Subpixel positioning is not supported.
|
||||
*
|
||||
* Drivers for hardware that don't have these restrictions can provide their
|
||||
* own implementation rather than using this helper.
|
||||
*
|
||||
|
|
|
@ -82,13 +82,30 @@ drm_mode_validate_flag(const struct drm_display_mode *mode,
|
|||
|
||||
static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_cmdline_mode *cmdline_mode;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
if (!connector->cmdline_mode.specified)
|
||||
cmdline_mode = &connector->cmdline_mode;
|
||||
if (!cmdline_mode->specified)
|
||||
return 0;
|
||||
|
||||
/* Only add a GTF mode if we find no matching probed modes */
|
||||
list_for_each_entry(mode, &connector->probed_modes, head) {
|
||||
if (mode->hdisplay != cmdline_mode->xres ||
|
||||
mode->vdisplay != cmdline_mode->yres)
|
||||
continue;
|
||||
|
||||
if (cmdline_mode->refresh_specified) {
|
||||
/* The probed mode's vrefresh is set until later */
|
||||
if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
|
||||
continue;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
mode = drm_mode_create_from_cmdline_mode(connector->dev,
|
||||
&connector->cmdline_mode);
|
||||
cmdline_mode);
|
||||
if (mode == NULL)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -127,6 +127,9 @@ EXPORT_SYMBOL(drm_vma_offset_manager_destroy);
|
|||
* used to implement weakly referenced lookups using kref_get_unless_zero().
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ::
|
||||
*
|
||||
* drm_vma_offset_lock_lookup(mgr);
|
||||
* node = drm_vma_offset_lookup_locked(mgr);
|
||||
* if (node)
|
||||
|
|
|
@ -125,7 +125,7 @@ struct etnaviv_gpu {
|
|||
u32 completed_fence;
|
||||
u32 retired_fence;
|
||||
wait_queue_head_t fence_event;
|
||||
unsigned int fence_context;
|
||||
u64 fence_context;
|
||||
spinlock_t fence_spinlock;
|
||||
|
||||
/* worker for handling active-list retiring: */
|
||||
|
|
|
@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
|
|||
{
|
||||
struct exynos_drm_private *priv = dev->dev_private;
|
||||
struct exynos_atomic_commit *commit;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int i, ret;
|
||||
|
||||
commit = kzalloc(sizeof(*commit), GFP_KERNEL);
|
||||
|
@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
|
|||
/* Wait until all affected CRTCs have completed previous commits and
|
||||
* mark them as pending.
|
||||
*/
|
||||
for (i = 0; i < dev->mode_config.num_crtc; ++i) {
|
||||
if (state->crtcs[i])
|
||||
commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
|
||||
}
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i)
|
||||
commit->crtcs |= drm_crtc_mask(crtc);
|
||||
|
||||
wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
|
||||
|
||||
|
|
|
@ -175,20 +175,21 @@ void gma_crtc_load_lut(struct drm_crtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
void gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
|
||||
u32 start, u32 size)
|
||||
int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
|
||||
u32 size)
|
||||
{
|
||||
struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
|
||||
int i;
|
||||
int end = (start + size > 256) ? 256 : start + size;
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
gma_crtc->lut_r[i] = red[i] >> 8;
|
||||
gma_crtc->lut_g[i] = green[i] >> 8;
|
||||
gma_crtc->lut_b[i] = blue[i] >> 8;
|
||||
}
|
||||
|
||||
gma_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -72,8 +72,8 @@ extern int gma_crtc_cursor_set(struct drm_crtc *crtc,
|
|||
uint32_t width, uint32_t height);
|
||||
extern int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
|
||||
extern void gma_crtc_load_lut(struct drm_crtc *crtc);
|
||||
extern void gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, u32 start, u32 size);
|
||||
extern int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, u32 size);
|
||||
extern void gma_crtc_dpms(struct drm_crtc *crtc, int mode);
|
||||
extern void gma_crtc_prepare(struct drm_crtc *crtc);
|
||||
extern void gma_crtc_commit(struct drm_crtc *crtc);
|
||||
|
|
|
@ -886,7 +886,7 @@ enum skl_disp_power_wells {
|
|||
* PLLs can be routed to any transcoder A/B/C.
|
||||
*
|
||||
* Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is
|
||||
* digital port D (CHV) or port A (BXT).
|
||||
* digital port D (CHV) or port A (BXT). ::
|
||||
*
|
||||
*
|
||||
* Dual channel PHY (VLV/CHV/BXT)
|
||||
|
|
|
@ -150,28 +150,28 @@ static int vgt_balloon_space(struct drm_mm *mm,
|
|||
* of its graphic space being zero. Yet there are some portions ballooned out(
|
||||
* the shadow part, which are marked as reserved by drm allocator). From the
|
||||
* host point of view, the graphic address space is partitioned by multiple
|
||||
* vGPUs in different VMs.
|
||||
* vGPUs in different VMs. ::
|
||||
*
|
||||
* vGPU1 view Host view
|
||||
* 0 ------> +-----------+ +-----------+
|
||||
* ^ |///////////| | vGPU3 |
|
||||
* | |///////////| +-----------+
|
||||
* | |///////////| | vGPU2 |
|
||||
* ^ |###########| | vGPU3 |
|
||||
* | |###########| +-----------+
|
||||
* | |###########| | vGPU2 |
|
||||
* | +-----------+ +-----------+
|
||||
* mappable GM | available | ==> | vGPU1 |
|
||||
* | +-----------+ +-----------+
|
||||
* | |///////////| | |
|
||||
* v |///////////| | Host |
|
||||
* | |###########| | |
|
||||
* v |###########| | Host |
|
||||
* +=======+===========+ +===========+
|
||||
* ^ |///////////| | vGPU3 |
|
||||
* | |///////////| +-----------+
|
||||
* | |///////////| | vGPU2 |
|
||||
* ^ |###########| | vGPU3 |
|
||||
* | |###########| +-----------+
|
||||
* | |###########| | vGPU2 |
|
||||
* | +-----------+ +-----------+
|
||||
* unmappable GM | available | ==> | vGPU1 |
|
||||
* | +-----------+ +-----------+
|
||||
* | |///////////| | |
|
||||
* | |///////////| | Host |
|
||||
* v |///////////| | |
|
||||
* | |###########| | |
|
||||
* | |###########| | Host |
|
||||
* v |###########| | |
|
||||
* total GM size ------> +-----------+ +-----------+
|
||||
*
|
||||
* Returns:
|
||||
|
|
|
@ -191,7 +191,7 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
|
|||
|
||||
/* plane scaler case: assign as a plane scaler */
|
||||
/* find the plane that set the bit as scaler_user */
|
||||
plane = drm_state->planes[i];
|
||||
plane = drm_state->planes[i].ptr;
|
||||
|
||||
/*
|
||||
* to enable/disable hq mode, add planes that are using scaler
|
||||
|
@ -223,7 +223,8 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
|
|||
continue;
|
||||
}
|
||||
|
||||
plane_state = to_intel_plane_state(drm_state->plane_states[i]);
|
||||
plane_state = intel_atomic_get_existing_plane_state(drm_state,
|
||||
intel_plane);
|
||||
scaler_id = &plane_state->scaler_id;
|
||||
}
|
||||
|
||||
|
|
|
@ -5214,14 +5214,14 @@ void intel_edp_drrs_flush(struct drm_device *dev,
|
|||
*
|
||||
* DRRS saves power by switching to low RR based on usage scenarios.
|
||||
*
|
||||
* eDP DRRS:-
|
||||
* The implementation is based on frontbuffer tracking implementation.
|
||||
* When there is a disturbance on the screen triggered by user activity or a
|
||||
* periodic system activity, DRRS is disabled (RR is changed to high RR).
|
||||
* When there is no movement on screen, after a timeout of 1 second, a switch
|
||||
* to low RR is made.
|
||||
* For integration with frontbuffer tracking code,
|
||||
* intel_edp_drrs_invalidate() and intel_edp_drrs_flush() are called.
|
||||
* The implementation is based on frontbuffer tracking implementation. When
|
||||
* there is a disturbance on the screen triggered by user activity or a periodic
|
||||
* system activity, DRRS is disabled (RR is changed to high RR). When there is
|
||||
* no movement on screen, after a timeout of 1 second, a switch to low RR is
|
||||
* made.
|
||||
*
|
||||
* For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
|
||||
* and intel_edp_drrs_flush() are called.
|
||||
*
|
||||
* DRRS can be further extended to support other internal panels and also
|
||||
* the scenario of video playback wherein RR is set based on the rate
|
||||
|
|
|
@ -374,8 +374,9 @@ static void intel_fbc_hw_deactivate(struct drm_i915_private *dev_priv)
|
|||
* @dev_priv: i915 device instance
|
||||
*
|
||||
* This function is used to verify the current state of FBC.
|
||||
*
|
||||
* FIXME: This should be tracked in the plane config eventually
|
||||
* instead of queried at runtime for most callers.
|
||||
* instead of queried at runtime for most callers.
|
||||
*/
|
||||
bool intel_fbc_is_active(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
|
|
|
@ -1352,19 +1352,20 @@ static void mga_crtc_commit(struct drm_crtc *crtc)
|
|||
* use this for 8-bit mode so can't perform smooth fades on deeper modes,
|
||||
* but it's a requirement that we provide the function
|
||||
*/
|
||||
static void mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t start, uint32_t size)
|
||||
static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
|
||||
int end = (start + size > MGAG200_LUT_SIZE) ? MGAG200_LUT_SIZE : start + size;
|
||||
int i;
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
mga_crtc->lut_r[i] = red[i] >> 8;
|
||||
mga_crtc->lut_g[i] = green[i] >> 8;
|
||||
mga_crtc->lut_b[i] = blue[i] >> 8;
|
||||
}
|
||||
mga_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Simple cleanup function */
|
||||
|
|
|
@ -106,31 +106,27 @@ static int mdp4_hw_init(struct msm_kms *kms)
|
|||
static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
|
||||
{
|
||||
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
|
||||
int i, ncrtcs = state->dev->mode_config.num_crtc;
|
||||
int i;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
mdp4_enable(mdp4_kms);
|
||||
|
||||
/* see 119ecb7fd */
|
||||
for (i = 0; i < ncrtcs; i++) {
|
||||
struct drm_crtc *crtc = state->crtcs[i];
|
||||
if (!crtc)
|
||||
continue;
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i)
|
||||
drm_crtc_vblank_get(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
|
||||
{
|
||||
struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
|
||||
int i, ncrtcs = state->dev->mode_config.num_crtc;
|
||||
int i;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
|
||||
/* see 119ecb7fd */
|
||||
for (i = 0; i < ncrtcs; i++) {
|
||||
struct drm_crtc *crtc = state->crtcs[i];
|
||||
if (!crtc)
|
||||
continue;
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i)
|
||||
drm_crtc_vblank_put(crtc);
|
||||
}
|
||||
|
||||
mdp4_disable(mdp4_kms);
|
||||
}
|
||||
|
|
|
@ -374,6 +374,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
struct drm_device *dev = crtc->dev;
|
||||
struct plane_state pstates[STAGE_MAX + 1];
|
||||
const struct mdp5_cfg_hw *hw_cfg;
|
||||
const struct drm_plane_state *pstate;
|
||||
int cnt = 0, i;
|
||||
|
||||
DBG("%s: check", mdp5_crtc->name);
|
||||
|
@ -382,20 +383,13 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
* and that we don't have conflicting mixer stages:
|
||||
*/
|
||||
hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
|
||||
drm_atomic_crtc_state_for_each_plane(plane, state) {
|
||||
struct drm_plane_state *pstate;
|
||||
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
|
||||
if (cnt >= (hw_cfg->lm.nb_stages)) {
|
||||
dev_err(dev->dev, "too many planes!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pstate = state->state->plane_states[drm_plane_index(plane)];
|
||||
|
||||
/* plane might not have changed, in which case take
|
||||
* current state:
|
||||
*/
|
||||
if (!pstate)
|
||||
pstate = plane->state;
|
||||
pstates[cnt].plane = plane;
|
||||
pstates[cnt].state = to_mdp5_plane_state(pstate);
|
||||
|
||||
|
|
|
@ -78,17 +78,11 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
|
|||
{
|
||||
int i;
|
||||
struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
|
||||
int nplanes = mdp5_kms->dev->mode_config.num_total_plane;
|
||||
|
||||
for (i = 0; i < nplanes; i++) {
|
||||
struct drm_plane *plane = state->planes[i];
|
||||
struct drm_plane_state *plane_state = state->plane_states[i];
|
||||
|
||||
if (!plane)
|
||||
continue;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *plane_state;
|
||||
|
||||
for_each_plane_in_state(state, plane, plane_state, i)
|
||||
mdp5_plane_complete_commit(plane, plane_state);
|
||||
}
|
||||
|
||||
mdp5_disable(mdp5_kms);
|
||||
}
|
||||
|
|
|
@ -84,17 +84,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
|
|||
struct drm_atomic_state *old_state)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct msm_drm_private *priv = old_state->dev->dev_private;
|
||||
struct msm_kms *kms = priv->kms;
|
||||
int ncrtcs = old_state->dev->mode_config.num_crtc;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ncrtcs; i++) {
|
||||
crtc = old_state->crtcs[i];
|
||||
|
||||
if (!crtc)
|
||||
continue;
|
||||
|
||||
for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
|
||||
if (!crtc->state->enable)
|
||||
continue;
|
||||
|
||||
|
@ -192,9 +187,11 @@ int msm_atomic_commit(struct drm_device *dev,
|
|||
struct drm_atomic_state *state, bool nonblock)
|
||||
{
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
int nplanes = dev->mode_config.num_total_plane;
|
||||
int ncrtcs = dev->mode_config.num_crtc;
|
||||
struct msm_commit *c;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *plane_state;
|
||||
int i, ret;
|
||||
|
||||
ret = drm_atomic_helper_prepare_planes(dev, state);
|
||||
|
@ -210,28 +207,18 @@ int msm_atomic_commit(struct drm_device *dev,
|
|||
/*
|
||||
* Figure out what crtcs we have:
|
||||
*/
|
||||
for (i = 0; i < ncrtcs; i++) {
|
||||
struct drm_crtc *crtc = state->crtcs[i];
|
||||
if (!crtc)
|
||||
continue;
|
||||
c->crtc_mask |= (1 << drm_crtc_index(crtc));
|
||||
}
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i)
|
||||
c->crtc_mask |= drm_crtc_mask(crtc);
|
||||
|
||||
/*
|
||||
* Figure out what fence to wait for:
|
||||
*/
|
||||
for (i = 0; i < nplanes; i++) {
|
||||
struct drm_plane *plane = state->planes[i];
|
||||
struct drm_plane_state *new_state = state->plane_states[i];
|
||||
|
||||
if (!plane)
|
||||
continue;
|
||||
|
||||
if ((plane->state->fb != new_state->fb) && new_state->fb) {
|
||||
struct drm_gem_object *obj = msm_framebuffer_bo(new_state->fb, 0);
|
||||
for_each_plane_in_state(state, plane, plane_state, i) {
|
||||
if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
|
||||
struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
|
||||
struct msm_gem_object *msm_obj = to_msm_bo(obj);
|
||||
|
||||
new_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
|
||||
plane_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -785,14 +785,14 @@ nv_crtc_disable(struct drm_crtc *crtc)
|
|||
nouveau_bo_ref(NULL, &disp->image[nv_crtc->index]);
|
||||
}
|
||||
|
||||
static void
|
||||
nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
|
||||
static int
|
||||
nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
uint32_t size)
|
||||
{
|
||||
int end = (start + size > 256) ? 256 : start + size, i;
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
int i;
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
nv_crtc->lut.r[i] = r[i];
|
||||
nv_crtc->lut.g[i] = g[i];
|
||||
nv_crtc->lut.b[i] = b[i];
|
||||
|
@ -805,10 +805,12 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
|
|||
*/
|
||||
if (!nv_crtc->base.primary->fb) {
|
||||
nv_crtc->lut.depth = 0;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nv_crtc_gamma_load(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -57,7 +57,8 @@ struct nouveau_fence_priv {
|
|||
int (*context_new)(struct nouveau_channel *);
|
||||
void (*context_del)(struct nouveau_channel *);
|
||||
|
||||
u32 contexts, context_base;
|
||||
u32 contexts;
|
||||
u64 context_base;
|
||||
bool uevent;
|
||||
};
|
||||
|
||||
|
|
|
@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
|
|||
ntfy->p->base.event = &ntfy->p->e.base;
|
||||
ntfy->p->base.file_priv = f;
|
||||
ntfy->p->base.pid = current->pid;
|
||||
ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree;
|
||||
ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF;
|
||||
ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply;
|
||||
|
||||
|
|
|
@ -1346,21 +1346,22 @@ nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
uint32_t start, uint32_t size)
|
||||
uint32_t size)
|
||||
{
|
||||
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
|
||||
u32 end = min_t(u32, start + size, 256);
|
||||
u32 i;
|
||||
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
nv_crtc->lut.r[i] = r[i];
|
||||
nv_crtc->lut.g[i] = g[i];
|
||||
nv_crtc->lut.b[i] = b[i];
|
||||
}
|
||||
|
||||
nv50_crtc_lut_load(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
|
|||
{
|
||||
struct omap_drm_private *priv = dev->dev_private;
|
||||
struct omap_atomic_state_commit *commit;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
int i, ret;
|
||||
|
||||
ret = drm_atomic_helper_prepare_planes(dev, state);
|
||||
if (ret)
|
||||
|
@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
|
|||
/* Wait until all affected CRTCs have completed previous commits and
|
||||
* mark them as pending.
|
||||
*/
|
||||
for (i = 0; i < dev->mode_config.num_crtc; ++i) {
|
||||
if (state->crtcs[i])
|
||||
commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
|
||||
}
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i)
|
||||
commit->crtcs |= drm_crtc_mask(crtc);
|
||||
|
||||
wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
|
||||
|
||||
|
|
|
@ -221,7 +221,6 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
|
|||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct qxl_device *qdev = dev->dev_private;
|
||||
struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
|
||||
struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb);
|
||||
struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb);
|
||||
struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj);
|
||||
|
@ -252,14 +251,14 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
|
|||
qxl_draw_dirty_fb(qdev, qfb_src, bo, 0, 0,
|
||||
&norect, one_clip_rect, inc);
|
||||
|
||||
drm_vblank_get(dev, qcrtc->index);
|
||||
drm_crtc_vblank_get(crtc);
|
||||
|
||||
if (event) {
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
drm_send_vblank_event(dev, qcrtc->index, event);
|
||||
drm_crtc_send_vblank_event(crtc, event);
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
drm_vblank_put(dev, qcrtc->index);
|
||||
drm_crtc_vblank_put(crtc);
|
||||
|
||||
ret = qxl_bo_reserve(bo, false);
|
||||
if (!ret) {
|
||||
|
|
|
@ -131,10 +131,6 @@ static int qxlfb_create_pinned_object(struct qxl_fbdev *qfbdev,
|
|||
int ret;
|
||||
int aligned_size, size;
|
||||
int height = mode_cmd->height;
|
||||
int bpp;
|
||||
int depth;
|
||||
|
||||
drm_fb_get_bpp_depth(mode_cmd->pixel_format, &bpp, &depth);
|
||||
|
||||
size = mode_cmd->pitches[0] * height;
|
||||
aligned_size = ALIGN(size, PAGE_SIZE);
|
||||
|
|
|
@ -96,7 +96,7 @@ static long qxl_fence_wait(struct fence *fence, bool intr, signed long timeout)
|
|||
return 0;
|
||||
|
||||
if (have_drawable_releases && sc > 300) {
|
||||
FENCE_WARN(fence, "failed to wait on release %d "
|
||||
FENCE_WARN(fence, "failed to wait on release %llu "
|
||||
"after spincount %d\n",
|
||||
fence->context & ~0xf0000000, sc);
|
||||
goto signaled;
|
||||
|
|
|
@ -2386,7 +2386,7 @@ struct radeon_device {
|
|||
struct radeon_mman mman;
|
||||
struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS];
|
||||
wait_queue_head_t fence_queue;
|
||||
unsigned fence_context;
|
||||
u64 fence_context;
|
||||
struct mutex ring_lock;
|
||||
struct radeon_ring ring[RADEON_NUM_RINGS];
|
||||
bool ib_pool_ready;
|
||||
|
|
|
@ -231,19 +231,21 @@ void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
|
|||
*blue = radeon_crtc->lut_b[regno] << 6;
|
||||
}
|
||||
|
||||
static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t start, uint32_t size)
|
||||
static int radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
|
||||
u16 *blue, uint32_t size)
|
||||
{
|
||||
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
|
||||
int end = (start + size > 256) ? 256 : start + size, i;
|
||||
int i;
|
||||
|
||||
/* userspace palettes are always correct as is */
|
||||
for (i = start; i < end; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
radeon_crtc->lut_r[i] = red[i] >> 6;
|
||||
radeon_crtc->lut_g[i] = green[i] >> 6;
|
||||
radeon_crtc->lut_b[i] = blue[i] >> 6;
|
||||
}
|
||||
radeon_crtc_load_lut(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void radeon_crtc_destroy(struct drm_crtc *crtc)
|
||||
|
@ -381,7 +383,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
|
|||
|
||||
spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
|
||||
|
||||
drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id);
|
||||
drm_crtc_vblank_put(&radeon_crtc->base);
|
||||
radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
|
||||
queue_work(radeon_crtc->flip_queue, &work->unpin_work);
|
||||
}
|
||||
|
@ -598,7 +600,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
|
|||
}
|
||||
work->base = base;
|
||||
|
||||
r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id);
|
||||
r = drm_crtc_vblank_get(crtc);
|
||||
if (r) {
|
||||
DRM_ERROR("failed to get vblank before flip\n");
|
||||
goto pflip_cleanup;
|
||||
|
@ -625,7 +627,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
|
|||
return 0;
|
||||
|
||||
vblank_cleanup:
|
||||
drm_vblank_put(crtc->dev, radeon_crtc->crtc_id);
|
||||
drm_crtc_vblank_put(&radeon_crtc->base);
|
||||
|
||||
pflip_cleanup:
|
||||
if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) {
|
||||
|
@ -688,6 +690,7 @@ radeon_crtc_set_config(struct drm_mode_set *set)
|
|||
pm_runtime_put_autosuspend(dev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs radeon_crtc_funcs = {
|
||||
.cursor_set2 = radeon_crtc_cursor_set2,
|
||||
.cursor_move = radeon_crtc_cursor_move,
|
||||
|
|
|
@ -246,6 +246,7 @@ static void radeon_set_power_state(struct radeon_device *rdev)
|
|||
|
||||
static void radeon_pm_set_clocks(struct radeon_device *rdev)
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
int i, r;
|
||||
|
||||
/* no need to take locks, etc. if nothing's going to change */
|
||||
|
@ -274,26 +275,30 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
|
|||
radeon_unmap_vram_bos(rdev);
|
||||
|
||||
if (rdev->irq.installed) {
|
||||
for (i = 0; i < rdev->num_crtc; i++) {
|
||||
i = 0;
|
||||
drm_for_each_crtc(crtc, rdev->ddev) {
|
||||
if (rdev->pm.active_crtcs & (1 << i)) {
|
||||
/* This can fail if a modeset is in progress */
|
||||
if (drm_vblank_get(rdev->ddev, i) == 0)
|
||||
if (drm_crtc_vblank_get(crtc) == 0)
|
||||
rdev->pm.req_vblank |= (1 << i);
|
||||
else
|
||||
DRM_DEBUG_DRIVER("crtc %d no vblank, can glitch\n",
|
||||
i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
radeon_set_power_state(rdev);
|
||||
|
||||
if (rdev->irq.installed) {
|
||||
for (i = 0; i < rdev->num_crtc; i++) {
|
||||
i = 0;
|
||||
drm_for_each_crtc(crtc, rdev->ddev) {
|
||||
if (rdev->pm.req_vblank & (1 << i)) {
|
||||
rdev->pm.req_vblank &= ~(1 << i);
|
||||
drm_vblank_put(rdev->ddev, i);
|
||||
drm_crtc_vblank_put(crtc);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
|
|||
{
|
||||
struct rcar_du_device *rcdu = dev->dev_private;
|
||||
struct rcar_du_commit *commit;
|
||||
struct drm_crtc *crtc;
|
||||
struct drm_crtc_state *crtc_state;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
|
@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
|
|||
/* Wait until all affected CRTCs have completed previous commits and
|
||||
* mark them as pending.
|
||||
*/
|
||||
for (i = 0; i < dev->mode_config.num_crtc; ++i) {
|
||||
if (state->crtcs[i])
|
||||
commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
|
||||
}
|
||||
for_each_crtc_in_state(state, crtc, crtc_state, i)
|
||||
commit->crtcs |= drm_crtc_mask(crtc);
|
||||
|
||||
spin_lock(&rcdu->commit.wait.lock);
|
||||
ret = wait_event_interruptible_locked(rcdu->commit.wait,
|
||||
|
|
|
@ -140,18 +140,17 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
|
|||
bool needs_realloc = false;
|
||||
unsigned int groups = 0;
|
||||
unsigned int i;
|
||||
struct drm_plane *drm_plane;
|
||||
struct drm_plane_state *drm_plane_state;
|
||||
|
||||
/* Check if hardware planes need to be reallocated. */
|
||||
for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
|
||||
for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
|
||||
struct rcar_du_plane_state *plane_state;
|
||||
struct rcar_du_plane *plane;
|
||||
unsigned int index;
|
||||
|
||||
if (!state->planes[i])
|
||||
continue;
|
||||
|
||||
plane = to_rcar_plane(state->planes[i]);
|
||||
plane_state = to_rcar_plane_state(state->plane_states[i]);
|
||||
plane = to_rcar_plane(drm_plane);
|
||||
plane_state = to_rcar_plane_state(drm_plane_state);
|
||||
|
||||
dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
|
||||
plane->group->index, plane - plane->group->planes);
|
||||
|
@ -247,18 +246,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
|
|||
}
|
||||
|
||||
/* Reallocate hardware planes for each plane that needs it. */
|
||||
for (i = 0; i < dev->mode_config.num_total_plane; ++i) {
|
||||
for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
|
||||
struct rcar_du_plane_state *plane_state;
|
||||
struct rcar_du_plane *plane;
|
||||
unsigned int crtc_planes;
|
||||
unsigned int free;
|
||||
int idx;
|
||||
|
||||
if (!state->planes[i])
|
||||
continue;
|
||||
|
||||
plane = to_rcar_plane(state->planes[i]);
|
||||
plane_state = to_rcar_plane_state(state->plane_states[i]);
|
||||
plane = to_rcar_plane(drm_plane);
|
||||
plane_state = to_rcar_plane_state(drm_plane_state);
|
||||
|
||||
dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
|
||||
plane->group->index, plane - plane->group->planes);
|
||||
|
|
|
@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
|
|||
if (e && e->base.file_priv == file_priv) {
|
||||
vop->event = NULL;
|
||||
|
||||
e->base.destroy(&e->base);
|
||||
kfree(&e->base);
|
||||
file_priv->event_space += sizeof(e->event);
|
||||
}
|
||||
spin_unlock_irqrestore(&drm->event_lock, flags);
|
||||
|
|
|
@ -441,7 +441,7 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
|
|||
scrtc->event = NULL;
|
||||
if (event) {
|
||||
drm_crtc_send_vblank_event(&scrtc->crtc, event);
|
||||
drm_vblank_put(dev, 0);
|
||||
drm_crtc_vblank_put(&scrtc->crtc);
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
}
|
||||
|
@ -467,7 +467,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
|
|||
|
||||
if (event) {
|
||||
event->pipe = 0;
|
||||
drm_vblank_get(dev, 0);
|
||||
drm_crtc_vblank_get(&scrtc->crtc);
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
scrtc->event = event;
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
|
|
|
@ -376,7 +376,7 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc,
|
|||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
if (event)
|
||||
drm_send_vblank_event(dev, 0, event);
|
||||
drm_crtc_send_vblank_event(crtc, event);
|
||||
spin_unlock_irqrestore(&dev->event_lock, flags);
|
||||
crtc->primary->fb = fb;
|
||||
|
||||
|
|
|
@ -175,20 +175,22 @@ vc4_crtc_lut_load(struct drm_crtc *crtc)
|
|||
HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
vc4_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
uint32_t start, uint32_t size)
|
||||
uint32_t size)
|
||||
{
|
||||
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
|
||||
u32 i;
|
||||
|
||||
for (i = start; i < start + size; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
vc4_crtc->lut_r[i] = r[i] >> 8;
|
||||
vc4_crtc->lut_g[i] = g[i] >> 8;
|
||||
vc4_crtc->lut_b[i] = b[i] >> 8;
|
||||
}
|
||||
|
||||
vc4_crtc_lut_load(crtc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 vc4_get_fifo_full_level(u32 format)
|
||||
|
@ -395,6 +397,7 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
||||
struct drm_plane *plane;
|
||||
unsigned long flags;
|
||||
const struct drm_plane_state *plane_state;
|
||||
u32 dlist_count = 0;
|
||||
int ret;
|
||||
|
||||
|
@ -404,18 +407,8 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
if (hweight32(state->connector_mask) > 1)
|
||||
return -EINVAL;
|
||||
|
||||
drm_atomic_crtc_state_for_each_plane(plane, state) {
|
||||
struct drm_plane_state *plane_state =
|
||||
state->state->plane_states[drm_plane_index(plane)];
|
||||
|
||||
/* plane might not have changed, in which case take
|
||||
* current state:
|
||||
*/
|
||||
if (!plane_state)
|
||||
plane_state = plane->state;
|
||||
|
||||
drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state)
|
||||
dlist_count += vc4_plane_dlist_size(plane_state);
|
||||
}
|
||||
|
||||
dlist_count++; /* Account for SCALER_CTL0_END. */
|
||||
|
||||
|
|
|
@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
|
|||
struct drm_plane *vc4_plane_init(struct drm_device *dev,
|
||||
enum drm_plane_type type);
|
||||
u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
|
||||
u32 vc4_plane_dlist_size(struct drm_plane_state *state);
|
||||
u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
|
||||
void vc4_plane_async_set_fb(struct drm_plane *plane,
|
||||
struct drm_framebuffer *fb);
|
||||
|
||||
|
|
|
@ -111,6 +111,8 @@ static int vc4_atomic_commit(struct drm_device *dev,
|
|||
int i;
|
||||
uint64_t wait_seqno = 0;
|
||||
struct vc4_commit *c;
|
||||
struct drm_plane *plane;
|
||||
struct drm_plane_state *new_state;
|
||||
|
||||
c = commit_init(state);
|
||||
if (!c)
|
||||
|
@ -130,13 +132,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < dev->mode_config.num_total_plane; i++) {
|
||||
struct drm_plane *plane = state->planes[i];
|
||||
struct drm_plane_state *new_state = state->plane_states[i];
|
||||
|
||||
if (!plane)
|
||||
continue;
|
||||
|
||||
for_each_plane_in_state(state, plane, new_state, i) {
|
||||
if ((plane->state->fb != new_state->fb) && new_state->fb) {
|
||||
struct drm_gem_cma_object *cma_bo =
|
||||
drm_fb_cma_get_gem_obj(new_state->fb, 0);
|
||||
|
|
|
@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
|
|||
return vc4_state->dlist_count;
|
||||
}
|
||||
|
||||
u32 vc4_plane_dlist_size(struct drm_plane_state *state)
|
||||
u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
|
||||
{
|
||||
struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
|
||||
const struct vc4_plane_state *vc4_state =
|
||||
container_of(state, typeof(*vc4_state), base);
|
||||
|
||||
return vc4_state->dlist_count;
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ static int virtio_gpu_page_flip(struct drm_crtc *crtc,
|
|||
|
||||
if (event) {
|
||||
spin_lock_irqsave(&crtc->dev->event_lock, irqflags);
|
||||
drm_send_vblank_event(crtc->dev, -1, event);
|
||||
drm_crtc_send_vblank_event(crtc, event);
|
||||
spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ struct vmw_fence_manager {
|
|||
bool goal_irq_on; /* Protected by @goal_irq_mutex */
|
||||
bool seqno_valid; /* Protected by @lock, and may not be set to true
|
||||
without the @goal_irq_mutex held. */
|
||||
unsigned ctx;
|
||||
u64 ctx;
|
||||
};
|
||||
|
||||
struct vmw_user_fence {
|
||||
|
|
|
@ -1404,9 +1404,9 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
|
||||
u16 *r, u16 *g, u16 *b,
|
||||
uint32_t start, uint32_t size)
|
||||
int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
|
||||
u16 *r, u16 *g, u16 *b,
|
||||
uint32_t size)
|
||||
{
|
||||
struct vmw_private *dev_priv = vmw_priv(crtc->dev);
|
||||
int i;
|
||||
|
@ -1418,6 +1418,8 @@ void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
|
|||
vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
|
||||
vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
|
||||
|
|
|
@ -195,9 +195,9 @@ struct vmw_display_unit {
|
|||
void vmw_du_cleanup(struct vmw_display_unit *du);
|
||||
void vmw_du_crtc_save(struct drm_crtc *crtc);
|
||||
void vmw_du_crtc_restore(struct drm_crtc *crtc);
|
||||
void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
|
||||
int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
|
||||
u16 *r, u16 *g, u16 *b,
|
||||
uint32_t start, uint32_t size);
|
||||
uint32_t size);
|
||||
int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
|
||||
uint32_t handle, uint32_t width, uint32_t height,
|
||||
int32_t hot_x, int32_t hot_y);
|
||||
|
|
|
@ -68,7 +68,8 @@ struct sync_timeline {
|
|||
|
||||
/* protected by child_list_lock */
|
||||
bool destroyed;
|
||||
int context, value;
|
||||
u64 context;
|
||||
int value;
|
||||
|
||||
struct list_head child_list_head;
|
||||
spinlock_t child_list_lock;
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/fence.h>
|
||||
|
||||
#include <asm/mman.h>
|
||||
#include <asm/pgalloc.h>
|
||||
|
@ -283,12 +284,12 @@ struct drm_ioctl_desc {
|
|||
/* Event queued up for userspace to read */
|
||||
struct drm_pending_event {
|
||||
struct drm_event *event;
|
||||
struct fence *fence;
|
||||
struct list_head link;
|
||||
struct list_head pending_link;
|
||||
struct drm_file *file_priv;
|
||||
pid_t pid; /* pid of requester, no guarantee it's valid by the time
|
||||
we deliver the event, for tracing only */
|
||||
void (*destroy)(struct drm_pending_event *event);
|
||||
};
|
||||
|
||||
/* initial implementaton using a linked list - todo hashtab */
|
||||
|
@ -430,7 +431,7 @@ struct drm_driver {
|
|||
*
|
||||
* Driver callback for fetching a raw hardware vblank counter for @crtc.
|
||||
* If a device doesn't have a hardware counter, the driver can simply
|
||||
* return the value of drm_vblank_count. The DRM core will account for
|
||||
* use drm_vblank_no_hw_counter() function. The DRM core will account for
|
||||
* missed vblank events while interrupts where disabled based on system
|
||||
* timestamps.
|
||||
*
|
||||
|
@ -448,8 +449,8 @@ struct drm_driver {
|
|||
* @pipe: which irq to enable
|
||||
*
|
||||
* Enable vblank interrupts for @crtc. If the device doesn't have
|
||||
* a hardware vblank counter, this routine should be a no-op, since
|
||||
* interrupts will have to stay on to keep the count accurate.
|
||||
* a hardware vblank counter, the driver should use the
|
||||
* drm_vblank_no_hw_counter() function that keeps a virtual counter.
|
||||
*
|
||||
* RETURNS
|
||||
* Zero on success, appropriate errno if the given @crtc's vblank
|
||||
|
@ -463,8 +464,8 @@ struct drm_driver {
|
|||
* @pipe: which irq to enable
|
||||
*
|
||||
* Disable vblank interrupts for @crtc. If the device doesn't have
|
||||
* a hardware vblank counter, this routine should be a no-op, since
|
||||
* interrupts will have to stay on to keep the count accurate.
|
||||
* a hardware vblank counter, the driver should use the
|
||||
* drm_vblank_no_hw_counter() function that keeps a virtual counter.
|
||||
*/
|
||||
void (*disable_vblank) (struct drm_device *dev, unsigned int pipe);
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ static inline struct drm_crtc_state *
|
|||
drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
|
||||
struct drm_crtc *crtc)
|
||||
{
|
||||
return state->crtc_states[drm_crtc_index(crtc)];
|
||||
return state->crtcs[drm_crtc_index(crtc)].state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,7 +86,7 @@ static inline struct drm_plane_state *
|
|||
drm_atomic_get_existing_plane_state(struct drm_atomic_state *state,
|
||||
struct drm_plane *plane)
|
||||
{
|
||||
return state->plane_states[drm_plane_index(plane)];
|
||||
return state->planes[drm_plane_index(plane)].state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +106,43 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
|
|||
if (index >= state->num_connector)
|
||||
return NULL;
|
||||
|
||||
return state->connector_states[index];
|
||||
return state->connectors[index].state;
|
||||
}
|
||||
|
||||
/**
|
||||
* __drm_atomic_get_current_plane_state - get current plane state
|
||||
* @state: global atomic state object
|
||||
* @plane: plane to grab
|
||||
*
|
||||
* This function returns the plane state for the given plane, either from
|
||||
* @state, or if the plane isn't part of the atomic state update, from @plane.
|
||||
* This is useful in atomic check callbacks, when drivers need to peek at, but
|
||||
* not change, state of other planes, since it avoids threading an error code
|
||||
* back up the call chain.
|
||||
*
|
||||
* WARNING:
|
||||
*
|
||||
* Note that this function is in general unsafe since it doesn't check for the
|
||||
* required locking for access state structures. Drivers must ensure that it is
|
||||
* safe to access the returned state structure through other means. One common
|
||||
* example is when planes are fixed to a single CRTC, and the driver knows that
|
||||
* the CRTC lock is held already. In that case holding the CRTC lock gives a
|
||||
* read-lock on all planes connected to that CRTC. But if planes can be
|
||||
* reassigned things get more tricky. In that case it's better to use
|
||||
* drm_atomic_get_plane_state and wire up full error handling.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Read-only pointer to the current plane state.
|
||||
*/
|
||||
static inline const struct drm_plane_state *
|
||||
__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
|
||||
struct drm_plane *plane)
|
||||
{
|
||||
if (state->planes[drm_plane_index(plane)].state)
|
||||
return state->planes[drm_plane_index(plane)].state;
|
||||
|
||||
return plane->state;
|
||||
}
|
||||
|
||||
int __must_check
|
||||
|
@ -139,27 +175,27 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
|
|||
int __must_check drm_atomic_commit(struct drm_atomic_state *state);
|
||||
int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
|
||||
|
||||
#define for_each_connector_in_state(state, connector, connector_state, __i) \
|
||||
#define for_each_connector_in_state(__state, connector, connector_state, __i) \
|
||||
for ((__i) = 0; \
|
||||
(__i) < (state)->num_connector && \
|
||||
((connector) = (state)->connectors[__i], \
|
||||
(connector_state) = (state)->connector_states[__i], 1); \
|
||||
(__i) < (__state)->num_connector && \
|
||||
((connector) = (__state)->connectors[__i].ptr, \
|
||||
(connector_state) = (__state)->connectors[__i].state, 1); \
|
||||
(__i)++) \
|
||||
for_each_if (connector)
|
||||
|
||||
#define for_each_crtc_in_state(state, crtc, crtc_state, __i) \
|
||||
#define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \
|
||||
for ((__i) = 0; \
|
||||
(__i) < (state)->dev->mode_config.num_crtc && \
|
||||
((crtc) = (state)->crtcs[__i], \
|
||||
(crtc_state) = (state)->crtc_states[__i], 1); \
|
||||
(__i) < (__state)->dev->mode_config.num_crtc && \
|
||||
((crtc) = (__state)->crtcs[__i].ptr, \
|
||||
(crtc_state) = (__state)->crtcs[__i].state, 1); \
|
||||
(__i)++) \
|
||||
for_each_if (crtc_state)
|
||||
|
||||
#define for_each_plane_in_state(state, plane, plane_state, __i) \
|
||||
#define for_each_plane_in_state(__state, plane, plane_state, __i) \
|
||||
for ((__i) = 0; \
|
||||
(__i) < (state)->dev->mode_config.num_total_plane && \
|
||||
((plane) = (state)->planes[__i], \
|
||||
(plane_state) = (state)->plane_states[__i], 1); \
|
||||
(__i) < (__state)->dev->mode_config.num_total_plane && \
|
||||
((plane) = (__state)->planes[__i].ptr, \
|
||||
(plane_state) = (__state)->planes[__i].state, 1); \
|
||||
(__i)++) \
|
||||
for_each_if (plane_state)
|
||||
static inline bool
|
||||
|
|
|
@ -147,9 +147,9 @@ void
|
|||
__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state);
|
||||
void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
|
||||
struct drm_connector_state *state);
|
||||
void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
||||
u16 *red, u16 *green, u16 *blue,
|
||||
uint32_t start, uint32_t size);
|
||||
int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
||||
u16 *red, u16 *green, u16 *blue,
|
||||
uint32_t size);
|
||||
|
||||
/**
|
||||
* drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
|
||||
|
@ -159,7 +159,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
|||
* This iterates over the current state, useful (for example) when applying
|
||||
* atomic state after it has been checked and swapped. To iterate over the
|
||||
* planes which *will* be attached (for ->atomic_check()) see
|
||||
* drm_crtc_for_each_pending_plane()
|
||||
* drm_crtc_for_each_pending_plane().
|
||||
*/
|
||||
#define drm_atomic_crtc_for_each_plane(plane, crtc) \
|
||||
drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask)
|
||||
|
@ -171,11 +171,31 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
|
|||
*
|
||||
* Similar to drm_crtc_for_each_plane(), but iterates the planes that will be
|
||||
* attached if the specified state is applied. Useful during (for example)
|
||||
* ->atomic_check() operations, to validate the incoming state
|
||||
* ->atomic_check() operations, to validate the incoming state.
|
||||
*/
|
||||
#define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \
|
||||
drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask)
|
||||
|
||||
/**
|
||||
* drm_crtc_atomic_state_for_each_plane_state - iterate over attached planes in new state
|
||||
* @plane: the loop cursor
|
||||
* @plane_state: loop cursor for the plane's state, must be const
|
||||
* @crtc_state: the incoming crtc-state
|
||||
*
|
||||
* Similar to drm_crtc_for_each_plane(), but iterates the planes that will be
|
||||
* attached if the specified state is applied. Useful during (for example)
|
||||
* ->atomic_check() operations, to validate the incoming state.
|
||||
*
|
||||
* Compared to just drm_atomic_crtc_state_for_each_plane() this also fills in a
|
||||
* const plane_state. This is useful when a driver just wants to peek at other
|
||||
* active planes on this crtc, but does not need to change it.
|
||||
*/
|
||||
#define drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) \
|
||||
drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) \
|
||||
for_each_if ((plane_state = \
|
||||
__drm_atomic_get_current_plane_state((crtc_state)->state, \
|
||||
plane)))
|
||||
|
||||
/*
|
||||
* drm_atomic_plane_disabling - check whether a plane is being disabled
|
||||
* @plane: plane object
|
||||
|
|
|
@ -314,6 +314,7 @@ struct drm_plane_helper_funcs;
|
|||
* update to ensure framebuffer cleanup isn't done too early
|
||||
* @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
|
||||
* @mode: current mode timings
|
||||
* @mode_blob: &drm_property_blob for @mode
|
||||
* @degamma_lut: Lookup table for converting framebuffer pixel data
|
||||
* before apply the conversion matrix
|
||||
* @ctm: Transformation matrix
|
||||
|
@ -478,8 +479,8 @@ struct drm_crtc_funcs {
|
|||
* going on, which should eventually be unified to just one set of
|
||||
* hooks.
|
||||
*/
|
||||
void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
uint32_t start, uint32_t size);
|
||||
int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
|
||||
uint32_t size);
|
||||
|
||||
/**
|
||||
* @destroy:
|
||||
|
@ -708,6 +709,7 @@ struct drm_crtc_funcs {
|
|||
* @dev: parent DRM device
|
||||
* @port: OF node used by drm_of_find_possible_crtcs()
|
||||
* @head: list management
|
||||
* @name: human readable name, can be overwritten by the driver
|
||||
* @mutex: per-CRTC locking
|
||||
* @base: base KMS object for ID tracking etc.
|
||||
* @primary: primary plane for this CRTC
|
||||
|
@ -738,12 +740,13 @@ struct drm_crtc {
|
|||
|
||||
char *name;
|
||||
|
||||
/*
|
||||
* crtc mutex
|
||||
/**
|
||||
* @mutex:
|
||||
*
|
||||
* This provides a read lock for the overall crtc state (mode, dpms
|
||||
* state, ...) and a write lock for everything which can be update
|
||||
* without a full modeset (fb, cursor data, ...)
|
||||
* without a full modeset (fb, cursor data, crtc properties ...). Full
|
||||
* modeset also need to grab dev->mode_config.connection_mutex.
|
||||
*/
|
||||
struct drm_modeset_lock mutex;
|
||||
|
||||
|
@ -753,6 +756,9 @@ struct drm_crtc {
|
|||
struct drm_plane *primary;
|
||||
struct drm_plane *cursor;
|
||||
|
||||
/* position inside the mode_config.list, can be used as a [] idx */
|
||||
unsigned index;
|
||||
|
||||
/* position of cursor plane on crtc */
|
||||
int cursor_x;
|
||||
int cursor_y;
|
||||
|
@ -1078,7 +1084,7 @@ struct drm_encoder_funcs {
|
|||
* @dev: parent DRM device
|
||||
* @head: list management
|
||||
* @base: base KMS object
|
||||
* @name: encoder name
|
||||
* @name: human readable name, can be overwritten by the driver
|
||||
* @encoder_type: one of the %DRM_MODE_ENCODER_<foo> types in drm_mode.h
|
||||
* @possible_crtcs: bitmask of potential CRTC bindings
|
||||
* @possible_clones: bitmask of potential sibling encoders for cloning
|
||||
|
@ -1097,6 +1103,10 @@ struct drm_encoder {
|
|||
struct drm_mode_object base;
|
||||
char *name;
|
||||
int encoder_type;
|
||||
|
||||
/* position inside the mode_config.list, can be used as a [] idx */
|
||||
unsigned index;
|
||||
|
||||
uint32_t possible_crtcs;
|
||||
uint32_t possible_clones;
|
||||
|
||||
|
@ -1124,7 +1134,8 @@ struct drm_encoder {
|
|||
* @attr: sysfs attributes
|
||||
* @head: list management
|
||||
* @base: base KMS object
|
||||
* @name: connector name
|
||||
* @name: human readable name, can be overwritten by the driver
|
||||
* @connector_id: compacted connector id useful indexing arrays
|
||||
* @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h
|
||||
* @connector_type_id: index into connector type enum
|
||||
* @interlace_allowed: can this connector handle interlaced modes?
|
||||
|
@ -1137,7 +1148,6 @@ struct drm_encoder {
|
|||
* @funcs: connector control functions
|
||||
* @edid_blob_ptr: DRM property containing EDID if present
|
||||
* @properties: property tracking for this connector
|
||||
* @path_blob_ptr: DRM blob property data for the DP MST path property
|
||||
* @polled: a %DRM_CONNECTOR_POLL_<foo> value for core driven polling
|
||||
* @dpms: current dpms state
|
||||
* @helper_private: mid-layer private data
|
||||
|
@ -1200,8 +1210,23 @@ struct drm_connector {
|
|||
struct drm_property_blob *edid_blob_ptr;
|
||||
struct drm_object_properties properties;
|
||||
|
||||
/**
|
||||
* @path_blob_ptr:
|
||||
*
|
||||
* DRM blob property data for the DP MST path property.
|
||||
*/
|
||||
struct drm_property_blob *path_blob_ptr;
|
||||
|
||||
/**
|
||||
* @tile_blob_ptr:
|
||||
*
|
||||
* DRM blob property data for the tile property (used mostly by DP MST).
|
||||
* This is meant for screens which are driven through separate display
|
||||
* pipelines represented by &drm_crtc, which might not be running with
|
||||
* genlocked clocks. For tiled panels which are genlocked, like
|
||||
* dual-link LVDS or dual-link DSI, the driver should try to not expose
|
||||
* the tiling and virtualize both &drm_crtc and &drm_plane if needed.
|
||||
*/
|
||||
struct drm_property_blob *tile_blob_ptr;
|
||||
|
||||
uint8_t polled; /* DRM_CONNECTOR_POLL_* */
|
||||
|
@ -1263,6 +1288,7 @@ struct drm_connector {
|
|||
* plane (in 16.16)
|
||||
* @src_w: width of visible portion of plane (in 16.16)
|
||||
* @src_h: height of visible portion of plane (in 16.16)
|
||||
* @rotation: rotation of the plane
|
||||
* @state: backpointer to global drm_atomic_state
|
||||
*/
|
||||
struct drm_plane_state {
|
||||
|
@ -1503,6 +1529,7 @@ enum drm_plane_type {
|
|||
* struct drm_plane - central DRM plane control structure
|
||||
* @dev: DRM device this plane belongs to
|
||||
* @head: for list management
|
||||
* @name: human readable name, can be overwritten by the driver
|
||||
* @base: base mode object
|
||||
* @possible_crtcs: pipes this plane can be bound to
|
||||
* @format_types: array of formats supported by this plane
|
||||
|
@ -1516,6 +1543,7 @@ enum drm_plane_type {
|
|||
* @properties: property tracking for this plane
|
||||
* @type: type of plane (overlay, primary, cursor)
|
||||
* @state: current atomic state for this plane
|
||||
* @helper_private: mid-layer private data
|
||||
*/
|
||||
struct drm_plane {
|
||||
struct drm_device *dev;
|
||||
|
@ -1523,6 +1551,13 @@ struct drm_plane {
|
|||
|
||||
char *name;
|
||||
|
||||
/**
|
||||
* @mutex:
|
||||
*
|
||||
* Protects modeset plane state, together with the mutex of &drm_crtc
|
||||
* this plane is linked to (when active, getting actived or getting
|
||||
* disabled).
|
||||
*/
|
||||
struct drm_modeset_lock mutex;
|
||||
|
||||
struct drm_mode_object base;
|
||||
|
@ -1543,6 +1578,9 @@ struct drm_plane {
|
|||
|
||||
enum drm_plane_type type;
|
||||
|
||||
/* position inside the mode_config.list, can be used as a [] idx */
|
||||
unsigned index;
|
||||
|
||||
const struct drm_plane_helper_funcs *helper_private;
|
||||
|
||||
struct drm_plane_state *state;
|
||||
|
@ -1693,19 +1731,31 @@ struct drm_bridge {
|
|||
void *driver_private;
|
||||
};
|
||||
|
||||
struct __drm_planes_state {
|
||||
struct drm_plane *ptr;
|
||||
struct drm_plane_state *state;
|
||||
};
|
||||
|
||||
struct __drm_crtcs_state {
|
||||
struct drm_crtc *ptr;
|
||||
struct drm_crtc_state *state;
|
||||
};
|
||||
|
||||
struct __drm_connnectors_state {
|
||||
struct drm_connector *ptr;
|
||||
struct drm_connector_state *state;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct drm_atomic_state - the global state object for atomic updates
|
||||
* @dev: parent DRM device
|
||||
* @allow_modeset: allow full modeset
|
||||
* @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
|
||||
* @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL.
|
||||
* @planes: pointer to array of plane pointers
|
||||
* @plane_states: pointer to array of plane states pointers
|
||||
* @planes: pointer to array of structures with per-plane data
|
||||
* @crtcs: pointer to array of CRTC pointers
|
||||
* @crtc_states: pointer to array of CRTC states pointers
|
||||
* @num_connector: size of the @connectors and @connector_states arrays
|
||||
* @connectors: pointer to array of connector pointers
|
||||
* @connector_states: pointer to array of connector states pointers
|
||||
* @connectors: pointer to array of structures with per-connector data
|
||||
* @acquire_ctx: acquire context for this atomic modeset state update
|
||||
*/
|
||||
struct drm_atomic_state {
|
||||
|
@ -1713,13 +1763,10 @@ struct drm_atomic_state {
|
|||
bool allow_modeset : 1;
|
||||
bool legacy_cursor_update : 1;
|
||||
bool legacy_set_config : 1;
|
||||
struct drm_plane **planes;
|
||||
struct drm_plane_state **plane_states;
|
||||
struct drm_crtc **crtcs;
|
||||
struct drm_crtc_state **crtc_states;
|
||||
struct __drm_planes_state *planes;
|
||||
struct __drm_crtcs_state *crtcs;
|
||||
int num_connector;
|
||||
struct drm_connector **connectors;
|
||||
struct drm_connector_state **connector_states;
|
||||
struct __drm_connnectors_state *connectors;
|
||||
|
||||
struct drm_modeset_acquire_ctx *acquire_ctx;
|
||||
};
|
||||
|
@ -2022,8 +2069,6 @@ struct drm_mode_config_funcs {
|
|||
* @connection_mutex: ww mutex protecting connector state and routing
|
||||
* @acquire_ctx: global implicit acquire context used by atomic drivers for
|
||||
* legacy IOCTLs
|
||||
* @idr_mutex: mutex for KMS ID allocation and management
|
||||
* @crtc_idr: main KMS ID tracking object
|
||||
* @fb_lock: mutex to protect fb state and lists
|
||||
* @num_fb: number of fbs available
|
||||
* @fb_list: list of framebuffers available
|
||||
|
@ -2045,6 +2090,7 @@ struct drm_mode_config_funcs {
|
|||
* @fb_base: base address of the framebuffer
|
||||
* @poll_enabled: track polling support for this device
|
||||
* @poll_running: track polling status for this device
|
||||
* @delayed_event: track delayed poll uevent deliver for this device
|
||||
* @output_poll_work: delayed work for polling in process context
|
||||
* @property_blob_list: list of all the blob property objects
|
||||
* @blob_lock: mutex for blob property allocation and management
|
||||
|
@ -2072,10 +2118,30 @@ struct drm_mode_config {
|
|||
struct mutex mutex; /* protects configuration (mode lists etc.) */
|
||||
struct drm_modeset_lock connection_mutex; /* protects connector->encoder and encoder->crtc links */
|
||||
struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */
|
||||
struct mutex idr_mutex; /* for IDR management */
|
||||
struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
|
||||
struct idr tile_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
|
||||
/* this is limited to one for now */
|
||||
|
||||
/**
|
||||
* @idr_mutex:
|
||||
*
|
||||
* Mutex for KMS ID allocation and management. Protects both @crtc_idr
|
||||
* and @tile_idr.
|
||||
*/
|
||||
struct mutex idr_mutex;
|
||||
|
||||
/**
|
||||
* @crtc_idr:
|
||||
*
|
||||
* Main KMS ID tracking object. Use this idr for all IDs, fb, crtc,
|
||||
* connector, modes - just makes life easier to have only one.
|
||||
*/
|
||||
struct idr crtc_idr;
|
||||
|
||||
/**
|
||||
* @tile_idr:
|
||||
*
|
||||
* Use this idr for allocating new IDs for tiled sinks like use in some
|
||||
* high-res DP MST screens.
|
||||
*/
|
||||
struct idr tile_idr;
|
||||
|
||||
struct mutex fb_lock; /* proctects global and per-file fb lists */
|
||||
int num_fb;
|
||||
|
@ -2177,7 +2243,11 @@ struct drm_mode_config {
|
|||
/* whether async page flip is supported or not */
|
||||
bool async_page_flip;
|
||||
|
||||
/* whether the driver supports fb modifiers */
|
||||
/**
|
||||
* @allow_fb_modifiers:
|
||||
*
|
||||
* Whether the driver supports fb modifiers in the ADDFB2.1 ioctl call.
|
||||
*/
|
||||
bool allow_fb_modifiers;
|
||||
|
||||
/* cursor size */
|
||||
|
@ -2230,7 +2300,18 @@ int drm_crtc_init_with_planes(struct drm_device *dev,
|
|||
const struct drm_crtc_funcs *funcs,
|
||||
const char *name, ...);
|
||||
extern void drm_crtc_cleanup(struct drm_crtc *crtc);
|
||||
extern unsigned int drm_crtc_index(struct drm_crtc *crtc);
|
||||
|
||||
/**
|
||||
* drm_crtc_index - find the index of a registered CRTC
|
||||
* @crtc: CRTC to find index for
|
||||
*
|
||||
* Given a registered CRTC, return the index of that CRTC within a DRM
|
||||
* device's list of CRTCs.
|
||||
*/
|
||||
static inline unsigned int drm_crtc_index(struct drm_crtc *crtc)
|
||||
{
|
||||
return crtc->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_crtc_mask - find the mask of a registered CRTC
|
||||
|
@ -2284,7 +2365,18 @@ int drm_encoder_init(struct drm_device *dev,
|
|||
struct drm_encoder *encoder,
|
||||
const struct drm_encoder_funcs *funcs,
|
||||
int encoder_type, const char *name, ...);
|
||||
extern unsigned int drm_encoder_index(struct drm_encoder *encoder);
|
||||
|
||||
/**
|
||||
* drm_encoder_index - find the index of a registered encoder
|
||||
* @encoder: encoder to find index for
|
||||
*
|
||||
* Given a registered encoder, return the index of that encoder within a DRM
|
||||
* device's list of encoders.
|
||||
*/
|
||||
static inline unsigned int drm_encoder_index(struct drm_encoder *encoder)
|
||||
{
|
||||
return encoder->index;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_encoder_crtc_ok - can a given crtc drive a given encoder?
|
||||
|
@ -2315,7 +2407,18 @@ extern int drm_plane_init(struct drm_device *dev,
|
|||
const uint32_t *formats, unsigned int format_count,
|
||||
bool is_primary);
|
||||
extern void drm_plane_cleanup(struct drm_plane *plane);
|
||||
extern unsigned int drm_plane_index(struct drm_plane *plane);
|
||||
|
||||
/**
|
||||
* drm_plane_index - find the index of a registered plane
|
||||
* @plane: plane to find index for
|
||||
*
|
||||
* Given a registered plane, return the index of that plane within a DRM
|
||||
* device's list of planes.
|
||||
*/
|
||||
static inline unsigned int drm_plane_index(struct drm_plane *plane)
|
||||
{
|
||||
return plane->index;
|
||||
}
|
||||
extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);
|
||||
extern void drm_plane_force_disable(struct drm_plane *plane);
|
||||
extern int drm_plane_check_pixel_format(const struct drm_plane *plane,
|
||||
|
|
|
@ -263,6 +263,7 @@ int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
|
|||
u16 end);
|
||||
int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
|
||||
u16 end);
|
||||
int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi, u16 param);
|
||||
int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
|
||||
int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
|
||||
enum mipi_dsi_dcs_tear_mode mode);
|
||||
|
|
|
@ -169,6 +169,8 @@ enum drm_mode_status {
|
|||
*
|
||||
* The horizontal and vertical timings are defined per the following diagram.
|
||||
*
|
||||
* ::
|
||||
*
|
||||
*
|
||||
* Active Front Sync Back
|
||||
* Region Porch Porch
|
||||
|
|
|
@ -736,6 +736,11 @@ struct drm_connector_helper_funcs {
|
|||
* inspect dynamic configuration state should instead use
|
||||
* @atomic_best_encoder.
|
||||
*
|
||||
* You can leave this function to NULL if the connector is only
|
||||
* attached to a single encoder and you are using the atomic helpers.
|
||||
* In this case, the core will call drm_atomic_helper_best_encoder()
|
||||
* for you.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Encoder that should be used for the given connector and connector
|
||||
|
@ -752,8 +757,9 @@ struct drm_connector_helper_funcs {
|
|||
* need to select the best encoder depending upon the desired
|
||||
* configuration and can't select it statically.
|
||||
*
|
||||
* This function is used by drm_atomic_helper_check_modeset() and either
|
||||
* this or @best_encoder is required.
|
||||
* This function is used by drm_atomic_helper_check_modeset().
|
||||
* If it is not implemented, the core will fallback to @best_encoder
|
||||
* (or drm_atomic_helper_best_encoder() if @best_encoder is NULL).
|
||||
*
|
||||
* NOTE:
|
||||
*
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* fence-array: aggregates fence 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.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_FENCE_ARRAY_H
|
||||
#define __LINUX_FENCE_ARRAY_H
|
||||
|
||||
#include <linux/fence.h>
|
||||
|
||||
/**
|
||||
* struct fence_array_cb - callback helper for fence array
|
||||
* @cb: fence callback structure for signaling
|
||||
* @array: reference to the parent fence array object
|
||||
*/
|
||||
struct fence_array_cb {
|
||||
struct fence_cb cb;
|
||||
struct fence_array *array;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct fence_array - fence to represent an array of fences
|
||||
* @base: fence base class
|
||||
* @lock: spinlock for fence handling
|
||||
* @num_fences: number of fences in the array
|
||||
* @num_pending: fences in the array still pending
|
||||
* @fences: array of the fences
|
||||
*/
|
||||
struct fence_array {
|
||||
struct fence base;
|
||||
|
||||
spinlock_t lock;
|
||||
unsigned num_fences;
|
||||
atomic_t num_pending;
|
||||
struct fence **fences;
|
||||
};
|
||||
|
||||
extern const struct fence_ops fence_array_ops;
|
||||
|
||||
/**
|
||||
* to_fence_array - cast a fence to a fence_array
|
||||
* @fence: fence to cast to a fence_array
|
||||
*
|
||||
* Returns NULL if the fence is not a fence_array,
|
||||
* or the fence_array otherwise.
|
||||
*/
|
||||
static inline struct fence_array *to_fence_array(struct fence *fence)
|
||||
{
|
||||
if (fence->ops != &fence_array_ops)
|
||||
return NULL;
|
||||
|
||||
return container_of(fence, struct fence_array, base);
|
||||
}
|
||||
|
||||
struct fence_array *fence_array_create(int num_fences, struct fence **fences,
|
||||
u64 context, unsigned seqno,
|
||||
bool signal_on_any);
|
||||
|
||||
#endif /* __LINUX_FENCE_ARRAY_H */
|
|
@ -77,7 +77,8 @@ struct fence {
|
|||
struct rcu_head rcu;
|
||||
struct list_head cb_list;
|
||||
spinlock_t *lock;
|
||||
unsigned context, seqno;
|
||||
u64 context;
|
||||
unsigned seqno;
|
||||
unsigned long flags;
|
||||
ktime_t timestamp;
|
||||
int status;
|
||||
|
@ -180,7 +181,7 @@ struct fence_ops {
|
|||
};
|
||||
|
||||
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);
|
||||
|
||||
void fence_release(struct kref *kref);
|
||||
void fence_free(struct fence *fence);
|
||||
|
@ -354,27 +355,27 @@ static inline signed long fence_wait(struct fence *fence, bool intr)
|
|||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
unsigned fence_context_alloc(unsigned num);
|
||||
u64 fence_context_alloc(unsigned num);
|
||||
|
||||
#define FENCE_TRACE(f, fmt, args...) \
|
||||
do { \
|
||||
struct fence *__ff = (f); \
|
||||
if (config_enabled(CONFIG_FENCE_TRACE)) \
|
||||
pr_info("f %u#%u: " fmt, \
|
||||
pr_info("f %llu#%u: " fmt, \
|
||||
__ff->context, __ff->seqno, ##args); \
|
||||
} while (0)
|
||||
|
||||
#define FENCE_WARN(f, fmt, args...) \
|
||||
do { \
|
||||
struct fence *__ff = (f); \
|
||||
pr_warn("f %u#%u: " fmt, __ff->context, __ff->seqno, \
|
||||
pr_warn("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
|
||||
##args); \
|
||||
} while (0)
|
||||
|
||||
#define FENCE_ERR(f, fmt, args...) \
|
||||
do { \
|
||||
struct fence *__ff = (f); \
|
||||
pr_err("f %u#%u: " fmt, __ff->context, __ff->seqno, \
|
||||
pr_err("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
|
||||
##args); \
|
||||
} while (0)
|
||||
|
||||
|
|
Loading…
Reference in New Issue