Skip to content

Commit

Permalink
Merge tag 'drm-misc-next-2021-10-06' of git://anongit.freedesktop.org…
Browse files Browse the repository at this point in the history
…/drm/drm-misc into drm-next

drm-misc-next for v5.16:

UAPI Changes:
- Allow empty drm leases for creating separate GEM namespaces.

Cross-subsystem Changes:
- Slightly rework dma_buf_poll.
- Add dma_resv_for_each_fence_unlocked to iterate, and use it inside
  the lockless dma-resv functions.

Core Changes:
- Allow devm_drm_of_get_bridge to build without CONFIG_OF for compile testing.
- Add more DP2 headers.
- fix CONFIG_FB dependency in fb_helper.
- Add DRM_FORMAT_R8 to drm_format_info, and helpers for RGB332 and RGB888.
- Fix crash on a 0 or invalid EDID.

Driver Changes:
- Apply and revert DRM_MODESET_LOCK_ALL_BEGIN.
- Add mode_valid to ti-sn65dsi86 bridge.
- Support multiple syncobjs in v3d.
- Add R8, RGB332 and RGB888 pixel formats to GUD.
- Use devm_add_action_or_reset in dw-hdmi-cec.

Signed-off-by: Dave Airlie <airlied@redhat.com>

# gpg: Signature made Wed 06 Oct 2021 20:48:12 AEST
# gpg:                using RSA key B97BD6A80CAC4981091AE547FE558C72A67013C3
# gpg: Good signature from "Maarten Lankhorst <maarten.lankhorst@linux.intel.com>" [expired]
# gpg:                 aka "Maarten Lankhorst <maarten@debian.org>" [expired]
# gpg:                 aka "Maarten Lankhorst <maarten.lankhorst@canonical.com>" [expired]
# gpg: Note: This key has expired!
# Primary key fingerprint: B97B D6A8 0CAC 4981 091A  E547 FE55 8C72 A670 13C3
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/2602f4e9-a8ac-83f8-6c2a-39fd9ca2e1ba@linux.intel.com
  • Loading branch information
Dave Airlie committed Oct 11, 2021
2 parents b1f8166 + 9962601 commit 797d72c
Show file tree
Hide file tree
Showing 99 changed files with 3,148 additions and 1,131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ properties:
- auo,b101uan08.3
# BOE TV105WUM-NW0 10.5" WUXGA TFT LCD panel
- boe,tv105wum-nw0
# BOE TV110C9M-LL3 10.95" WUXGA TFT LCD panel
- boe,tv110c9m-ll3
# INX HJ110IZ-01A 10.95" WUXGA TFT LCD panel
- innolux,hj110iz-01a

reg:
description: the virtual channel number of a DSI peripheral
Expand All @@ -36,6 +40,9 @@ properties:
pp1800-supply:
description: core voltage supply

pp3300-supply:
description: core voltage supply

avdd-supply:
description: phandle of the regulator that provides positive voltage

Expand Down
12 changes: 12 additions & 0 deletions Documentation/gpu/drm-kms-helpers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,18 @@ Overview
.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
:doc: overview

Display Driver Integration
--------------------------

.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
:doc: display driver integration

Special Care with MIPI-DSI bridges
----------------------------------

.. kernel-doc:: drivers/gpu/drm/drm_bridge.c
:doc: special care dsi

Bridge Operations
-----------------

Expand Down
17 changes: 0 additions & 17 deletions Documentation/gpu/todo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -353,23 +353,6 @@ converted, except for struct drm_driver.gem_prime_mmap.

Level: Intermediate

Use DRM_MODESET_LOCK_ALL_* helpers instead of boilerplate
---------------------------------------------------------

For cases where drivers are attempting to grab the modeset locks with a local
acquire context. Replace the boilerplate code surrounding
drm_modeset_lock_all_ctx() with DRM_MODESET_LOCK_ALL_BEGIN() and
DRM_MODESET_LOCK_ALL_END() instead.

This should also be done for all places where drm_modeset_lock_all() is still
used.

As a reference, take a look at the conversions already completed in drm core.

Contact: Sean Paul, respective driver maintainers

Level: Starter

Rename CMA helpers to DMA helpers
---------------------------------

Expand Down
2 changes: 1 addition & 1 deletion Documentation/locking/ww-mutex-design.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Concepts
Compared to normal mutexes two additional concepts/objects show up in the lock
interface for w/w mutexes:

Acquire context: To ensure eventual forward progress it is important the a task
Acquire context: To ensure eventual forward progress it is important that a task
trying to acquire locks doesn't grab a new reservation id, but keeps the one it
acquired when starting the lock acquisition. This ticket is stored in the
acquire context. Furthermore the acquire context keeps track of debugging state
Expand Down
152 changes: 70 additions & 82 deletions drivers/dma-buf/dma-buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static void dma_buf_release(struct dentry *dentry)
* If you hit this BUG() it means someone dropped their ref to the
* dma-buf while still having pending operation to the buffer.
*/
BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active);
BUG_ON(dmabuf->cb_in.active || dmabuf->cb_out.active);

dma_buf_stats_teardown(dmabuf);
dmabuf->ops->release(dmabuf);
Expand Down Expand Up @@ -206,16 +206,55 @@ static void dma_buf_poll_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
wake_up_locked_poll(dcb->poll, dcb->active);
dcb->active = 0;
spin_unlock_irqrestore(&dcb->poll->lock, flags);
dma_fence_put(fence);
}

static bool dma_buf_poll_shared(struct dma_resv *resv,
struct dma_buf_poll_cb_t *dcb)
{
struct dma_resv_list *fobj = dma_resv_shared_list(resv);
struct dma_fence *fence;
int i, r;

if (!fobj)
return false;

for (i = 0; i < fobj->shared_count; ++i) {
fence = rcu_dereference_protected(fobj->shared[i],
dma_resv_held(resv));
dma_fence_get(fence);
r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb);
if (!r)
return true;
dma_fence_put(fence);
}

return false;
}

static bool dma_buf_poll_excl(struct dma_resv *resv,
struct dma_buf_poll_cb_t *dcb)
{
struct dma_fence *fence = dma_resv_excl_fence(resv);
int r;

if (!fence)
return false;

dma_fence_get(fence);
r = dma_fence_add_callback(fence, &dcb->cb, dma_buf_poll_cb);
if (!r)
return true;
dma_fence_put(fence);

return false;
}

static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
{
struct dma_buf *dmabuf;
struct dma_resv *resv;
struct dma_resv_list *fobj;
struct dma_fence *fence_excl;
__poll_t events;
unsigned shared_count, seq;

dmabuf = file->private_data;
if (!dmabuf || !dmabuf->resv)
Expand All @@ -229,101 +268,50 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
if (!events)
return 0;

retry:
seq = read_seqcount_begin(&resv->seq);
rcu_read_lock();

fobj = rcu_dereference(resv->fence);
if (fobj)
shared_count = fobj->shared_count;
else
shared_count = 0;
fence_excl = dma_resv_excl_fence(resv);
if (read_seqcount_retry(&resv->seq, seq)) {
rcu_read_unlock();
goto retry;
}

if (fence_excl && (!(events & EPOLLOUT) || shared_count == 0)) {
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_excl;
__poll_t pevents = EPOLLIN;
dma_resv_lock(resv, NULL);

if (shared_count == 0)
pevents |= EPOLLOUT;
if (events & EPOLLOUT) {
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_out;

/* Check that callback isn't busy */
spin_lock_irq(&dmabuf->poll.lock);
if (dcb->active) {
dcb->active |= pevents;
events &= ~pevents;
} else
dcb->active = pevents;
if (dcb->active)
events &= ~EPOLLOUT;
else
dcb->active = EPOLLOUT;
spin_unlock_irq(&dmabuf->poll.lock);

if (events & pevents) {
if (!dma_fence_get_rcu(fence_excl)) {
/* force a recheck */
events &= ~pevents;
dma_buf_poll_cb(NULL, &dcb->cb);
} else if (!dma_fence_add_callback(fence_excl, &dcb->cb,
dma_buf_poll_cb)) {
events &= ~pevents;
dma_fence_put(fence_excl);
} else {
/*
* No callback queued, wake up any additional
* waiters.
*/
dma_fence_put(fence_excl);
if (events & EPOLLOUT) {
if (!dma_buf_poll_shared(resv, dcb) &&
!dma_buf_poll_excl(resv, dcb))
/* No callback queued, wake up any other waiters */
dma_buf_poll_cb(NULL, &dcb->cb);
}
else
events &= ~EPOLLOUT;
}
}

if ((events & EPOLLOUT) && shared_count > 0) {
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_shared;
int i;
if (events & EPOLLIN) {
struct dma_buf_poll_cb_t *dcb = &dmabuf->cb_in;

/* Only queue a new callback if no event has fired yet */
/* Check that callback isn't busy */
spin_lock_irq(&dmabuf->poll.lock);
if (dcb->active)
events &= ~EPOLLOUT;
events &= ~EPOLLIN;
else
dcb->active = EPOLLOUT;
dcb->active = EPOLLIN;
spin_unlock_irq(&dmabuf->poll.lock);

if (!(events & EPOLLOUT))
goto out;

for (i = 0; i < shared_count; ++i) {
struct dma_fence *fence = rcu_dereference(fobj->shared[i]);

if (!dma_fence_get_rcu(fence)) {
/*
* fence refcount dropped to zero, this means
* that fobj has been freed
*
* call dma_buf_poll_cb and force a recheck!
*/
events &= ~EPOLLOUT;
if (events & EPOLLIN) {
if (!dma_buf_poll_excl(resv, dcb))
/* No callback queued, wake up any other waiters */
dma_buf_poll_cb(NULL, &dcb->cb);
break;
}
if (!dma_fence_add_callback(fence, &dcb->cb,
dma_buf_poll_cb)) {
dma_fence_put(fence);
events &= ~EPOLLOUT;
break;
}
dma_fence_put(fence);
else
events &= ~EPOLLIN;
}

/* No callback queued, wake up any additional waiters. */
if (i == shared_count)
dma_buf_poll_cb(NULL, &dcb->cb);
}

out:
rcu_read_unlock();
dma_resv_unlock(resv);
return events;
}

Expand Down Expand Up @@ -566,8 +554,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
dmabuf->owner = exp_info->owner;
spin_lock_init(&dmabuf->name_lock);
init_waitqueue_head(&dmabuf->poll);
dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
dmabuf->cb_in.poll = dmabuf->cb_out.poll = &dmabuf->poll;
dmabuf->cb_in.active = dmabuf->cb_out.active = 0;

if (!resv) {
resv = (struct dma_resv *)&dmabuf[1];
Expand Down
Loading

0 comments on commit 797d72c

Please sign in to comment.