From 9c779fb7d59a7073b02645d1435f431992ace934 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 5 Jul 2017 14:34:23 -0700 Subject: [PATCH] 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 Reviewed-by: Sean Paul Signed-off-by: Dave Airlie Signed-off-by: Ao Xu --- drivers/gpu/drm/drm_atomic.c | 5 +++-- drivers/gpu/drm/drm_crtc.c | 23 +++++++++++++++++++++++ drivers/gpu/drm/drm_irq.c | 5 +++++ include/drm/drm_crtc.h | 1 + 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, -- 2.7.4