Merge tag 'topic/drm-misc-2016-11-10' of git://anongit.freedesktop.org/drm-intel into drm-next

- better atomic state debugging from Rob
- fence prep from gustavo
- sumits flushed out his backlog of pending dma-buf/fence patches from
  various people
- drm_mm leak debugging plus trying to appease Kconfig (Chris)
- a few misc things all over

* tag 'topic/drm-misc-2016-11-10' of git://anongit.freedesktop.org/drm-intel: (35 commits)
  drm: Make DRM_DEBUG_MM depend on STACKTRACE_SUPPORT
  drm/i915: Restrict DRM_DEBUG_MM automatic selection
  drm: Restrict stackdepot usage to builtin drm.ko
  drm/msm: module param to dump state on error irq
  drm/msm/mdp5: add atomic_print_state support
  drm/atomic: add debugfs file to dump out atomic state
  drm/atomic: add new drm_debug bit to dump atomic state
  drm: add helpers to go from plane state to drm_rect
  drm: add helper for printing to log or seq_file
  drm: helper macros to print composite types
  reservation: revert "wait only with non-zero timeout specified (v3)" v2
  drm/ttm: fix ttm_bo_wait
  dma-buf/fence: revert "don't wait when specified timeout is zero" (v2)
  dma-buf/fence: make timeout handling in fence_default_wait consistent (v2)
  drm/amdgpu: add the interface of waiting multiple fences (v4)
  dma-buf: return index of the first signaled fence (v2)
  MAINTAINERS: update Sync File Framework files
  dma-buf/sw_sync: put fence reference from the fence creation
  dma-buf/sw_sync: mark sync_timeline_create() static
  drm: Add stackdepot include for DRM_DEBUG_MM
  ...
This commit is contained in:
Dave Airlie 2016-11-11 09:28:44 +10:00
commit 3e91168a6a
78 changed files with 969 additions and 171 deletions

View file

@ -350,6 +350,23 @@ how the ioctl is allowed to be called.
.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
:export:
Misc Utilities
==============
Printer
-------
.. kernel-doc:: include/drm/drm_print.h
:doc: print
.. kernel-doc:: include/drm/drm_print.h
:internal:
.. kernel-doc:: include/drm/drm_print.h
:export:
Legacy Support Code
===================

View file

@ -3919,8 +3919,10 @@ R: Gustavo Padovan <gustavo@padovan.org>
S: Maintained
L: linux-media@vger.kernel.org
L: dri-devel@lists.freedesktop.org
F: drivers/dma-buf/sync_file.c
F: drivers/dma-buf/sync_*
F: drivers/dma-buf/sw_sync.c
F: include/linux/sync_file.h
F: include/uapi/linux/sync_file.h
F: Documentation/sync_file.txt
T: git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git

View file

@ -161,9 +161,6 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
if (WARN_ON(timeout < 0))
return -EINVAL;
if (timeout == 0)
return dma_fence_is_signaled(fence);
trace_dma_fence_wait_start(fence);
ret = fence->ops->wait(fence, intr, timeout);
trace_dma_fence_wait_end(fence);
@ -339,18 +336,20 @@ dma_fence_default_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
* @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
*
* Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
* remaining timeout in jiffies on success.
* remaining timeout in jiffies on success. If timeout is zero the value one is
* returned if the fence is already signaled for consistency with other
* functions taking a jiffies timeout.
*/
signed long
dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
{
struct default_wait_cb cb;
unsigned long flags;
signed long ret = timeout;
signed long ret = timeout ? timeout : 1;
bool was_set;
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return timeout;
return ret;
spin_lock_irqsave(fence->lock, flags);
@ -403,14 +402,18 @@ out:
EXPORT_SYMBOL(dma_fence_default_wait);
static bool
dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count)
dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count,
uint32_t *idx)
{
int i;
for (i = 0; i < count; ++i) {
struct dma_fence *fence = fences[i];
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
if (idx)
*idx = i;
return true;
}
}
return false;
}
@ -422,6 +425,8 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count)
* @count: [in] number of fences to wait on
* @intr: [in] if true, do an interruptible wait
* @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
* @idx: [out] the first signaled fence index, meaningful only on
* positive return
*
* Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if
* interrupted, 0 if the wait timed out, or the remaining timeout in jiffies
@ -433,7 +438,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count)
*/
signed long
dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
bool intr, signed long timeout)
bool intr, signed long timeout, uint32_t *idx)
{
struct default_wait_cb *cb;
signed long ret = timeout;
@ -444,8 +449,11 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
if (timeout == 0) {
for (i = 0; i < count; ++i)
if (dma_fence_is_signaled(fences[i]))
if (dma_fence_is_signaled(fences[i])) {
if (idx)
*idx = i;
return 1;
}
return 0;
}
@ -468,6 +476,8 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
if (dma_fence_add_callback(fence, &cb[i].base,
dma_fence_default_wait_cb)) {
/* This fence is already signaled */
if (idx)
*idx = i;
goto fence_rm_cb;
}
}
@ -478,7 +488,7 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
else
set_current_state(TASK_UNINTERRUPTIBLE);
if (dma_fence_test_signaled_any(fences, count))
if (dma_fence_test_signaled_any(fences, count, idx))
break;
ret = schedule_timeout(ret);

View file

@ -370,10 +370,7 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
{
struct dma_fence *fence;
unsigned seq, shared_count, i = 0;
long ret = timeout;
if (!timeout)
return reservation_object_test_signaled_rcu(obj, wait_all);
long ret = timeout ? timeout : 1;
retry:
fence = NULL;

View file

@ -84,7 +84,7 @@ static inline struct sync_pt *dma_fence_to_sync_pt(struct dma_fence *fence)
* Creates a new sync_timeline. Returns the sync_timeline object or NULL in
* case of error.
*/
struct sync_timeline *sync_timeline_create(const char *name)
static struct sync_timeline *sync_timeline_create(const char *name)
{
struct sync_timeline *obj;
@ -316,8 +316,8 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj,
}
sync_file = sync_file_create(&pt->base);
dma_fence_put(&pt->base);
if (!sync_file) {
dma_fence_put(&pt->base);
err = -ENOMEM;
goto err;
}

View file

@ -33,6 +33,20 @@ config DRM_DP_AUX_CHARDEV
read and write values to arbitrary DPCD registers on the DP aux
channel.
config DRM_DEBUG_MM
bool "Insert extra checks and debug info into the DRM range managers"
default n
depends on DRM=y
depends on STACKTRACE_SUPPORT
select STACKDEPOT
help
Enable allocation tracking of memory manager and leak detection on
shutdown.
Recommended for driver developers only.
If in doubt, say "N".
config DRM_KMS_HELPER
tristate
depends on DRM

View file

@ -15,7 +15,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
drm_modeset_lock.o drm_atomic.o drm_bridge.o \
drm_framebuffer.o drm_connector.o drm_blend.o \
drm_encoder.o drm_mode_object.o drm_property.o \
drm_plane.o drm_color_mgmt.o
drm_plane.o drm_color_mgmt.o drm_print.o
drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o

View file

@ -1212,6 +1212,8 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);
int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);
int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp);

View file

@ -1140,6 +1140,180 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
return 0;
}
/**
* amdgpu_cs_get_fence - helper to get fence from drm_amdgpu_fence
*
* @adev: amdgpu device
* @filp: file private
* @user: drm_amdgpu_fence copied from user space
*/
static struct dma_fence *amdgpu_cs_get_fence(struct amdgpu_device *adev,
struct drm_file *filp,
struct drm_amdgpu_fence *user)
{
struct amdgpu_ring *ring;
struct amdgpu_ctx *ctx;
struct dma_fence *fence;
int r;
r = amdgpu_cs_get_ring(adev, user->ip_type, user->ip_instance,
user->ring, &ring);
if (r)
return ERR_PTR(r);
ctx = amdgpu_ctx_get(filp->driver_priv, user->ctx_id);
if (ctx == NULL)
return ERR_PTR(-EINVAL);
fence = amdgpu_ctx_get_fence(ctx, ring, user->seq_no);
amdgpu_ctx_put(ctx);
return fence;
}
/**
* amdgpu_cs_wait_all_fence - wait on all fences to signal
*
* @adev: amdgpu device
* @filp: file private
* @wait: wait parameters
* @fences: array of drm_amdgpu_fence
*/
static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
struct drm_file *filp,
union drm_amdgpu_wait_fences *wait,
struct drm_amdgpu_fence *fences)
{
uint32_t fence_count = wait->in.fence_count;
unsigned int i;
long r = 1;
for (i = 0; i < fence_count; i++) {
struct dma_fence *fence;
unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns);
fence = amdgpu_cs_get_fence(adev, filp, &fences[i]);
if (IS_ERR(fence))
return PTR_ERR(fence);
else if (!fence)
continue;
r = dma_fence_wait_timeout(fence, true, timeout);
if (r < 0)
return r;
if (r == 0)
break;
}
memset(wait, 0, sizeof(*wait));
wait->out.status = (r > 0);
return 0;
}
/**
* amdgpu_cs_wait_any_fence - wait on any fence to signal
*
* @adev: amdgpu device
* @filp: file private
* @wait: wait parameters
* @fences: array of drm_amdgpu_fence
*/
static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev,
struct drm_file *filp,
union drm_amdgpu_wait_fences *wait,
struct drm_amdgpu_fence *fences)
{
unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns);
uint32_t fence_count = wait->in.fence_count;
uint32_t first = ~0;
struct dma_fence **array;
unsigned int i;
long r;
/* Prepare the fence array */
array = kcalloc(fence_count, sizeof(struct dma_fence *), GFP_KERNEL);
if (array == NULL)
return -ENOMEM;
for (i = 0; i < fence_count; i++) {
struct dma_fence *fence;
fence = amdgpu_cs_get_fence(adev, filp, &fences[i]);
if (IS_ERR(fence)) {
r = PTR_ERR(fence);
goto err_free_fence_array;
} else if (fence) {
array[i] = fence;
} else { /* NULL, the fence has been already signaled */
r = 1;
goto out;
}
}
r = dma_fence_wait_any_timeout(array, fence_count, true, timeout,
&first);
if (r < 0)
goto err_free_fence_array;
out:
memset(wait, 0, sizeof(*wait));
wait->out.status = (r > 0);
wait->out.first_signaled = first;
/* set return value 0 to indicate success */
r = 0;
err_free_fence_array:
for (i = 0; i < fence_count; i++)
dma_fence_put(array[i]);
kfree(array);
return r;
}
/**
* amdgpu_cs_wait_fences_ioctl - wait for multiple command submissions to finish
*
* @dev: drm device
* @data: data from userspace
* @filp: file private
*/
int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
struct drm_file *filp)
{
struct amdgpu_device *adev = dev->dev_private;
union drm_amdgpu_wait_fences *wait = data;
uint32_t fence_count = wait->in.fence_count;
struct drm_amdgpu_fence *fences_user;
struct drm_amdgpu_fence *fences;
int r;
/* Get the fences from userspace */
fences = kmalloc_array(fence_count, sizeof(struct drm_amdgpu_fence),
GFP_KERNEL);
if (fences == NULL)
return -ENOMEM;
fences_user = (void __user *)(unsigned long)(wait->in.fences);
if (copy_from_user(fences, fences_user,
sizeof(struct drm_amdgpu_fence) * fence_count)) {
r = -EFAULT;
goto err_free_fences;
}
if (wait->in.wait_all)
r = amdgpu_cs_wait_all_fences(adev, filp, wait, fences);
else
r = amdgpu_cs_wait_any_fence(adev, filp, wait, fences);
err_free_fences:
kfree(fences);
return r;
}
/**
* amdgpu_cs_find_bo_va - find bo_va for VM address
*

View file

@ -823,6 +823,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
DRM_IOCTL_DEF_DRV(AMDGPU_CS, amdgpu_cs_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_INFO, amdgpu_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_CS, amdgpu_cs_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_FENCES, amdgpu_cs_wait_fences_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),

View file

@ -361,7 +361,8 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
if (count) {
spin_unlock(&sa_manager->wq.lock);
t = dma_fence_wait_any_timeout(fences, count, false,
MAX_SCHEDULE_TIMEOUT);
MAX_SCHEDULE_TIMEOUT,
NULL);
for (i = 0; i < count; ++i)
dma_fence_put(fences[i]);

View file

@ -65,9 +65,7 @@ static const struct file_operations arcpgu_drm_ops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -268,9 +268,7 @@ static const struct file_operations fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = noop_llseek,

View file

@ -197,9 +197,7 @@ static const struct file_operations fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = noop_llseek,

View file

@ -188,9 +188,7 @@ static const struct file_operations ast_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = ast_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.read = drm_read,
};

View file

@ -749,9 +749,7 @@ static const struct file_operations fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -70,9 +70,7 @@ static const struct file_operations bochs_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -126,9 +126,7 @@ static const struct file_operations cirrus_driver_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = cirrus_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
};
static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM,

View file

@ -30,6 +30,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_mode.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_print.h>
#include "drm_crtc_internal.h"
@ -605,6 +606,28 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
return 0;
}
static void drm_atomic_crtc_print_state(struct drm_printer *p,
const struct drm_crtc_state *state)
{
struct drm_crtc *crtc = state->crtc;
drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
drm_printf(p, "\tenable=%d\n", state->enable);
drm_printf(p, "\tactive=%d\n", state->active);
drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
if (crtc->funcs->atomic_print_state)
crtc->funcs->atomic_print_state(p, state);
}
/**
* drm_atomic_get_plane_state - get plane state
* @state: global atomic state object
@ -881,6 +904,38 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
return 0;
}
static void drm_atomic_plane_print_state(struct drm_printer *p,
const struct drm_plane_state *state)
{
struct drm_plane *plane = state->plane;
struct drm_rect src = drm_plane_state_src(state);
struct drm_rect dest = drm_plane_state_dest(state);
drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
if (state->fb) {
struct drm_framebuffer *fb = state->fb;
int i, n = drm_format_num_planes(fb->pixel_format);
drm_printf(p, "\t\tformat=%s\n",
drm_get_format_name(fb->pixel_format));
drm_printf(p, "\t\tsize=%dx%d\n", fb->width, fb->height);
drm_printf(p, "\t\tlayers:\n");
for (i = 0; i < n; i++) {
drm_printf(p, "\t\t\tpitch[%d]=%u\n", i, fb->pitches[i]);
drm_printf(p, "\t\t\toffset[%d]=%u\n", i, fb->offsets[i]);
drm_printf(p, "\t\t\tmodifier[%d]=0x%llx\n", i, fb->modifier[i]);
}
}
drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
drm_printf(p, "\trotation=%x\n", state->rotation);
if (plane->funcs->atomic_print_state)
plane->funcs->atomic_print_state(p, state);
}
/**
* drm_atomic_get_connector_state - get connector state
* @state: global atomic state object
@ -996,6 +1051,18 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_atomic_connector_set_property);
static void drm_atomic_connector_print_state(struct drm_printer *p,
const struct drm_connector_state *state)
{
struct drm_connector *connector = state->connector;
drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
if (connector->funcs->atomic_print_state)
connector->funcs->atomic_print_state(p, state);
}
/**
* drm_atomic_connector_get_property - get property value from connector state
* @connector: the drm connector to set a property on
@ -1149,6 +1216,36 @@ drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
}
EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
/**
* drm_atomic_set_fence_for_plane - set fence for plane
* @plane_state: atomic state object for the plane
* @fence: dma_fence to use for the plane
*
* Helper to setup the plane_state fence in case it is not set yet.
* By using this drivers doesn't need to worry if the user choose
* implicit or explicit fencing.
*
* This function will not set the fence to the state if it was set
* via explicit fencing interfaces on the atomic ioctl. It will
* all drope the reference to the fence as we not storing it
* anywhere.
*
* Otherwise, if plane_state->fence is not set this function we
* just set it with the received implict fence.
*/
void
drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state,
struct dma_fence *fence)
{
if (plane_state->fence) {
dma_fence_put(fence);
return;
}
plane_state->fence = fence;
}
EXPORT_SYMBOL(drm_atomic_set_fence_for_plane);
/**
* drm_atomic_set_crtc_for_connector - set crtc for connector
* @conn_state: atomic state object for the connector
@ -1460,6 +1557,92 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
}
EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
static void drm_atomic_print_state(const struct drm_atomic_state *state)
{
struct drm_printer p = drm_info_printer(state->dev->dev);
struct drm_plane *plane;
struct drm_plane_state *plane_state;
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
struct drm_connector *connector;
struct drm_connector_state *connector_state;
int i;
DRM_DEBUG_ATOMIC("checking %p\n", state);
for_each_plane_in_state(state, plane, plane_state, i)
drm_atomic_plane_print_state(&p, plane_state);
for_each_crtc_in_state(state, crtc, crtc_state, i)
drm_atomic_crtc_print_state(&p, crtc_state);
for_each_connector_in_state(state, connector, connector_state, i)
drm_atomic_connector_print_state(&p, connector_state);
}
/**
* drm_state_dump - dump entire device atomic state
* @dev: the drm device
* @p: where to print the state to
*
* Just for debugging. Drivers might want an option to dump state
* to dmesg in case of error irq's. (Hint, you probably want to
* ratelimit this!)
*
* The caller must drm_modeset_lock_all(), or if this is called
* from error irq handler, it should not be enabled by default.
* (Ie. if you are debugging errors you might not care that this
* is racey. But calling this without all modeset locks held is
* not inherently safe.)
*/
void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
{
struct drm_mode_config *config = &dev->mode_config;
struct drm_plane *plane;
struct drm_crtc *crtc;
struct drm_connector *connector;
if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
return;
list_for_each_entry(plane, &config->plane_list, head)
drm_atomic_plane_print_state(p, plane->state);
list_for_each_entry(crtc, &config->crtc_list, head)
drm_atomic_crtc_print_state(p, crtc->state);
list_for_each_entry(connector, &config->connector_list, head)
drm_atomic_connector_print_state(p, connector->state);
}
EXPORT_SYMBOL(drm_state_dump);
#ifdef CONFIG_DEBUG_FS
static int drm_state_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
struct drm_printer p = drm_seq_file_printer(m);
drm_modeset_lock_all(dev);
drm_state_dump(dev, &p);
drm_modeset_unlock_all(dev);
return 0;
}
/* any use in debugfs files to dump individual planes/crtc/etc? */
static const struct drm_info_list drm_atomic_debugfs_list[] = {
{"state", drm_state_info, 0},
};
int drm_atomic_debugfs_init(struct drm_minor *minor)
{
return drm_debugfs_create_files(drm_atomic_debugfs_list,
ARRAY_SIZE(drm_atomic_debugfs_list),
minor->debugfs_root, minor);
}
#endif
/*
* The big monstor ioctl
*/
@ -1749,6 +1932,9 @@ retry:
} else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
ret = drm_atomic_nonblocking_commit(state);
} else {
if (unlikely(drm_debug & DRM_UT_STATE))
drm_atomic_print_state(state);
ret = drm_atomic_commit(state);
}

View file

@ -229,9 +229,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
crtc->primary = primary;
crtc->cursor = cursor;
if (primary)
if (primary && !primary->possible_crtcs)
primary->possible_crtcs = 1 << drm_crtc_index(crtc);
if (cursor)
if (cursor && !cursor->possible_crtcs)
cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
ret = drm_crtc_crc_init(crtc);

View file

@ -36,6 +36,7 @@
#include <linux/export.h>
#include <drm/drmP.h>
#include <drm/drm_edid.h>
#include <drm/drm_atomic.h>
#include "drm_internal.h"
#if defined(CONFIG_DEBUG_FS)
@ -163,6 +164,14 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
return ret;
}
if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
ret = drm_atomic_debugfs_init(minor);
if (ret) {
DRM_ERROR("Failed to create atomic debugfs files\n");
return ret;
}
}
if (dev->driver->debugfs_init) {
ret = dev->driver->debugfs_init(minor);
if (ret) {

View file

@ -957,13 +957,13 @@ static const struct drm_display_mode edid_cea_modes[] = {
798, 858, 0, 480, 489, 495, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
.vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
/* 58 - 720(1440)x480i@240 */
/* 58 - 720(1440)x480i@240Hz */
{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
801, 858, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
.vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
/* 59 - 720(1440)x480i@240 */
/* 59 - 720(1440)x480i@240Hz */
{ DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
801, 858, 0, 480, 488, 494, 525, 0,
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |

View file

@ -51,10 +51,11 @@ DEFINE_MUTEX(drm_global_mutex);
* Drivers must define the file operations structure that forms the DRM
* userspace API entry point, even though most of those operations are
* implemented in the DRM core. The mandatory functions are drm_open(),
* drm_read(), drm_ioctl() and drm_compat_ioctl if CONFIG_COMPAT is enabled.
* Drivers which implement private ioctls that require 32/64 bit compatibility
* support must provided their onw .compat_ioctl() handler that processes
* private ioctls and calls drm_compat_ioctl() for core ioctls.
* drm_read(), drm_ioctl() and drm_compat_ioctl() if CONFIG_COMPAT is enabled
* (note that drm_compat_ioctl will be NULL if CONFIG_COMPAT=n). Drivers which
* implement private ioctls that require 32/64 bit compatibility support must
* provide their own .compat_ioctl() handler that processes private ioctls and
* calls drm_compat_ioctl() for core ioctls.
*
* In addition drm_read() and drm_poll() provide support for DRM events. DRM
* events are a generic and extensible means to send asynchronous events to
@ -75,9 +76,7 @@ DEFINE_MUTEX(drm_global_mutex);
* .open = drm_open,
* .release = drm_release,
* .unlocked_ioctl = drm_ioctl,
* #ifdef CONFIG_COMPAT
* .compat_ioctl = drm_compat_ioctl,
* #endif
* .compat_ioctl = drm_compat_ioctl, // NULL if CONFIG_COMPAT=n
* .poll = drm_poll,
* .read = drm_read,
* .llseek = no_llseek,

View file

@ -673,6 +673,11 @@ EXPORT_SYMBOL(drm_framebuffer_lookup);
* those used for fbdev. Note that the caller must hold a reference of it's own,
* i.e. the object may not be destroyed through this call (since it'll lead to a
* locking inversion).
*
* NOTE: This function is deprecated. For driver-private framebuffers it is not
* recommended to embed a framebuffer struct info fbdev struct, instead, a
* framebuffer pointer is preferred and drm_framebuffer_unreference() should be
* called when the framebuffer is to be cleaned up.
*/
void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
{

View file

@ -104,6 +104,68 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_
u64 end,
enum drm_mm_search_flags flags);
#ifdef CONFIG_DRM_DEBUG_MM
#include <linux/stackdepot.h>
#define STACKDEPTH 32
#define BUFSZ 4096
static noinline void save_stack(struct drm_mm_node *node)
{
unsigned long entries[STACKDEPTH];
struct stack_trace trace = {
.entries = entries,
.max_entries = STACKDEPTH,
.skip = 1
};
save_stack_trace(&trace);
if (trace.nr_entries != 0 &&
trace.entries[trace.nr_entries-1] == ULONG_MAX)
trace.nr_entries--;
/* May be called under spinlock, so avoid sleeping */
node->stack = depot_save_stack(&trace, GFP_NOWAIT);
}
static void show_leaks(struct drm_mm *mm)
{
struct drm_mm_node *node;
unsigned long entries[STACKDEPTH];
char *buf;
buf = kmalloc(BUFSZ, GFP_KERNEL);
if (!buf)
return;
list_for_each_entry(node, &mm->head_node.node_list, node_list) {
struct stack_trace trace = {
.entries = entries,
.max_entries = STACKDEPTH
};
if (!node->stack) {
DRM_ERROR("node [%08llx + %08llx]: unknown owner\n",
node->start, node->size);
continue;
}
depot_fetch_stack(node->stack, &trace);
snprint_stack_trace(buf, BUFSZ, &trace, 0);
DRM_ERROR("node [%08llx + %08llx]: inserted at\n%s",
node->start, node->size, buf);
}
kfree(buf);
}
#undef STACKDEPTH
#undef BUFSZ
#else
static void save_stack(struct drm_mm_node *node) { }
static void show_leaks(struct drm_mm *mm) { }
#endif
#define START(node) ((node)->start)
#define LAST(node) ((node)->start + (node)->size - 1)
@ -228,6 +290,8 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
list_add(&node->hole_stack, &mm->hole_stack);
node->hole_follows = 1;
}
save_stack(node);
}
/**
@ -293,6 +357,8 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
node->hole_follows = 1;
}
save_stack(node);
return 0;
}
EXPORT_SYMBOL(drm_mm_reserve_node);
@ -397,6 +463,8 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
list_add(&node->hole_stack, &mm->hole_stack);
node->hole_follows = 1;
}
save_stack(node);
}
/**
@ -861,10 +929,12 @@ EXPORT_SYMBOL(drm_mm_init);
* Note that it is a bug to call this function on an allocator which is not
* clean.
*/
void drm_mm_takedown(struct drm_mm * mm)
void drm_mm_takedown(struct drm_mm *mm)
{
WARN(!list_empty(&mm->head_node.node_list),
"Memory manager not clean during takedown.\n");
if (WARN(!list_empty(&mm->head_node.node_list),
"Memory manager not clean during takedown.\n"))
show_leaks(mm);
}
EXPORT_SYMBOL(drm_mm_takedown);

View file

@ -49,13 +49,7 @@
*/
void drm_mode_debug_printmodeline(const struct drm_display_mode *mode)
{
DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d "
"0x%x 0x%x\n",
mode->base.id, mode->name, mode->vrefresh, mode->clock,
mode->hdisplay, mode->hsync_start,
mode->hsync_end, mode->htotal,
mode->vdisplay, mode->vsync_start,
mode->vsync_end, mode->vtotal, mode->type, mode->flags);
DRM_DEBUG_KMS("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
}
EXPORT_SYMBOL(drm_mode_debug_printmodeline);

View file

@ -130,15 +130,8 @@ int drm_plane_helper_check_state(struct drm_plane_state *state,
unsigned int rotation = state->rotation;
int hscale, vscale;
src->x1 = state->src_x;
src->y1 = state->src_y;
src->x2 = state->src_x + state->src_w;
src->y2 = state->src_y + state->src_h;
dst->x1 = state->crtc_x;
dst->y1 = state->crtc_y;
dst->x2 = state->crtc_x + state->crtc_w;
dst->y2 = state->crtc_y + state->crtc_h;
*src = drm_plane_state_src(state);
*dst = drm_plane_state_dest(state);
if (!fb) {
state->visible = false;

View file

@ -0,0 +1,54 @@
/*
* Copyright (C) 2016 Red Hat
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rob Clark <robdclark@gmail.com>
*/
#include <stdarg.h>
#include <linux/seq_file.h>
#include <drm/drmP.h>
#include <drm/drm_print.h>
void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf)
{
seq_printf(p->arg, "%pV", vaf);
}
EXPORT_SYMBOL(__drm_printfn_seq_file);
void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf)
{
dev_printk(KERN_INFO, p->arg, "[" DRM_NAME "] %pV", vaf);
}
EXPORT_SYMBOL(__drm_printfn_info);
void drm_printf(struct drm_printer *p, const char *f, ...)
{
struct va_format vaf;
va_list args;
va_start(args, f);
vaf.fmt = f;
vaf.va = &args;
p->printfn(p, &vaf);
va_end(args);
}
EXPORT_SYMBOL(drm_printf);

View file

@ -281,17 +281,10 @@ EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed);
*/
void drm_rect_debug_print(const char *prefix, const struct drm_rect *r, bool fixed_point)
{
int w = drm_rect_width(r);
int h = drm_rect_height(r);
if (fixed_point)
DRM_DEBUG_KMS("%s%d.%06ux%d.%06u%+d.%06u%+d.%06u\n", prefix,
w >> 16, ((w & 0xffff) * 15625) >> 10,
h >> 16, ((h & 0xffff) * 15625) >> 10,
r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10,
r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10);
DRM_DEBUG_KMS("%s" DRM_RECT_FP_FMT "\n", prefix, DRM_RECT_FP_ARG(r));
else
DRM_DEBUG_KMS("%s%dx%d%+d%+d\n", prefix, w, h, r->x1, r->y1);
DRM_DEBUG_KMS("%s" DRM_RECT_FMT "\n", prefix, DRM_RECT_ARG(r));
}
EXPORT_SYMBOL(drm_rect_debug_print);

View file

@ -479,9 +479,7 @@ static const struct file_operations fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -366,9 +366,7 @@ static const struct file_operations exynos_drm_driver_fops = {
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.release = drm_release,
};

View file

@ -180,9 +180,7 @@ static const struct file_operations fsl_dcu_drm_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -131,7 +131,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,
* page table entries with the dummy page. This is protected via the gtt
* mutex which the caller must hold.
*/
void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
{
struct drm_psb_private *dev_priv = dev->dev_private;
u32 __iomem *gtt_slot;

View file

@ -473,6 +473,7 @@ static const struct file_operations psb_gem_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = psb_unlocked_ioctl,
.compat_ioctl = drm_compat_ioctl,
.mmap = drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,

View file

@ -753,10 +753,6 @@ extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset);
extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
extern int psb_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file);
/* psb_device.c */
extern const struct psb_ops psb_chip_ops;

View file

@ -152,9 +152,7 @@ static const struct file_operations kirin_drm_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -113,9 +113,7 @@ static const struct file_operations i810_buffer_fops = {
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
.mmap = i810_mmap_buffers,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -49,9 +49,7 @@ static const struct file_operations i810_driver_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = drm_legacy_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -21,6 +21,7 @@ config DRM_I915_DEBUG
select PREEMPT_COUNT
select X86_MSR # used by igt/pm_rpm
select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
select DRM_DEBUG_MM if DRM=y
default n
help
Choose this option to turn on extra driver debugging that may affect

View file

@ -2497,9 +2497,7 @@ static const struct file_operations i915_driver_fops = {
.mmap = drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
#ifdef CONFIG_COMPAT
.compat_ioctl = i915_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -3001,6 +3001,8 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level,
#ifdef CONFIG_COMPAT
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
#else
#define i915_compat_ioctl NULL
#endif
extern const struct dev_pm_ops i915_pm_ops;

View file

@ -2821,14 +2821,8 @@ valid_fb:
plane_state->crtc_w = fb->width;
plane_state->crtc_h = fb->height;
intel_state->base.src.x1 = plane_state->src_x;
intel_state->base.src.y1 = plane_state->src_y;
intel_state->base.src.x2 = plane_state->src_x + plane_state->src_w;
intel_state->base.src.y2 = plane_state->src_y + plane_state->src_h;
intel_state->base.dst.x1 = plane_state->crtc_x;
intel_state->base.dst.y1 = plane_state->crtc_y;
intel_state->base.dst.x2 = plane_state->crtc_x + plane_state->crtc_w;
intel_state->base.dst.y2 = plane_state->crtc_y + plane_state->crtc_h;
intel_state->base.src = drm_plane_state_src(plane_state);
intel_state->base.dst = drm_plane_state_dest(plane_state);
obj = intel_fb_obj(fb);
if (i915_gem_object_is_tiled(obj))

View file

@ -773,15 +773,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
bool can_scale;
int ret;
src->x1 = state->base.src_x;
src->y1 = state->base.src_y;
src->x2 = state->base.src_x + state->base.src_w;
src->y2 = state->base.src_y + state->base.src_h;
dst->x1 = state->base.crtc_x;
dst->y1 = state->base.crtc_y;
dst->x2 = state->base.crtc_x + state->base.crtc_w;
dst->y2 = state->base.crtc_y + state->base.crtc_h;
*src = drm_plane_state_src(&state->base);
*dst = drm_plane_state_dest(&state->base);
if (!fb) {
state->base.visible = false;

View file

@ -158,6 +158,7 @@ static int imx_drm_atomic_commit(struct drm_device *dev,
struct drm_plane_state *plane_state;
struct drm_plane *plane;
struct dma_buf *dma_buf;
struct dma_fence *fence;
int i;
/*
@ -170,8 +171,9 @@ static int imx_drm_atomic_commit(struct drm_device *dev,
0)->base.dma_buf;
if (!dma_buf)
continue;
plane_state->fence =
reservation_object_get_excl_rcu(dma_buf->resv);
fence = reservation_object_get_excl_rcu(dma_buf->resv);
drm_atomic_set_fence_for_plane(plane_state, fence);
}
}

View file

@ -249,9 +249,7 @@ static const struct file_operations mtk_drm_fops = {
.mmap = mtk_drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
};
static struct drm_driver mtk_drm_driver = {

View file

@ -82,9 +82,7 @@ static const struct file_operations mgag200_driver_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = mgag200_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.read = drm_read,
};

View file

@ -15,6 +15,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <drm/drm_print.h>
#include "msm_drv.h"
#include "mdp4_kms.h"
@ -29,7 +30,16 @@ void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
static void mdp4_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
{
struct mdp4_kms *mdp4_kms = container_of(irq, struct mdp4_kms, error_handler);
static DEFINE_RATELIMIT_STATE(rs, 5*HZ, 1);
extern bool dumpstate;
DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus);
if (dumpstate && __ratelimit(&rs)) {
struct drm_printer p = drm_info_printer(mdp4_kms->dev->dev);
drm_state_dump(mdp4_kms->dev, &p);
}
}
void mdp4_irq_preinstall(struct msm_kms *kms)

View file

@ -17,6 +17,8 @@
#include <linux/irq.h>
#include <drm/drm_print.h>
#include "msm_drv.h"
#include "mdp5_kms.h"
@ -30,7 +32,16 @@ void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
{
struct mdp5_kms *mdp5_kms = container_of(irq, struct mdp5_kms, error_handler);
static DEFINE_RATELIMIT_STATE(rs, 5*HZ, 1);
extern bool dumpstate;
DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus);
if (dumpstate && __ratelimit(&rs)) {
struct drm_printer p = drm_info_printer(mdp5_kms->dev->dev);
drm_state_dump(mdp5_kms->dev, &p);
}
}
void mdp5_irq_preinstall(struct msm_kms *kms)

View file

@ -114,6 +114,18 @@ static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg)
return msm_readl(mdp5_kms->mmio + reg);
}
static inline const char *stage2name(enum mdp_mixer_stage_id stage)
{
static const char *names[] = {
#define NAME(n) [n] = #n
NAME(STAGE_UNUSED), NAME(STAGE_BASE),
NAME(STAGE0), NAME(STAGE1), NAME(STAGE2),
NAME(STAGE3), NAME(STAGE4), NAME(STAGE6),
#undef NAME
};
return names[stage];
}
static inline const char *pipe2name(enum mdp5_pipe pipe)
{
static const char *names[] = {

View file

@ -16,6 +16,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <drm/drm_print.h>
#include "mdp5_kms.h"
struct mdp5_plane {
@ -181,6 +182,20 @@ done:
#undef SET_PROPERTY
}
static void
mdp5_plane_atomic_print_state(struct drm_printer *p,
const struct drm_plane_state *state)
{
struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
drm_printf(p, "\tpremultiplied=%u\n", pstate->premultiplied);
drm_printf(p, "\tzpos=%u\n", pstate->zpos);
drm_printf(p, "\talpha=%u\n", pstate->alpha);
drm_printf(p, "\tstage=%s\n", stage2name(pstate->stage));
drm_printf(p, "\tmode_changed=%u\n", pstate->mode_changed);
drm_printf(p, "\tpending=%u\n", pstate->pending);
}
static void mdp5_plane_reset(struct drm_plane *plane)
{
struct mdp5_plane_state *mdp5_state;
@ -244,6 +259,7 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
.reset = mdp5_plane_reset,
.atomic_duplicate_state = mdp5_plane_duplicate_state,
.atomic_destroy_state = mdp5_plane_destroy_state,
.atomic_print_state = mdp5_plane_atomic_print_state,
};
static int mdp5_plane_prepare_fb(struct drm_plane *plane,
@ -913,7 +929,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
mdp5_plane->formats, mdp5_plane->nformats,
type, NULL);
type, "%s", mdp5_plane->name);
if (ret)
goto fail;

View file

@ -217,8 +217,9 @@ int msm_atomic_commit(struct drm_device *dev,
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);
struct dma_fence *fence = reservation_object_get_excl_rcu(msm_obj->resv);
plane_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
drm_atomic_set_fence_for_plane(plane_state, fence);
}
}

View file

@ -79,6 +79,10 @@ static char *vram = "16m";
MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU)");
module_param(vram, charp, 0);
bool dumpstate = false;
MODULE_PARM_DESC(dumpstate, "Dump KMS state on errors");
module_param(dumpstate, bool, 0600);
/*
* Util/helpers:
*/
@ -768,9 +772,7 @@ static const struct file_operations fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -201,9 +201,7 @@ static const struct file_operations rcar_du_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -275,9 +275,7 @@ static const struct file_operations rockchip_drm_driver_fops = {
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.release = drm_release,
};

View file

@ -42,9 +42,7 @@ static const struct file_operations savage_driver_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = drm_legacy_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -245,9 +245,7 @@ static const struct file_operations shmob_drm_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -72,9 +72,7 @@ static const struct file_operations sis_driver_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = drm_legacy_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -297,9 +297,7 @@ static const struct file_operations sti_driver_fops = {
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.release = drm_release,
};

View file

@ -53,9 +53,7 @@ static const struct file_operations sun4i_drv_fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -49,9 +49,7 @@ static const struct file_operations tdfx_driver_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = drm_legacy_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -802,9 +802,7 @@ static const struct file_operations tegra_drm_fops = {
.mmap = tegra_drm_mmap,
.poll = drm_poll,
.read = drm_read,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -573,9 +573,7 @@ static const struct file_operations fops = {
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.poll = drm_poll,
.read = drm_read,
.llseek = no_llseek,

View file

@ -1611,7 +1611,14 @@ EXPORT_SYMBOL(ttm_bo_unmap_virtual);
int ttm_bo_wait(struct ttm_buffer_object *bo,
bool interruptible, bool no_wait)
{
long timeout = no_wait ? 0 : 15 * HZ;
long timeout = 15 * HZ;
if (no_wait) {
if (reservation_object_test_signaled_rcu(bo->resv, true))
return 0;
else
return -EBUSY;
}
timeout = reservation_object_wait_timeout_rcu(bo->resv, true,
interruptible, timeout);

View file

@ -44,9 +44,7 @@ static const struct file_operations udl_driver_fops = {
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
.release = drm_release,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -103,9 +103,7 @@ static const struct file_operations vc4_drm_fops = {
.mmap = vc4_mmap,
.poll = drm_poll,
.read = drm_read,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -64,9 +64,7 @@ static const struct file_operations via_driver_fops = {
.unlocked_ioctl = drm_ioctl,
.mmap = drm_legacy_mmap,
.poll = drm_poll,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -108,9 +108,7 @@ static const struct file_operations virtio_gpu_driver_fops = {
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
.release = drm_release,
#ifdef CONFIG_COMPAT
.compat_ioctl = drm_compat_ioctl,
#endif
.llseek = noop_llseek,
};

View file

@ -135,6 +135,7 @@ struct dma_buf_attachment;
#define DRM_UT_PRIME 0x08
#define DRM_UT_ATOMIC 0x10
#define DRM_UT_VBL 0x20
#define DRM_UT_STATE 0x40
extern __printf(6, 7)
void drm_dev_printk(const struct device *dev, const char *level,
@ -306,6 +307,27 @@ void drm_printk(const char *level, unsigned int category,
#define DRM_DEBUG_PRIME_RATELIMITED(fmt, args...) \
DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##args)
/* Format strings and argument splitters to simplify printing
* various "complex" objects
*/
#define DRM_MODE_FMT "%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x"
#define DRM_MODE_ARG(m) \
(m)->base.id, (m)->name, (m)->vrefresh, (m)->clock, \
(m)->hdisplay, (m)->hsync_start, (m)->hsync_end, (m)->htotal, \
(m)->vdisplay, (m)->vsync_start, (m)->vsync_end, (m)->vtotal, \
(m)->type, (m)->flags
#define DRM_RECT_FMT "%dx%d%+d%+d"
#define DRM_RECT_ARG(r) drm_rect_width(r), drm_rect_height(r), (r)->x1, (r)->y1
/* for rect's in fixed-point format: */
#define DRM_RECT_FP_FMT "%d.%06ux%d.%06u%+d.%06u%+d.%06u"
#define DRM_RECT_FP_ARG(r) \
drm_rect_width(r) >> 16, ((drm_rect_width(r) & 0xffff) * 15625) >> 10, \
drm_rect_height(r) >> 16, ((drm_rect_height(r) & 0xffff) * 15625) >> 10, \
(r)->x1 >> 16, (((r)->x1 & 0xffff) * 15625) >> 10, \
(r)->y1 >> 16, (((r)->y1 & 0xffff) * 15625) >> 10
/*@}*/
/***********************************************************************/
@ -941,8 +963,13 @@ static inline bool drm_is_primary_client(const struct drm_file *file_priv)
extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv);
extern long drm_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
#ifdef CONFIG_COMPAT
extern long drm_compat_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg);
#else
/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */
#define drm_compat_ioctl NULL
#endif
extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
/* File Operations (drm_fops.c) */

View file

@ -345,6 +345,8 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
struct drm_crtc *crtc);
void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
struct drm_framebuffer *fb);
void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state,
struct dma_fence *fence);
int __must_check
drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
struct drm_crtc *crtc);
@ -364,6 +366,13 @@ 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);
void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
#ifdef CONFIG_DEBUG_FS
struct drm_minor;
int drm_atomic_debugfs_init(struct drm_minor *minor);
#endif
#define for_each_connector_in_state(__state, connector, connector_state, __i) \
for ((__i) = 0; \
(__i) < (__state)->num_connector && \

View file

@ -37,6 +37,7 @@ struct drm_crtc;
struct drm_encoder;
struct drm_property;
struct drm_property_blob;
struct drm_printer;
struct edid;
enum drm_connector_force {
@ -481,6 +482,18 @@ struct drm_connector_funcs {
const struct drm_connector_state *state,
struct drm_property *property,
uint64_t *val);
/**
* @atomic_print_state:
*
* If driver subclasses struct &drm_connector_state, it should implement
* this optional hook for printing additional driver specific state.
*
* Do not call this directly, use drm_atomic_connector_print_state()
* instead.
*/
void (*atomic_print_state)(struct drm_printer *p,
const struct drm_connector_state *state);
};
/* mode specified on the command line */

View file

@ -53,6 +53,7 @@ struct drm_device;
struct drm_mode_set;
struct drm_file;
struct drm_clip_rect;
struct drm_printer;
struct device_node;
struct dma_fence;
struct edid;
@ -594,6 +595,18 @@ struct drm_crtc_funcs {
*/
int (*set_crc_source)(struct drm_crtc *crtc, const char *source,
size_t *values_cnt);
/**
* @atomic_print_state:
*
* If driver subclasses struct &drm_crtc_state, it should implement
* this optional hook for printing additional driver specific state.
*
* Do not call this directly, use drm_atomic_crtc_print_state()
* instead.
*/
void (*atomic_print_state)(struct drm_printer *p,
const struct drm_crtc_state *state);
};
/**

View file

@ -44,6 +44,9 @@
#ifdef CONFIG_DEBUG_FS
#include <linux/seq_file.h>
#endif
#ifdef CONFIG_DRM_DEBUG_MM
#include <linux/stackdepot.h>
#endif
enum drm_mm_search_flags {
DRM_MM_SEARCH_DEFAULT = 0,
@ -74,6 +77,9 @@ struct drm_mm_node {
u64 size;
u64 __subtree_last;
struct drm_mm *mm;
#ifdef CONFIG_DRM_DEBUG_MM
depot_stack_handle_t stack;
#endif
};
struct drm_mm {

View file

@ -361,8 +361,8 @@ struct drm_crtc_helper_funcs {
*
* Note that the power state of the display pipe when this function is
* called depends upon the exact helpers and calling sequence the driver
* has picked. See drm_atomic_commit_planes() for a discussion of the
* tradeoffs and variants of plane commit helpers.
* has picked. See drm_atomic_helper_commit_planes() for a discussion of
* the tradeoffs and variants of plane commit helpers.
*
* This callback is used by the atomic modeset helpers and by the
* transitional plane helpers, but it is optional.
@ -385,8 +385,8 @@ struct drm_crtc_helper_funcs {
*
* Note that the power state of the display pipe when this function is
* called depends upon the exact helpers and calling sequence the driver
* has picked. See drm_atomic_commit_planes() for a discussion of the
* tradeoffs and variants of plane commit helpers.
* has picked. See drm_atomic_helper_commit_planes() for a discussion of
* the tradeoffs and variants of plane commit helpers.
*
* This callback is used by the atomic modeset helpers and by the
* transitional plane helpers, but it is optional.
@ -940,8 +940,8 @@ struct drm_plane_helper_funcs {
*
* Note that the power state of the display pipe when this function is
* called depends upon the exact helpers and calling sequence the driver
* has picked. See drm_atomic_commit_planes() for a discussion of the
* tradeoffs and variants of plane commit helpers.
* has picked. See drm_atomic_helper_commit_planes() for a discussion of
* the tradeoffs and variants of plane commit helpers.
*
* This callback is used by the atomic modeset helpers and by the
* transitional plane helpers, but it is optional.
@ -963,8 +963,8 @@ struct drm_plane_helper_funcs {
*
* Note that the power state of the display pipe when this function is
* called depends upon the exact helpers and calling sequence the driver
* has picked. See drm_atomic_commit_planes() for a discussion of the
* tradeoffs and variants of plane commit helpers.
* has picked. See drm_atomic_helper_commit_planes() for a discussion of
* the tradeoffs and variants of plane commit helpers.
*
* This callback is used by the atomic modeset helpers and by the
* transitional plane helpers, but it is optional.

View file

@ -28,15 +28,11 @@
#include <drm/drm_mode_object.h>
struct drm_crtc;
struct drm_printer;
/**
* struct drm_plane_state - mutable plane state
* @plane: backpointer to the plane
* @crtc: currently bound CRTC, NULL if disabled
* @fb: currently bound framebuffer
* @fence: optional fence to wait for before scanning out @fb
* @crtc_x: left position of visible portion of plane on crtc
* @crtc_y: upper position of visible portion of plane on crtc
* @crtc_w: width of visible portion of plane on crtc
* @crtc_h: height of visible portion of plane on crtc
* @src_x: left position of visible portion of plane within
@ -57,18 +53,51 @@ struct drm_crtc;
* it can be trusted.
* @src: clipped source coordinates of the plane (in 16.16)
* @dst: clipped destination coordinates of the plane
* @visible: visibility of the plane
* @state: backpointer to global drm_atomic_state
*/
struct drm_plane_state {
struct drm_plane *plane;
struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_plane() */
struct drm_framebuffer *fb; /* do not write directly, use drm_atomic_set_fb_for_plane() */
/**
* @crtc:
*
* Currently bound CRTC, NULL if disabled. Do not this write directly,
* use drm_atomic_set_crtc_for_plane()
*/
struct drm_crtc *crtc;
/**
* @fb:
*
* Currently bound framebuffer. Do not write this directly, use
* drm_atomic_set_fb_for_plane()
*/
struct drm_framebuffer *fb;
/**
* @fence:
*
* Optional fence to wait for before scanning out @fb. Do not write this
* directly, use drm_atomic_set_fence_for_plane()
*/
struct dma_fence *fence;
/* Signed dest location allows it to be partially off screen */
int32_t crtc_x, crtc_y;
/**
* @crtc_x:
*
* Left position of visible portion of plane on crtc, signed dest
* location allows it to be partially off screen.
*/
int32_t crtc_x;
/**
* @crtc_y:
*
* Upper position of visible portion of plane on crtc, signed dest
* location allows it to be partially off screen.
*/
int32_t crtc_y;
uint32_t crtc_w, crtc_h;
/* Source values are 16.16 fixed point */
@ -85,15 +114,41 @@ struct drm_plane_state {
/* Clipped coordinates */
struct drm_rect src, dst;
/*
* Is the plane actually visible? Can be false even
* if fb!=NULL and crtc!=NULL, due to clipping.
/**
* @visible:
*
* Visibility of the plane. This can be false even if fb!=NULL and
* crtc!=NULL, due to clipping.
*/
bool visible;
struct drm_atomic_state *state;
};
static inline struct drm_rect
drm_plane_state_src(const struct drm_plane_state *state)
{
struct drm_rect src = {
.x1 = state->src_x,
.y1 = state->src_y,
.x2 = state->src_x + state->src_w,
.y2 = state->src_y + state->src_h,
};
return src;
}
static inline struct drm_rect
drm_plane_state_dest(const struct drm_plane_state *state)
{
struct drm_rect dest = {
.x1 = state->crtc_x,
.y1 = state->crtc_y,
.x2 = state->crtc_x + state->crtc_w,
.y2 = state->crtc_y + state->crtc_h,
};
return dest;
}
/**
* struct drm_plane_funcs - driver plane control functions
*/
@ -322,6 +377,18 @@ struct drm_plane_funcs {
* before data structures are torndown.
*/
void (*early_unregister)(struct drm_plane *plane);
/**
* @atomic_print_state:
*
* If driver subclasses struct &drm_plane_state, it should implement
* this optional hook for printing additional driver specific state.
*
* Do not call this directly, use drm_atomic_plane_print_state()
* instead.
*/
void (*atomic_print_state)(struct drm_printer *p,
const struct drm_plane_state *state);
};
/**

117
include/drm/drm_print.h Normal file
View file

@ -0,0 +1,117 @@
/*
* Copyright (C) 2016 Red Hat
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rob Clark <robdclark@gmail.com>
*/
#ifndef DRM_PRINT_H_
#define DRM_PRINT_H_
#include <linux/seq_file.h>
#include <linux/device.h>
/**
* DOC: print
*
* A simple wrapper for dev_printk(), seq_printf(), etc. Allows same
* debug code to be used for both debugfs and printk logging.
*
* For example::
*
* void log_some_info(struct drm_printer *p)
* {
* drm_printf(p, "foo=%d\n", foo);
* drm_printf(p, "bar=%d\n", bar);
* }
*
* #ifdef CONFIG_DEBUG_FS
* void debugfs_show(struct seq_file *f)
* {
* struct drm_printer p = drm_seq_file_printer(f);
* log_some_info(&p);
* }
* #endif
*
* void some_other_function(...)
* {
* struct drm_printer p = drm_info_printer(drm->dev);
* log_some_info(&p);
* }
*/
/**
* struct drm_printer - drm output "stream"
* @printfn: actual output fxn
* @arg: output fxn specific data
*
* Do not use struct members directly. Use drm_printer_seq_file(),
* drm_printer_info(), etc to initialize. And drm_printf() for output.
*/
struct drm_printer {
void (*printfn)(struct drm_printer *p, struct va_format *vaf);
void *arg;
};
void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
/**
* drm_printf - print to a &drm_printer stream
* @p: the &drm_printer
* @f: format string
*/
void drm_printf(struct drm_printer *p, const char *f, ...);
/**
* drm_seq_file_printer - construct a &drm_printer that outputs to &seq_file
* @f: the struct &seq_file to output to
*
* RETURNS:
* The &drm_printer object
*/
static inline struct drm_printer drm_seq_file_printer(struct seq_file *f)
{
struct drm_printer p = {
.printfn = __drm_printfn_seq_file,
.arg = f,
};
return p;
}
/**
* drm_info_printer - construct a &drm_printer that outputs to dev_printk()
* @dev: the struct &device pointer
*
* RETURNS:
* The &drm_printer object
*/
static inline struct drm_printer drm_info_printer(struct device *dev)
{
struct drm_printer p = {
.printfn = __drm_printfn_info,
.arg = dev,
};
return p;
}
#endif /* DRM_PRINT_H_ */

View file

@ -382,7 +382,8 @@ signed long dma_fence_wait_timeout(struct dma_fence *,
bool intr, signed long timeout);
signed long dma_fence_wait_any_timeout(struct dma_fence **fences,
uint32_t count,
bool intr, signed long timeout);
bool intr, signed long timeout,
uint32_t *idx);
/**
* dma_fence_wait - sleep until the fence gets signaled

View file

@ -50,6 +50,7 @@ extern "C" {
#define DRM_AMDGPU_WAIT_CS 0x09
#define DRM_AMDGPU_GEM_OP 0x10
#define DRM_AMDGPU_GEM_USERPTR 0x11
#define DRM_AMDGPU_WAIT_FENCES 0x12
#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
@ -63,6 +64,7 @@ extern "C" {
#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
#define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences)
#define AMDGPU_GEM_DOMAIN_CPU 0x1
#define AMDGPU_GEM_DOMAIN_GTT 0x2
@ -307,6 +309,32 @@ union drm_amdgpu_wait_cs {
struct drm_amdgpu_wait_cs_out out;
};
struct drm_amdgpu_fence {
__u32 ctx_id;
__u32 ip_type;
__u32 ip_instance;
__u32 ring;
__u64 seq_no;
};
struct drm_amdgpu_wait_fences_in {
/** This points to uint64_t * which points to fences */
__u64 fences;
__u32 fence_count;
__u32 wait_all;
__u64 timeout_ns;
};
struct drm_amdgpu_wait_fences_out {
__u32 status;
__u32 first_signaled;
};
union drm_amdgpu_wait_fences {
struct drm_amdgpu_wait_fences_in in;
struct drm_amdgpu_wait_fences_out out;
};
#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
#define AMDGPU_GEM_OP_SET_PLACEMENT 1

View file

@ -47,7 +47,15 @@ extern "C" {
#define DRM_MODE_TYPE_DRIVER (1<<6)
/* Video mode flags */
/* bit compatible with the xorg definitions. */
/* bit compatible with the xrandr RR_ definitions (bits 0-13)
*
* ABI warning: Existing userspace really expects
* the mode flags to match the xrandr definitions. Any
* changes that don't match the xrandr definitions will
* likely need a new client cap or some other mechanism
* to avoid breaking existing userspace. This includes
* allocating new flags in the previously unused bits!
*/
#define DRM_MODE_FLAG_PHSYNC (1<<0)
#define DRM_MODE_FLAG_NHSYNC (1<<1)
#define DRM_MODE_FLAG_PVSYNC (1<<2)