summaryrefslogtreecommitdiff
authorKeith Packard <keithp@keithp.com>2017-07-05 21:34:23 (GMT)
committer Tao Zeng <tao.zeng@amlogic.com>2019-07-30 01:52:54 (GMT)
commit9c779fb7d59a7073b02645d1435f431992ace934 (patch)
treeb50367a6424404a0fb2d12ef014f5c34ca879399
parentcb0491f2cab55e0a67a54873119a4a6b457ed7af (diff)
downloadcommon-9c779fb7d59a7073b02645d1435f431992ace934.zip
common-9c779fb7d59a7073b02645d1435f431992ace934.tar.gz
common-9c779fb7d59a7073b02645d1435f431992ace934.tar.bz2
drm: Reorganize drm_pending_event to support future event types [v2]
PD#SWPL-4863 Place drm_event_vblank in a new union that includes that and a bare drm_event structure. This will allow new members of that union to be added in the future without changing code related to the existing vbl event type. Assignments to the crtc_id field are now done when the event is allocated, rather than when delievered. This way, delivery doesn't need to have the crtc ID available. v2: * Remove 'dev' argument from create_vblank_event It wasn't being used anyways, and if we need it in the future, we can always get it from crtc->dev. * Check for MODESETTING before looking for crtc in queue_vblank_event UMS drivers will oops if we try to get a crtc, so make sure we're modesetting before we try to find a crtc_id to fill into the event. (cherry picked from commit dc695b85fde88eca3ef3b03fcd82f15b6bc6e462) Change-Id: I6f0feabcba9373fcc434b148752d9cd28bea67e6 Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Sean Paul <seanpaul@chromium.org> Signed-off-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Ao Xu <ao.xu@amlogic.com>
Diffstat
-rw-r--r--drivers/gpu/drm/drm_atomic.c5
-rw-r--r--drivers/gpu/drm/drm_crtc.c23
-rw-r--r--drivers/gpu/drm/drm_irq.c5
-rw-r--r--include/drm/drm_crtc.h1
4 files changed, 32 insertions, 2 deletions
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index b3f8543..8669712 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -1654,7 +1654,7 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
*/
static struct drm_pending_vblank_event *create_vblank_event(
- struct drm_device *dev, uint64_t user_data)
+ struct drm_crtc *crtc, uint64_t user_data)
{
struct drm_pending_vblank_event *e = NULL;
@@ -1665,6 +1665,7 @@ static struct drm_pending_vblank_event *create_vblank_event(
e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
e->event.base.length = sizeof(e->event);
e->event.user_data = user_data;
+ e->event.crtc_id = crtc->base.id;
return e;
}
@@ -1867,7 +1868,7 @@ static int prepare_crtc_signaling(struct drm_device *dev,
if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) {
struct drm_pending_vblank_event *e;
- e = create_vblank_event(dev, arg->user_data);
+ e = create_vblank_event(crtc, arg->user_data);
if (!e)
return -ENOMEM;
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index ebdef0c..de4fd23 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -47,6 +47,29 @@
#include "drm_internal.h"
/**
+ * drm_crtc_from_index - find the registered CRTC at an index
+ * @dev: DRM device
+ * @idx: index of registered CRTC to find for
+ *
+ * Given a CRTC index, return the registered CRTC from DRM device's
+ * list of CRTCs with matching index. This is the inverse of drm_crtc_index().
+ * It's useful in the vblank callbacks (like &drm_driver.enable_vblank or
+ * &drm_driver.disable_vblank), since that still deals with indices instead
+ * of pointers to &struct drm_crtc."
+ */
+struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx)
+{
+ struct drm_crtc *crtc;
+
+ drm_for_each_crtc(crtc, dev)
+ if (idx == crtc->index)
+ return crtc;
+
+ return NULL;
+}
+EXPORT_SYMBOL(drm_crtc_from_index);
+
+/**
* drm_crtc_force_disable - Forcibly turn off a CRTC
* @crtc: CRTC to turn off
*
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 28536aa..9a87bbe 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -1578,6 +1578,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
{
struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
struct drm_pending_vblank_event *e;
+ struct drm_crtc *crtc;
struct timeval now;
unsigned long flags;
unsigned int seq;
@@ -1594,6 +1595,10 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe,
e->event.base.type = DRM_EVENT_VBLANK;
e->event.base.length = sizeof(e->event);
e->event.user_data = vblwait->request.signal;
+ e->event.crtc_id = 0;
+ crtc = drm_crtc_from_index(dev, pipe);
+ if (crtc)
+ e->event.crtc_id = crtc->base.id;
spin_lock_irqsave(&dev->event_lock, flags);
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index be7a15d..e2aa770 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -786,6 +786,7 @@ extern struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
char topology[8]);
extern void drm_mode_put_tile_group(struct drm_device *dev,
struct drm_tile_group *tg);
+struct drm_crtc *drm_crtc_from_index(struct drm_device *dev, int idx);
/* Helpers */
static inline struct drm_crtc *drm_crtc_find(struct drm_device *dev,