From: Tomi Valkeinen <tomi.valkeinen@ti.com>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCHv2 41/45] drm: omapdrm: remove omap_crtc_wait_page_flip
Date: Mon, 8 Jun 2015 19:02:28 +0300 [thread overview]
Message-ID: <5575BC94.4040108@ti.com> (raw)
In-Reply-To: <2119555.L6uFpPdt4e@avalon>
[-- Attachment #1.1: Type: text/plain, Size: 11242 bytes --]
On 06/06/15 07:09, Laurent Pinchart wrote:
> Hi Tomi,
>
> Thank you for the patch.
>
> On Thursday 04 June 2015 12:02:58 Tomi Valkeinen wrote:
>> omap_crtc_disable() waits for pending page flips to finish. However,
>> omap_crtc_disable() is always called via omap_atomic_complete() and we
>> never have page flips going on at that time.
>
> Why is that ? Because our omap_atomic_complete() implementation waits for
> vblanks before allowing the next atomic commit to run, and that our vblank IRQ
> handler completes all pending page flips ? If so, I believe we have a few
> corner cases that won't work properly.
Yes, I think what omap_atomic_complete() is supposed to do is to wait until
everything is done for the affected crtcs. But you are right, it wasn't quite
correct.
> For instance, if the user performs a full mode set on a CRTC without change
> the framebuffer, an event can be queued but
> drm_atomic_helper_wait_for_vblanks() won't wait for vblank on that CRTC as
> framebuffer_changed() will return false. If the next commit then disables the
> CRTC the event might not have completed yet.
I reworked the event/flip_wait code, removing this patch and 42 and 43. I didn't
have time to clean it up properly, but I'm probably not able to work on it for
the following days, so I'll post it now. Quick testing went fine.
I also pushed it to omapdrm-atomic-v2 branch.
From 8d6429616783c335d20bf8ebaf8cc4dc447d0385 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@ti.com>
Date: Fri, 29 May 2015 16:01:18 +0300
Subject: [PATCH] drm: omapdrm: new vblank and event handling
Rework the crtc event/flip_wait system as follows:
- If we enable a crtc (full modeset), we set omap_crtc->pending and
register vblank irq.
- If we need to set GO bit (page flip), we do the same but also set the
GO bit.
- On vblank we unregister the irq, clear the 'pending' flag, send vblank
event to userspace if crtc->state->event != NULL, and wake up
'pending_wait' wq.
- In omap_atomic_complete() we wait for the 'pending' flag to get reset
for all enabled crtcs using 'pending_wait wq.
The above ensures that we send the events to userspace in vblank, and
that after the wait in omap_atomic_complete() everything for the
affected crtcs has been completed.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 8d2bf8565ddd..9b067d10e8d2 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -17,8 +17,6 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <linux/completion.h>
-
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
@@ -49,13 +47,10 @@ struct omap_crtc {
struct omap_drm_irq vblank_irq;
struct omap_drm_irq error_irq;
- /* pending event */
- struct drm_pending_vblank_event *event;
- wait_queue_head_t flip_wait;
-
- struct completion completion;
-
bool ignore_digit_sync_lost;
+
+ bool pending;
+ wait_queue_head_t pending_wait;
};
/* -----------------------------------------------------------------------------
@@ -81,6 +76,15 @@ enum omap_channel omap_crtc_channel(struct drm_crtc *crtc)
return omap_crtc->channel;
}
+int omap_crtc_wait_pending(struct drm_crtc *crtc)
+{
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+
+ return wait_event_timeout(omap_crtc->pending_wait,
+ !omap_crtc->pending,
+ msecs_to_jiffies(50));
+}
+
/* -----------------------------------------------------------------------------
* DSS Manager Functions
*/
@@ -253,77 +257,45 @@ static const struct dss_mgr_ops mgr_ops = {
* Setup, Flush and Page Flip
*/
-static void omap_crtc_complete_page_flip(struct drm_crtc *crtc)
+static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
{
- struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
- struct drm_pending_vblank_event *event;
- struct drm_device *dev = crtc->dev;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->event_lock, flags);
-
- event = omap_crtc->event;
- omap_crtc->event = NULL;
-
- if (event) {
- list_del(&event->base.link);
-
- /*
- * Queue the event for delivery if it's still linked to a file
- * handle, otherwise just destroy it.
- */
- if (event->base.file_priv)
- drm_crtc_send_vblank_event(crtc, event);
- else
- event->base.destroy(&event->base);
+ struct omap_crtc *omap_crtc =
+ container_of(irq, struct omap_crtc, error_irq);
- wake_up(&omap_crtc->flip_wait);
- drm_crtc_vblank_put(crtc);
+ if (omap_crtc->ignore_digit_sync_lost) {
+ irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
+ if (!irqstatus)
+ return;
}
- spin_unlock_irqrestore(&dev->event_lock, flags);
+ DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
}
-static bool omap_crtc_page_flip_pending(struct drm_crtc *crtc)
+static void omap_crtc_complete_page_flip(struct drm_crtc *crtc)
{
- struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ struct drm_pending_vblank_event *event;
struct drm_device *dev = crtc->dev;
unsigned long flags;
- bool pending;
- spin_lock_irqsave(&dev->event_lock, flags);
- pending = omap_crtc->event != NULL;
- spin_unlock_irqrestore(&dev->event_lock, flags);
+ event = crtc->state->event;
- return pending;
-}
-
-static void omap_crtc_wait_page_flip(struct drm_crtc *crtc)
-{
- struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
-
- if (wait_event_timeout(omap_crtc->flip_wait,
- !omap_crtc_page_flip_pending(crtc),
- msecs_to_jiffies(50)))
+ if (!event)
return;
- dev_warn(crtc->dev->dev, "page flip timeout!\n");
-
- omap_crtc_complete_page_flip(crtc);
-}
+ spin_lock_irqsave(&dev->event_lock, flags);
-static void omap_crtc_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
-{
- struct omap_crtc *omap_crtc =
- container_of(irq, struct omap_crtc, error_irq);
+ list_del(&event->base.link);
- if (omap_crtc->ignore_digit_sync_lost) {
- irqstatus &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
- if (!irqstatus)
- return;
- }
+ /*
+ * Queue the event for delivery if it's still linked to a file
+ * handle, otherwise just destroy it.
+ */
+ if (event->base.file_priv)
+ drm_crtc_send_vblank_event(crtc, event);
+ else
+ event->base.destroy(&event->base);
- DRM_ERROR_RATELIMITED("%s: errors: %08x\n", omap_crtc->name, irqstatus);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
}
static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
@@ -336,12 +308,19 @@ static void omap_crtc_vblank_irq(struct omap_drm_irq *irq, uint32_t irqstatus)
return;
DBG("%s: apply done", omap_crtc->name);
+
__omap_irq_unregister(dev, &omap_crtc->vblank_irq);
- /* wakeup userspace */
+ mb();
+ WARN_ON(!omap_crtc->pending);
+ omap_crtc->pending = false;
+ mb();
+
+ /* wake up userspace */
omap_crtc_complete_page_flip(&omap_crtc->base);
- complete(&omap_crtc->completion);
+ /* wake up omap_atomic_complete */
+ wake_up(&omap_crtc->pending_wait);
}
/* -----------------------------------------------------------------------------
@@ -375,6 +354,13 @@ static void omap_crtc_enable(struct drm_crtc *crtc)
DBG("%s", omap_crtc->name);
+ WARN_ON(omap_crtc->pending);
+
+ omap_crtc->pending = true;
+ mb();
+
+ omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
+
drm_crtc_vblank_on(crtc);
}
@@ -384,7 +370,6 @@ static void omap_crtc_disable(struct drm_crtc *crtc)
DBG("%s", omap_crtc->name);
- omap_crtc_wait_page_flip(crtc);
drm_crtc_vblank_off(crtc);
}
@@ -405,19 +390,7 @@ static void omap_crtc_mode_set_nofb(struct drm_crtc *crtc)
static void omap_crtc_atomic_begin(struct drm_crtc *crtc)
{
- struct drm_pending_vblank_event *event = crtc->state->event;
- struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
- struct drm_device *dev = crtc->dev;
- unsigned long flags;
-
- if (event) {
- WARN_ON(omap_crtc->event);
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
- spin_lock_irqsave(&dev->event_lock, flags);
- omap_crtc->event = event;
- spin_unlock_irqrestore(&dev->event_lock, flags);
- }
}
static void omap_crtc_atomic_flush(struct drm_crtc *crtc)
@@ -425,16 +398,16 @@ static void omap_crtc_atomic_flush(struct drm_crtc *crtc)
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
WARN_ON(omap_crtc->vblank_irq.registered);
+ WARN_ON(omap_crtc->pending);
if (dispc_mgr_is_enabled(omap_crtc->channel)) {
DBG("%s: GO", omap_crtc->name);
+ omap_crtc->pending = true;
+ mb();
+
dispc_mgr_go(omap_crtc->channel);
omap_irq_register(crtc->dev, &omap_crtc->vblank_irq);
-
- WARN_ON(!wait_for_completion_timeout(&omap_crtc->completion,
- msecs_to_jiffies(100)));
- reinit_completion(&omap_crtc->completion);
}
crtc->invert_dimensions = !!(crtc->primary->state->rotation &
@@ -534,8 +507,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
crtc = &omap_crtc->base;
- init_waitqueue_head(&omap_crtc->flip_wait);
- init_completion(&omap_crtc->completion);
+ init_waitqueue_head(&omap_crtc->pending_wait);
omap_crtc->channel = channel;
omap_crtc->name = channel_names[channel];
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 50f555530e55..e8f4001d9d31 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -66,6 +66,25 @@ struct omap_atomic_state_commit {
u32 crtcs;
};
+static void omap_atomic_wait_for_gos(struct drm_device *dev,
+ struct drm_atomic_state *old_state)
+{
+ struct drm_crtc *crtc;
+ struct drm_crtc_state *old_crtc_state;
+ int i, ret;
+
+ for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
+ if (!crtc->state->enable)
+ continue;
+
+ ret = omap_crtc_wait_pending(crtc);
+
+ if (!ret)
+ dev_warn(dev->dev,
+ "atomic flush timeout (pipe %u)!\n", i);
+ }
+}
+
static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
{
struct drm_device *dev = commit->dev;
@@ -79,7 +98,7 @@ static void omap_atomic_complete(struct omap_atomic_state_commit *commit)
drm_atomic_helper_commit_planes(dev, old_state);
drm_atomic_helper_commit_modeset_enables(dev, old_state);
- drm_atomic_helper_wait_for_vblanks(dev, old_state);
+ omap_atomic_wait_for_gos(dev, old_state);
drm_atomic_helper_cleanup_planes(dev, old_state);
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 0b7a055bf007..ae2df41f216f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -147,6 +147,7 @@ void omap_crtc_pre_init(void);
void omap_crtc_pre_uninit(void);
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id);
+int omap_crtc_wait_pending(struct drm_crtc *crtc);
struct drm_plane *omap_plane_init(struct drm_device *dev,
int id, enum drm_plane_type type);
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2015-06-08 16:02 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-04 9:02 [PATCHv2 00/45] Convert omapdrm to the atomic updates API Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 01/45] drm: omapdrm: Store the rotation property in dev->mode_config Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 02/45] drm: omapdrm: Apply settings synchronously Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 03/45] drm: omapdrm: Rename omap_crtc_page_flip_locked to omap_crtc_page_flip Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 04/45] drm: omapdrm: Rename omap_crtc page flip-related fields Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 05/45] drm: omapdrm: Simplify IRQ registration Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 06/45] drm: omapdrm: Cancel pending page flips when closing device Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 07/45] drm: omapdrm: Rework page flip handling Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 08/45] drm: omapdrm: Turn vblank on/off when enabling/disabling CRTC Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 09/45] drm: omapdrm: Fix page flip race with CRTC disable Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 10/45] drm: omapdrm: Clean up #include's Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 11/45] drm: omapdrm: Rename CRTC DSS operations with an omap_crtc_dss_ prefix Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 12/45] drm: omapdrm: Rework CRTC enable/disable for atomic updates Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 13/45] drm: omapdrm: Implement encoder .disable() and .enable() operations Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 14/45] drm: omapdrm: Wire up atomic state object scaffolding Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 15/45] drm: omapdrm: Implement planes atomic operations Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 16/45] drm: omapdrm: Handle primary plane config through atomic plane ops Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 17/45] drm: omapdrm: Switch plane update to atomic helpers Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 18/45] drm: omapdrm: Switch mode config " Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 19/45] drm: omapdrm: Switch connector DPMS " Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 20/45] drm: omapdrm: Replace encoder mode_fixup with atomic_check Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 21/45] drm: omapdrm: Implement asynchronous commit support Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 22/45] drm: omapdrm: Switch page flip to atomic helpers Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 23/45] drm: omapdrm: Drop manual framebuffer pin handling Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 24/45] drm: omapdrm: Switch crtc and plane set_property to atomic helpers Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 25/45] drm: omapdrm: Move plane info and win out of the plane structure Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 26/45] drm: omapdrm: Move crtc info out of the crtc structure Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 27/45] drm: omapdrm: Remove omap_crtc enabled field Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 28/45] drm: omapdrm: Remove omap_plane " Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 29/45] drm: omapdrm: Make the omap_crtc_flush function static Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 30/45] drm: omapdrm: Don't get/put dispc in omap_crtc_flush() Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 31/45] drm: omapdrm: omap_crtc_flush() isn't called with modeset locked Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 32/45] drm: omapdrm: Support unlinking page flip events prematurely Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 33/45] drm: omapdrm: Remove nested PM get/sync when configuring encoders Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 34/45] drm: omapdrm: Simplify DSS power management Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 35/45] drm: omapdrm: Move encoder setup to encoder operations Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 36/45] drm: omapdrm: Don't flush CRTC when enabling or disabling it Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 37/45] drm: omapdrm: Don't setup planes manually from CRTC .enable()/.disable() Tomi Valkeinen
2015-06-04 9:02 ` [PATCHv2 38/45] drm: omapdrm: omap_plane_setup() cannot fail, use WARN Tomi Valkeinen
2015-06-06 3:14 ` Laurent Pinchart
2015-06-04 9:02 ` [PATCHv2 39/45] drm: omapdrm: inline omap_plane_setup into update/disable Tomi Valkeinen
2015-06-06 3:15 ` Laurent Pinchart
2015-06-04 9:02 ` [PATCHv2 40/45] drm: omapdrm: if omap_plane_atomic_update fails, disable plane Tomi Valkeinen
2015-06-06 3:23 ` Laurent Pinchart
2015-06-04 9:02 ` [PATCHv2 41/45] drm: omapdrm: remove omap_crtc_wait_page_flip Tomi Valkeinen
2015-06-06 4:09 ` Laurent Pinchart
2015-06-08 16:02 ` Tomi Valkeinen [this message]
2015-06-04 9:02 ` [PATCHv2 42/45] drm: omapdrm: add omap_atomic_wait_for_gos() Tomi Valkeinen
2015-06-06 4:10 ` Laurent Pinchart
2015-06-08 8:36 ` Tomi Valkeinen
2015-06-04 9:03 ` [PATCHv2 43/45] drm: omapdrm: don't wait in crtc_atomic_flush Tomi Valkeinen
2015-06-06 4:20 ` Laurent Pinchart
2015-06-04 9:03 ` [PATCHv2 44/45] drm: omapdrm: merge omap_crtc_flush and omap_crtc_atomic_flush Tomi Valkeinen
2015-06-06 4:01 ` Laurent Pinchart
2015-06-04 9:03 ` [PATCHv2 45/45] drm: omapdrm: add lock for fb pinning Tomi Valkeinen
2015-06-06 4:30 ` Laurent Pinchart
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5575BC94.4040108@ti.com \
--to=tomi.valkeinen@ti.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=laurent.pinchart@ideasonboard.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.