Changes to drm_update_vblank_count() in Linux 4.4 broke the
behaviour of the pre/post modeset functions as the new update
code doesn't deal with hw vblank counter resets inbetween calls
to drm_vblank_pre_modeset an drm_vblank_post_modeset, as it
should.
This causes mistreatment of such hw counter resets as counter
wraparound, and thereby large forward jumps of the software
vblank counter which in turn cause vblank event dispatching
and vblank waits to fail/hang --> userspace clients hang.
This symptom was reported on radeon-kms to cause a infinite
hang of KDE Plasma 5 shell's login procedure, preventing users
from logging in.
Fix this by detecting when drm_update_vblank_count() is called
inside a pre->post modeset interval. If so, clamp valid vblank
increments to the safe values 0 and 1, pretty much restoring
the update behavior of the old update code of Linux 4.3 and
earlier. Also reset the last recorded hw vblank count at call
to drm_vblank_post_modeset() to be safe against hw that after
modesetting, dpms on etc. only fires its first vblank irq after
drm_vblank_post_modeset() was already called.
Reported-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Tested-by: Vlastimil Babka <vbabka@suse.cz>
Cc: <stable@vger.kernel.org> # 4.4+
Cc: michel@daenzer.net
Cc: vbabka@suse.cz
Cc: ville.syrjala@linux.intel.com
Cc: daniel.vetter@ffwll.ch
Cc: dri-devel@lists.freedesktop.org
Cc: alexander.deucher@amd.com
Cc: christian.koenig@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
This fixes a regression introduced by the new drm_update_vblank_count()
implementation in Linux 4.4:
Restrict the bump of the software vblank counter in drm_update_vblank_count()
to a safe maximum value of +1 whenever there is the possibility that
concurrent readers of vblank timestamps could be active at the moment,
as the current implementation of the timestamp caching and updating is
not safe against concurrent readers for calls to store_vblank() with a
bump of anything but +1. A bump != 1 would very likely return corrupted
timestamps to userspace, because the same slot in the cache could
be concurrently written by store_vblank() and read by one of those
readers in a non-atomic fashion and without the read-retry logic
detecting this collision.
Concurrent readers can exist while drm_update_vblank_count() is called
from the drm_vblank_off() or drm_vblank_on() functions or other non-vblank-
irq callers. However, all those calls are happening with the vbl_lock
locked thereby preventing a drm_vblank_get(), so the vblank refcount
can't increase while drm_update_vblank_count() is executing. Therefore
a zero vblank refcount during execution of that function signals that
is safe for arbitrary counter bumps if called from outside vblank irq,
whereas a non-zero count is not safe.
Whenever the function is called from vblank irq, we have to assume concurrent
readers could show up any time during its execution, even if the refcount
is currently zero, as vblank irqs are usually only enabled due to the
presence of readers, and because when it is called from vblank irq it
can't hold the vbl_lock to protect it from sudden bumps in vblank refcount.
Therefore also restrict bumps to +1 when the function is called from vblank
irq.
Such bumps of more than +1 can happen at other times than reenabling
vblank irqs, e.g., when regular vblank interrupts get delayed by more
than 1 frame due to long held locks, long irq off periods, realtime
preemption on RT kernels, or system management interrupts.
A better solution would be to rewrite the timestamp caching to use
full seqlocks to allow concurrent writes and reads for arbitrary
vblank counter increments.
v2: Add code comment that this is essentially a hack and should
be replaced by a full seqlock implementation for caching of
timestamps.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: <stable@vger.kernel.org> # 4.4+
Cc: michel@daenzer.net
Cc: vbabka@suse.cz
Cc: ville.syrjala@linux.intel.com
Cc: daniel.vetter@ffwll.ch
Cc: dri-devel@lists.freedesktop.org
Cc: alexander.deucher@amd.com
Cc: christian.koenig@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
Otherwise if a kms driver calls into drm_vblank_off() more than once
before calling drm_vblank_on() again, the redundant calls to
vblank_disable_and_save() will call drm_update_vblank_count()
while hw vblank counters and vblank timestamping are in a undefined
state during modesets, dpms off etc.
At least with the legacy drm helpers it is not unusual to
get multiple calls to drm_vblank_off and drm_vblank_on, e.g.,
half a dozen calls to drm_vblank_off and two calls to drm_vblank_on
were observed on radeon-kms during dpms-off -> dpms-on transition.
We don't no-op calls from atomic modesetting drivers, as they
should do a proper job of tracking hw state.
Fixes large jumps of the software maintained vblank counter due to
the hardware vblank counter resetting to zero during dpms off or
modeset, e.g., if radeon-kms is modified to use drm_vblank_off/on
instead of drm_vblank_pre/post_modeset().
This fixes a regression caused by the changes made to
drm_update_vblank_count() in Linux 4.4.
v2: Don't no-op on atomic modesetting drivers, per suggestion
of Daniel Vetter.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: <stable@vger.kernel.org> # 4.4+
Cc: michel@daenzer.net
Cc: vbabka@suse.cz
Cc: ville.syrjala@linux.intel.com
Cc: alexander.deucher@amd.com
Cc: christian.koenig@amd.com
Signed-off-by: Dave Airlie <airlied@redhat.com>
Well we can't use that directly since that code must hold
dev->event_lock already. Extract an _unlocked version.
Embarrassingly I've totally forgotten about this patch and any kind of
event-based vblank wait totally blew up, killing the kernel.
v2: Pick the right base struct, someone didn't noticed that gcc was
unhappy. No bug since the addresses at least matched (Daniel Stone)
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Daniel Stone <daniels@collabora.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1453978864-1513-1-git-send-email-daniel.vetter@ffwll.ch
Use them in the core vblank code and exynos/vmwgfx drivers.
Note that the difference between wake_up_all and _interruptible in
vmwgfx doesn't matter since the only waiter is the core code in
drm_fops.c. And that is interruptible.
v2: Adjust existing kerneldoc too.
Reviewed-by: Alex Deucher <alexander.deucher@amd.com> (v1)
Acked-by: Daniel Stone <daniels@collabora.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Thomas Hellstrom <thellstrom@vmware.com>
Cc: Inki Dae <inki.dae@samsung.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1452548477-15905-6-git-send-email-daniel.vetter@ffwll.ch
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
[danvet: Squash in compile fixup, spotted by 0-day.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
We moved the module options from drm_drv.c to drm_irq.c in 1888299571
('drm: Move vblank related module options into drm_irq.c'). Let's move
the MODULE_PARM_DESC()s as well so they're together.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20160108110045.GF32195@mwanda
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Apparently pre-nv50 pageflip events happen before the actual vblank
period. Therefore that functionality got semi-disabled in
commit af4870e406
Author: Mario Kleiner <mario.kleiner.de@gmail.com>
Date: Tue May 13 00:42:08 2014 +0200
drm/nouveau/kms/nv04-nv40: fix pageflip events via special case.
Unfortunately that hack got uprooted in
commit cc1ef118fc
Author: Thierry Reding <treding@nvidia.com>
Date: Wed Aug 12 17:00:31 2015 +0200
drm/irq: Make pipe unsigned and name consistent
Triggering a warning when trying to sample the vblank timestamp for a
non-existing pipe. There's a few ways to fix this:
- Open-code the old behaviour, which just enshrines this slight
breakage of the userspace ABI.
- Revert Mario's commit and again inflict broken timestamps, again not
pretty.
- Fix this for real by delaying the pageflip TS until the next vblank
interrupt, thereby making it accurate.
This patch implements the third option. Since having a page flip
interrupt that happens when the pageflip gets armed and not when it
completes in the next vblank seems to be fairly common (older i915 hw
works very similarly) create a new helper to arm vblank events for
such drivers.
v2 (Mario Kleiner):
- Fix function prototypes in drmP.h
- Add missing vblank_put() for pageflip completion without
pageflip event.
- Initialize sequence number for queued pageflip event to avoid
trouble in drm_handle_vblank_events().
- Remove dead code and spelling fix.
v3 (Mario Kleiner):
- Add a signed-off-by and cc stable tag per Ilja's advice.
v4 (Thierry Reding):
- Fix kerneldoc typo, discovered by Michel Dänzer
- Rearrange tags and changelog
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=106431
Cc: Thierry Reding <treding@nvidia.com>
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Acked-by: Ben Skeggs <bskeggs@redhat.com>
Cc: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: stable@vger.kernel.org # v4.3
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Add a new debug class for _verbose_ debug message from the vblank code.
That is message we spew out potentially for every vblank interrupt.
Thierry already got annoyed at the spew, and now I managed to lock up
my box with these debug prints (seems serial console + a few debug
prints every vblank aren't a good combination).
Or should I maybe call it DRM_DEBUG_IRQ?
Cc: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
String literals get concatenated just fine on their own,
no need to use '\'.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drm_vblank_count() returns the software counter. We should not pretend
it's the hw counter since we use the hw counter to figuere out what the
software counter value should be. So instead provide a new function
drm_vblank_no_hw_counter() for drivers that don't have a real hw
counter. The new function simply returns 0, which is about the only
thing it can do.
Cc: Vincent Abriou <vincent.abriou@st.com>
Cc: Thierry Reding <treding@nvidia.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Vincent Abriou <vincent.abriou@st.com>
[danvet: s/int pipe/unsigned int pipe/ to follow Thierry's interface
change.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This continues the pattern started in commit cc1ef118fc ("drm/irq:
Make pipe unsigned and name consistent"). This is applied to the public
APIs and driver callbacks, so pretty much all drivers need to be updated
to match the new prototypes.
Cc: Christian König <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
Cc: Inki Dae <inki.dae@samsung.com>
Cc: Jianwei Wang <jianwei.wang.chn@gmail.com>
Cc: Alison Wang <alison.wang@freescale.com>
Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Philipp Zabel <p.zabel@pengutronix.de>
Cc: David Airlie <airlied@linux.ie>
Cc: Rob Clark <robdclark@gmail.com>
Cc: Ben Skeggs <bskeggs@redhat.com>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Mark Yao <mark.yao@rock-chips.com>
Cc: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Cc: Vincent Abriou <vincent.abriou@st.com>
Cc: Thomas Hellstrom <thellstrom@vmware.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
If we couldn't get a high precisions vblank timestamp, we currently
store a zeroed timestamp instead and assume the next vblank irq to
get us something better. This makes sense when trying to update the
timestamp from eg. vblank enable. But if we do this from the vblank
irq we will never get a vblank timestamp unless we high precision
timestamps are available and succeeded. This break weston for instance
on drivers lacking high precision timestamps.
To fix this, zero the timestamp only when not called from vbl irq.
When called from the irq, we still want the timestamp, even if not
perfect.
This fixes a regression from
4dfd64862f drm: Use vblank timestamps to guesstimate how many vblanks were missed
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Thierry Reding <thierry.reding@gmail.com>
Reported-by: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Tested-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This function is the KMS native variant of drm_vblank_count_and_time().
It takes a struct drm_crtc * instead of a struct drm_device * and an
index of the CRTC.
Eventually the goal is to access vblank data through the CRTC only so
that the per-CRTC data can be moved to struct drm_crtc.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Since the original crtc parameter was renamed to pipe, there is no
longer a need to artificially prefix the CRTC parameter.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
When lacking am accurate hardware frame counter, we can fall back to
using the vblank timestamps to guesstimagte how many vblanks have
elapsed since the last time the vblank counter was updated.
Take the oppostunity to unify the vblank_disable_and_save() and
drm_handle_vblank_events() to call the same function
(drm_update_vblank_count()) to perform the vblank updates.
If the hardware/driver has an accurate frame counter use it instead of
the timestamp based guesstimate. If the hardware/driver has neither
a frame counter nor acurate vblank timestamps, we fall back to assuming
that each drm_handle_vblank_events() should increment the vblank count
by one.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Remove the NULL 't_vblank' checks from store_vblank() since that will
never happen.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Avoid confusion and don't use 'vbl_status' as both the
.get_scanout_position() return value and the return value from
drm_calc_vbltimestamp_from_scanoutpos().
While at it make 'vbl_status' unsigned and print it as hex in the
debug prints since it's a bitmask.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Pontential infinite loops in the vblank code are a bad idea. Add some
limits.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
We'll soon have use for the 'flags' in drm_update_vblank_count() so pass
it in.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
pixeldur_ns is now unsued, so kill it from drm_vblank_crtc. framedur_ns
is also currently unused but we will have use for it in the near future
so leave it be. linedur_ns is still used by nouveau for some internal
delays.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
linedur_ns, and especially pixeldur_ns are becoming rather inaccurate
to be used for the vblank timestamp correction. With 4k@60 the pixel
duration is already below 2ns, so the amount of error due to the
truncation to nanoseconds is introducing quite a bit of error.
We can avoid such problems if we instead calculate the timestamp
delta_ns directly from the dislay timings, avoiding the use of
these intermediate truncated values.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
[danvet: Squash in fixup from Thierry Reding for amdgpu.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Collect the timestamping constants alongside the rest of the relevant
stuff under drm_vblank_crtc.
We can now get rid of the 'refcrtc' parameter to
drm_calc_vbltimestamp_from_scanoutpos().
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Finish the recent replacement of 'int pipe' with 'unsigned int pipe'
Cc: Thierry Reding <treding@nvidia.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Some of the functions are documented inconsistently. Add Returns:
sections where missing and use consistent style to describe the return
value.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Name all references to the pipe number (CRTC index) consistently to make
it easier to distinguish which is a pipe number and which is a pointer
to struct drm_crtc.
While at it also make all references to the pipe number unsigned because
there is no longer any reason why it should ever be negative.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
When accessing the array of per-CRTC VBLANK structures we must always
check that the index into the array is valid before dereferencing to
avoid crashing.
Signed-off-by: Thierry Reding <treding@nvidia.com>
[danvet: Squash in my own whitespace ocd fixup in drm_vblank_count.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
The drm_send_vblank_event() function treats negative CRTC indices as
meaning that a driver doesn't have proper VBLANK handling. This is the
only place where DRM needs negative CRTC indices, so in order to enable
subsequent cleanup, remove this special case and replace it by the more
obvious check for whether or not VBLANK support was initialized.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
In
commit 99264a61df
Author: Daniel Vetter <daniel.vetter@ffwll.ch>
Date: Wed Apr 15 19:34:43 2015 +0200
drm/vblank: Fixup and document timestamp update/read barriers
I've switched vblank->count from atomic_t to unsigned long and
accidentally created an integer comparison bug in
drm_vblank_count_and_time since vblanke->count might overflow the u32
local copy and hence the retry loop never succeed.
Fix this by consistently using u32.
Cc: Michel Dänzer <michel@daenzer.net>
Reported-by: Michel Dänzer <michel@daenzer.net>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
This patch fix following warnings.
Warning(.//drivers/gpu/drm/drm_irq.c:1279): No description
found for parameter drm_crtc'
Warning(.//drivers/gpu/drm/drm_irq.c:1279): Excess function
parameter 'crtc' description in 'drm_crtc_vblank_reset'
Signed-off-by: Masanari Iida <standby24x7@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Yay, thanks to Gerd for pull this together.
* 'virtio-gpu-drm-next' of git://git.kraxel.org/linux:
Add MAINTAINERS entry for virtio-gpu.
Add virtio gpu driver.
drm_vblank_get: don't WARN_ON in case vblanks are not initialized
break kconfig dependency loop
dev->max_vblank_count contains the largest value that can be represented
by the hardware counter. When the hardware counter wraps around, we have
to add that value + 1 to get the same value as if the hardware counter
didn't wrap around.
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Since commit 844b03f277 we make
sure that after vblank irq off, we return the last valid
(vblank count, vblank timestamp) pair to clients, e.g., during
modesets, which is good.
An overlooked side effect of that commit for kms drivers without
support for precise vblank timestamping is that at vblank irq
enable, when we update the vblank counter from the hw counter, we
can't update the corresponding vblank timestamp, so now we have a
totally mismatched timestamp for the new count to confuse clients.
Restore old client visible behaviour from before Linux 3.18, but
zero out the timestamp at vblank counter update (instead of disable
as in original implementation) if we can't generate a meaningful
timestamp immediately for the new vblank counter. This will fix
this regression, so callers know they need to retry again later
if they need a valid timestamp, but at the same time preserves
the improvements made in the commit mentioned above.
v2: Rebased on top of Daniel Vetter's fixup and documentation
patch for timestamp updates. Drop request for stable kernel
backport as this would be more difficult, unless the original
patch would get applied to stable kernels.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Daniel Vetter <daniel@ffwll.ch>
Cc: Dave Airlie <airlied@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
For a kms driver to support immediate disable of vblank
irq's reliably without introducing off by one errors or
other mayhem for clients, it must not only support a
hardware vblank counter query, but also high precision
vblank timestamping, so vblank count and timestamp can be
instantaneously reinitialzed to valid values. Additionally
the exposed hardware counter must behave as if it is
incrementing at leading edge of vblank to avoid off by
one errors during reinitialization of the counter while
the display happens to be inside or close to vblank.
Check during drm_vblank_init that a driver which claims to
be capable of vblank_disable_immediate at least supports
high precision timestamping and prevent use of instant
disable if that isn't present as a minimum requirement.
v2: Changed from DRM_ERROR to DRM_INFO and made message
more clear, as suggested by Michel Dänzer.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Cc: Dave Airlie <airlied@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This was a bit too much cargo-culted, so lets make it solid:
- vblank->count doesn't need to be an atomic, writes are always done
under the protection of dev->vblank_time_lock. Switch to an unsigned
long instead and update comments. Note that atomic_read is just a
normal read of a volatile variable, so no need to audit all the
read-side access specifically.
- The barriers for the vblank counter seqlock weren't complete: The
read-side was missing the first barrier between the counter read and
the timestamp read, it only had a barrier between the ts and the
counter read. We need both.
- Barriers weren't properly documented. Since barriers only work if
you have them on boths sides of the transaction it's prudent to
reference where the other side is. To avoid duplicating the
write-side comment 3 times extract a little store_vblank() helper.
In that helper also assert that we do indeed hold
dev->vblank_time_lock, since in some cases the lock is acquired a
few functions up in the callchain.
Spotted while reviewing a patch from Chris Wilson to add a fastpath to
the vblank_wait ioctl.
v2: Add comment to better explain how store_vblank works, suggested by
Chris.
v3: Peter noticed that as-is the 2nd smp_wmb is redundant with the
implicit barrier in the spin_unlock. But that can only be proven by
auditing all callers and my point in extracting this little helper was
to localize all the locking into just one place. Hence I think that
additional optimization is too risky.
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Peter Hurley <peter@hurleysoftware.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
- Y tiling support for scanout from Tvrtko&Damien
- Remove more UMS support
- some small prep patches for OLR removal from John Harrison
- first few patches for dynamic pagetable allocation from Ben Widawsky, rebased
by tons of other people
- DRRS support patches (Sonika&Vandana)
- fbc patches from Paulo
- make sure our vblank callbacks aren't called when the pipes are off
- various patches all over
* tag 'drm-intel-next-2015-02-27' of git://anongit.freedesktop.org/drm-intel: (61 commits)
drm/i915: Update DRIVER_DATE to 20150227
drm/i915: Clarify obj->map_and_fenceable
drm/i915/skl: Allow Y (and Yf) frame buffer creation
drm/i915/skl: Update watermarks for Y tiling
drm/i915/skl: Updated watermark programming
drm/i915/skl: Adjust get_plane_config() to support Yb/Yf tiling
drm/i915/skl: Teach pin_and_fence_fb_obj() about Y tiling constraints
drm/i915/skl: Adjust intel_fb_align_height() for Yb/Yf tiling
drm/i915/skl: Allow scanning out Y and Yf fbs
drm/i915/skl: Add new displayable tiling formats
drm/i915: Remove DRIVER_MODESET checks from modeset code
drm/i915: Remove regfile code&data for UMS suspend/resume
drm/i915: Remove DRIVER_MODESET checks from gem code
drm/i915: Remove DRIVER_MODESET checks in the gpu reset code
drm/i915: Remove DRIVER_MODESET checks from suspend/resume code
drm/i915: Remove DRIVER_MODESET checks in load/unload/close code
drm/i915: fix a printk format
drm/i915: Add media rc6 residency file to sysfs
drm/i915: Add missing description to parameter in alloc_pt_range
drm/i915: Removed the read of RP_STATE_CAP from sysfs/debugfs functions
...
drm_crtc_vblank_get() is the new drm_vblank_get(), not the new
drm_vblank_off().
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
KMS drivers are in full control of their irq and vblank handling, if
they get a vblank interrupt before drm_vblank_init or after
drm_vblank_cleanup that's just a driver bug.
For ums driver there's only r128 and radeon which support vblank, and
they call drm_vblank_init in their driver load functions. Which again
means that userspace can do whatever it wants with interrupt, vblank
structures will always be there.
So this should never happen, let's catch driver issues with a WARN_ON.
Motivated by some discussions with Imre.
v2: Use WARN_ON_ONCE as suggested by Imre.
Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
The pipe might already have been shut down, and then it's not a good
idea to call hw accessor functions. Instead use the same logic as
drm_vblank_off which has all the necessary checks to avoid troubles or
inconsistency.
Noticed by Imre while reviewing my patches to remove some sanity
checks from ->get_vblank_counter.
v2: Try harder. disable_and_save can still access the vblank stuff
when vblank->enabled isn't set. It has to, since vlbank irq could be
disable but the pipe is still on when being called from
drm_vblank_off. But we still want to use that code for more code
sharing. So add a check for vblank->enabled on top - if that's not set
we shouldn't have anyone waiting for the vblank. If we have that's a
pretty serious bug.
The other issue that Imre spotted is drm_vblank_cleanup. That code
again calls disable_and_save and so suffers from the same issues. But
really drm_irq_uninstall should have cleaned that all up, so replace
the code with WARN_ON. Note that we can't delete the timer cleanup
since drivers aren't required to use drm_irq_install/uninstall, but
can do their own irq handling.
v3: Make it clear that all that gunk in drm_irq_uninstall is really
just bandaids for UMS races between the irq/vblank code. In UMS
userspace is in control of enabling/disabling interrupts in general
and vblanks specifically.
v4: Imre observed that KMS drivers all call drm_vblank_cleanup before
drm_irq_uninstall (as they should), so again the code in there is dead
for KMS (due to dev->num_crtcs == 0 after drm_vblank_cleanup). Or
should be, so only WARN for KMS - with UMS userspace could try to do
evil things.
v5: After more discussion on irc we've gone back to v3: the
del_timer_sync is required in all cases in drm_vblank_cleanup, but
let's restrict the WARN_ON to kms drivers only. Imre was also
concerned that bad things could happen without the disable_and_save
call. But we immediately free vblank structures afterwards which makes
the save useless. And drm_handle_vblank has a check for dev->num_crtcs
to avoid surprises with ums.
Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
At driver load we need to tell the vblank code about the state of the
pipes, so that the logic around reject vblank_get when the pipe is off
works correctly.
Thus far i915 used drm_vblank_off, but one of the side-effects of it
is that it also saves the vblank counter. And for that it calls down
into the ->get_vblank_counter hook. Which isn't really a good idea
when the pipe is off for a few reasons:
- With runtime pm the register might not respond.
- If the pipe is off some datastructures might not be around or
unitialized.
The later is what blew up on gen3: We look at intel_crtc->config to
compute the vblank counter, and for a disabled pipe at boot-up that's
just not there. Thus far this was papered over by a check for
intel_crtc->active, but I want to get rid of that (since it's fairly
race, vblank hooks are called from all kinds of places).
So prep for that by adding a _reset functions which only does what we
really need to be done at driver load: Mark the vblank pipe as off,
but don't do any vblank counter saving or event flushing - neither of
that is required.
v2: Clarify the code flow slightly as suggested by Ville.
v3: Fix kerneldoc spelling, spotted by Laurent.
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Imre Deak <imre.deak@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com> (v2)
Acked-by: Dave Airlie <airlied@redhat.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
The .enable_vblank() operation is only called when vblank interrupts are
disabled, but no similar check exists when disabling vblank interrupts.
This leads to .disable_vblank() being called with vblank interrupts
already disabled and the device possibly runtime suspended. As the
operation is called with a spinlock held drivers can't runtime resume
the device there and thus must avoid touching device registers in that
case, requiring vblank refcounting.
As the DRM core tracks whether vblank interrupts are enabled just skip
the .disable_vblank() call when the interrupts are already disabled.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Misc drm patches with mostly polish patches from Thierry, with a bit of
generic mode validation from Ville and a few other oddball things.
* tag 'topic/core-stuff-2014-12-19' of git://anongit.freedesktop.org/drm-intel: (25 commits)
drm: Include drm_crtc_helper.h in DocBook
drm: Make drm_crtc_helper.h standalone includible
drm: Move IRQ related fields to proper section
drm: Remove stale comment
drm: Do basic sanity checks for user modes
drm: Perform basic sanity checks on probed modes
drm: Reorganize probed mode validation
drm/doc: Remove duplicate "by"
drm/info: Remove unused code
drm/cache: Use wbinvd helpers
drm/plane-helper: Test for plane disable earlier
drm/doc: Document drm_add_modes_noedid() usage
drm: bit of spell-check / editorializing.
drm: Prefer sizeof(type) over sizeof type
drm: Remove useless else block
drm: Remove unneeded braces for single statement blocks
drm: Do not assign in if condition
drm: Prefer kmalloc_array() over kmalloc() with multiply
drm: Prefer kcalloc() over kzalloc() with multiply
drm: Miscellaneous checkpatch whitespace cleanups
...
This function is the KMS native variant of drm_vblank_count(). It takes
a struct drm_crtc * instead of a struct drm_device * and an index of the
CRTC.
Eventually the goal is to access vblank data through the CRTC only so
that the per-CRTC data can be moved to struct drm_crtc.
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This function is the KMS native variant of drm_handle_vblank(). It takes
a struct drm_crtc * instead of a struct drm_device * and an index of the
CRTC.
Eventually the goal is to access vblank data through the CRTC only so
that the per-CRTC data can be moved to struct drm_crtc.
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Thierry Reding <treding@nvidia.com>
This function is the KMS native variant of drm_send_vblank_event(). It
takes a struct drm_crtc * instead of a struct drm_device * and an index
of the CRTC.
Eventually the goal is to access vblank data through the CRTC only so
that the per-CRTC data can be moved to struct drm_crtc.
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Thierry Reding <treding@nvidia.com>
sizeof(type) is the variant used most commonly and required by
checkpatch.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
A couple of whitespace changes required to silent various errors and
warnings flagged by checkpatch.
checkpatch requires that the opening brace be on the same line as a
variable declaration. Furthermore an empty line is required after a
block of variable declarations. Trailing whitespace as well as using
spaces before tabs is considered an error or warning, respectively.
Finally, the closing parenthesis of an if condition and the opening
brace of the conditional block should be separated by a space.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Spotted while reviewing the DRM changes in Linux 3.18 for LinuxFR.
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Martin Peres <martin.peres@free.fr>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Let's make things a bit easier to debug when things go bad (potentially
under console_lock).
Signed-off-by: Rob Clark <robdclark@gmail.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This patch fix spelling typos found in drm.xml.
It is because the file is generated from comments in
source codes, I have to fix the typos within source files.
Signed-off-by: Masanari Iida <standby24x7@gmail.com>
Acked-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This replicates what we've done in i915 in
commit 31e4b89acb
Author: Damien Lespiau <damien.lespiau@intel.com>
Date: Mon Aug 18 13:51:00 2014 +0100
drm/i915: Print the pipe on which the vblank wait times out
to make sure that when we switch i915 to drm_wait_one_vblank that the
debug output doesn't regress.
Cc: Damien Lespiau <damien.lespiau@intel.com>
Cc: Thomas Wood <thomas.wood@intel.com>
Reviewed-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
If we already have a timestamp for the current vblank counter, don't
update it with a new timestmap. Small errors can creep in between two
timestamp queries for the same vblank count, which could be confusing to
userspace when it queries the timestamp for the same vblank sequence
number twice.
This problem gets exposed when the vblank disable timer is not used
(or is set to expire quickly) and thus we can get multiple vblank
disable<->enable transition during the same frame which would all
attempt to update the timestamp with the latest estimate.
Testcase: igt/kms_flip/flip-vs-expired-vblank
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
v2:Mario: Trivial rebase on top of current drm-next (13-Sep-2014)
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This allows us to drop 2 header declarations from drmP.h. The 3rd one
is also used in drm_ioctl.c, so for that create a new drm_internal.h
header for non-legacy non-kms (since we have internal headers for
those parts already) declarations private to drm.ko.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Dave asked me to do the backmerge before sending him the revised pull
request, so here we go. Nothing fancy in the conflicts, just a few
things changed right next to each another.
Conflicts:
drivers/gpu/drm/drm_irq.c
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
I've read INVBL as "invalid backlight" and got mightly confused.
The #defines are already fairly long and we can afford to extend
them a bit more without resulting in ugly code all over.
I'm not sure how useful the complicated bitmask return value of these
functions really are since no one checks them. But for now let's keep
things as is.
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Imo u32 hints at a register value, but in reality all callers only
care whether the sampled timestamp is precise or not. So give them
just a bool.
Also move the declaration out of drmP.h, it's only used in drm_irq.c.
v2: Also drop the EXPORT_SYMBOL, spotted by Mario.
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Drivers without a hardware vblank counter simply can't account for the
vblanks that happened while the vblank interrupt was off. To check
this grab a vblank timestamp and if the result is dubious follow the
normal save-and-disable logic.
Drivers should prevent this by setting vblank_disable_allowed = false,
but since running vblank interrupts constantly is not good for power
consumption most drivers lie. Testing for precise vblank timestamps is
the next best thing we can check for.
Suggested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
With the new support for immediate vblank disabling we always disabled
the vblank interrupt right away, irrespective of the vblank offdelay
setting.
But being able to let vblanks run forever is fairly useful for
debugging, so restore that behaviour.
Suggested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Mario Kleiner <mario.kleiner.de@gmail.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Calling vblank_disable_fn() will cause that function to no-op
if !dev->vblank_disable_allowed for some kms drivers, e.g.,
on nouveau-kms. This can cause the gpu vblank irq's to not get
disabled before freeing the dev->vblank array, so if a
vblank irq fires and calls into drm_handle_vblank() after
drm_vblank_cleanup() completes, it will cause use-after-free
access to dev->vblank array.
Call vblank_disable_and_save unconditionally, so vblank irqs
are guaranteed to be off, before we delete the data structures
on which they operate.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
[danvet: Fix subsystem name in patch subject.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
So small drm stuff all over for 3.18. Biggest one is the cmdline parsing
from Chris with a few fixes from me to make it work for stupid kernel
configs.
Plus the atomic prep series.
Tested for more than a week in -nightly and Ville/Imre indeed discovered
some fun which is now fixed (and i915 vblank patches postponed since the
fixups need this branch plus drm-intel-next merged together).
* tag 'topic/core-stuff-2014-08-15' of git://anongit.freedesktop.org/drm-intel:
drm: Use the type of the array element when reallocating
drm: Don't return 0 for a value used as a denominator
drm: Docbook fixes
drm/irq: Implement a generic vblank_wait function
drm: Add a plane->reset hook
drm: trylock modest locking for fbdev panics
drm: Move ->old_fb from crtc to plane
drm: Handle legacy per-crtc locking with full acquire ctx
drm: Move modeset_lock_all helpers to drm_modeset_lock.[hc]
drm: Add drm_plane/connector_index
drm: idiot-proof vblank
drm: Warn when leaking flip events on close
drm: Perform cmdline mode parsing during connector initialisation
video/fbdev: Always built-in video= cmdline parsing
drm: Don't grab an fb reference for the idr
As usual in both a crtc index and a struct drm_crtc * version.
The function assumes that no one drivers their display below 10Hz, and
it will complain if the vblank wait takes longer than that.
v2: Also check dev->max_vblank_counter since some drivers register a
fake get_vblank_counter function.
v3: Use drm_vblank_count instead of calling the low-level
->get_vblank_counter callback. That way we'll get the sw-cooked
counter for platforms without proper vblank support and so can ditch
the max_vblank_counter check again.
v4: Review from Michel Dänzer:
- Restore lost notes about v3:
- Spelling in kerneldoc.
- Inline wait_event condition.
- s/vblank_wait/wait_one_vblank/
Cc: Michel Dänzer <michel@daenzer.net>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drm_vblank_cleanup() would operate on non-existent dev->vblank
data structure, as failure to allocate that data structure is
what triggers the error path in the first place.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
During vblank disable the code tries to guess based on the
timestamps whether we just missed one vblank or not. And if so
it increments the counter. However it forgets to store the new
timestamp to the approriate slot in our timestamp ring buffer.
So anyone querying the timestamp for the resulting sequence
number would get a stale timestamp. Fix it up by storing the
new timestamp.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Now that drm_update_vblank_count() can be called even when we're not
about to enable the vblank interrupts we shouldn't print debug messages
stating otherwise.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
If the user is interested in getting accurate vblank sequence
numbers all the time they may disable the vblank disable timer
entirely. In that case it seems appropriate to kick start the
vblank interrupts already from drm_vblank_on().
v2: Adapt to the drm_vblank_offdelay ==0 vs <0 changes
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Add a flag to drm_device which will cause the vblank code to bypass the
disable timer and always disable the vblank interrupt immediately when
the last reference is dropped.
v2: Add some notes about the flag to the kernel doc
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Make drm_vblank_put() disable the vblank interrupt immediately when the
refcount drops to zero and drm_vblank_offdelay<0.
v2: Preserve the current drm_vblank_offdelay==0 'never disable' behaviur
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Currently it's possible that the following will happen:
1. drm_wait_vblank() calls drm_vblank_get()
2. drm_vblank_off() gets called
3. drm_wait_vblank() calls drm_queue_vblank_event() which
adds the event to the queue event though vblank interrupts
are currently disabled (and may not be re-enabled ever again).
To fix the problem, add another vblank->enabled check into
drm_queue_vblank_event().
drm_vblank_off() holds event_lock around the vblank disable,
so no further locking needs to be added to drm_queue_vblank_event().
vblank disable from another source is not possible since
drm_wait_vblank() already holds a vblank reference.
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Currently both drm_irq.c and several drivers call drm_vblank_put()
while holding event_lock. Now that drm_vblank_put() can disable the
vblank interrupt directly it may need to grab vbl_lock and
vblank_time_lock. That causes deadlocks since we take the locks
in the opposite order in two places in drm_irq.c. So let's make
sure the locking order is always event_lock->vbl_lock->vblank_time_lock.
In drm_vblank_off() pull up event_lock from underneath vbl_lock. Hold
the event_lock across the whole operation to make sure we only send
out the events that were on the queue when we disabled the interrupt,
and not ones that got added just after (assuming drm_vblank_on() already
managed to get called somewhere between).
To sort the other deadlock pull the event_lock out from
drm_handle_vblank_events() into drm_handle_vblank() to be taken outside
vblank_time_lock. Add the appropriate assert_spin_locked() to
drm_handle_vblank_events().
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
When drm_vblank_on() is called the hardware vblank counter may have
been reset, so we can't trust that the old values sampled prior to
drm_vblank_off() have anything to do with the new values.
So update the .last count in drm_vblank_on() to make the first
drm_vblank_enable() consider that as the reference point. This
will correct the user space visible counter to account for the
time between drm_vblank_on() and the first drm_vblank_enable()
calls.
For extra safety subtract one from the .last count in drm_vblank_on()
to make sure that user space will never see the same counter value
before and after modeset.
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
If the vblank irq has already been disabled (via the disable timer) when
we call drm_vblank_off() sample the counter and timestamp one last time.
This will make the sure that the user space visible counter will account
for time between vblank irq disable and drm_vblank_off().
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Move drm_update_vblank_count() to avoid forward a declaration.
No functional change.
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Clearing the timestamps causes us to send zeroed timestamps to userspace
if they get sent out in response to the drm_vblank_off(). It's better
to send the very latest timestamp and count instead.
Testcase: igt/kms_flip/modeset-vs-vblank-race
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Make sure drm_vblank_get() never succeeds when called between
drm_vblank_off() and drm_vblank_on(). Borrow a trick from the
old drm_vblank_{pre,post}_modeset() functions and just bump
the refcount in drm_vblank_off() and drop it in drm_vblank_on().
When drm_vblank_get() encounters a >0 refcount and the vblank
interrupt is already disabled it will simply return -EINVAL.
Hopefully the use of inmodeset won't conflict badly with
drm_vblank_{pre,post}_modeset().
For i915 there's a window between drm_vblank_off() and marking the
crtc as inactive where the current code still allows drm_vblank_get().
v2: Describe what drm_vblank_get() does to explain how
a simple refcount bump manages to fix things (Daniel)
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
After spending slightly more time than I'd care to admit debugging the
various and presumably spectacular way things fail when you pass too low
a value to drm_vblank_init() (thanks console-lock for not letting me see
the carnage!), I decided it might be a good idea to add some sanity
checking.
Signed-off-by: Rob Clark <robdclark@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Convert the monotonic timestamp with ktime_mono_to_real() in
drm_calc_vbltimestamp_from_scanoutpos().
In get_drm_timestamp we can call either ktime_get() or
ktime_get_real() depending on drm_timestamp_monotonic. No point in
having two calls into the core for CLOCK_REALTIME.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Pull drm updates from Dave Airlie:
"This is the main drm merge window pull request, changes all over the
place, mostly normal levels of churn.
Highlights:
Core drm:
More cleanups, fix race on connector/encoder naming, docs updates,
object locking rework in prep for atomic modeset
i915:
mipi DSI support, valleyview power fixes, cursor size fixes,
execlist refactoring, vblank improvements, userptr support, OOM
handling improvements
radeon:
GPUVM tuning and large page size support, gart fixes, deep color
HDMI support, HDMI audio cleanups
nouveau:
- displayport rework should fix lots of issues
- initial gk20a support
- gk110b support
- gk208 fixes
exynos:
probe order fixes, HDMI changes, IPP consolidation
msm:
debugfs updates, misc fixes
ast:
ast2400 support, sync with UMS driver
tegra:
cleanups, hdmi + hw cursor for Tegra 124.
panel:
fixes existing panels add some new ones.
ipuv3:
moved from staging to drivers/gpu"
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (761 commits)
drm/nouveau/disp/dp: fix tmds passthrough on dp connector
drm/nouveau/dp: probe dpcd to determine connectedness
drm/nv50-: trigger update after all connectors disabled
drm/nv50-: prepare for attaching a SOR to multiple heads
drm/gf119-/disp: fix debug output on update failure
drm/nouveau/disp/dp: make use of postcursor when its available
drm/g94-/disp/dp: take max pullup value across all lanes
drm/nouveau/bios/dp: parse lane postcursor data
drm/nouveau/dp: fix support for dpms
drm/nouveau: register a drm_dp_aux channel for each dp connector
drm/g94-/disp: add method to power-off dp lanes
drm/nouveau/disp/dp: maintain link in response to hpd signal
drm/g94-/disp: bash and wait for something after changing lane power regs
drm/nouveau/disp/dp: split link config/power into two steps
drm/nv50/disp: train PIOR-attached DP from second supervisor
drm/nouveau/disp/dp: make use of existing output data for link training
drm/gf119/disp: start removing direct vbios parsing from supervisor
drm/nv50/disp: start removing direct vbios parsing from supervisor
drm/nouveau/disp/dp: maintain receiver caps in response to hpd signal
drm/nouveau/disp/dp: create subclass for dp outputs
...
Noticed by Thierry Reding in his review, but I've merged the drm
vblank rework topic branch a bit too quickly. So separate fixup.
Cc: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
We need to start somewhere ... With this the only places left in i915
where we use pipe integers is in the interrupt handling code. And
there it actually makes some amount of sense.
v2:
- Polish kerneldoc a bit (Thierry).
- Drop "dev" parameter since it's unecessary.
- Split out i915 changes (Thierry).
Cc: Thierry Reding <thierry.reding@gmail.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
- Integrate into the drm DocBook
- Disable kerneldoc for functions not exported to drivers.
- Properly document the new drm_vblank_on|off and add cautious
comments explaining when drm_vblank_pre|post_modesets shouldn't be
used.
- General polish and OCD.
v2: Polish as suggested by Thierry.
Cc: Thierry Reding <thierry.reding@gmail.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drm_vblank_off() will turn off vblank interrupts, but as long as the
refcount is elevated drm_vblank_get() will not re-enable them. This
is a problem is someone is holding a vblank reference while a modeset is
happening, and the driver requires vblank interrupt to work during that
time.
Add drm_vblank_on() as a counterpart to drm_vblank_off() which will
re-enabled vblank interrupts if the refcount is already elevated. This
will allow drivers to choose the specific places in the modeset sequence
at which vblank interrupts get disabled and enabled.
Testcase: igt/kms_flip/*-vs-suspend
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
[danvet: Add Testcase tag for the igt I've written.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
If there's a blocking vblank wait in progress while the vblank interrupt
gets disabled, the current code will just let the vblank wait time out.
Instead make it return immediately when vblank interrupts get disabled.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Currently there's one per-device vblank disable timer, and it gets
reset wheneven the vblank refcount for any crtc drops to zero. That
means that one crtc could accidentally be keeping the vblank interrupts
for other crtcs enabled even if there are no users for them. Make the
disable timer per-crtc to avoid this issue.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
The irq flags state is already established by the outer
spin_lock_irqsave(); re-disabling irqs is redundant.
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This was only ever used to pretty-print the irq driver name. And on
kms systems due to set_version bonghits we never set up the prettier
name, ever. Which make this a bit pointless.
Also, we can always dig out the driver-instance/irq relationship
through other means, so this isn't that useful. So just rip it out to
simplify the set_version/set_busid insanity a bit.
Also delete the temporary busname from drm_pci_set_busid, it's now
unused.
v2: Rebase on top of the new host1x drm_bus for tegra.
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Unfortunately this requires a drm-wide change, and I didn't see a sane
way around that. Luckily it's fairly simple, we just need to inline
the respective get_irq implementation from either drm_pci.c or
drm_platform.c.
With that we can now also remove drm_dev_to_irq from drm_irq.c.
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
It's only ever called for legacy drivers, which are all pci.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
To get rid of the dev->bus->get_irq callback we need to pass in the
desired irq explicitly into drm_irq_install. To avoid having to do the
same for drm_irq_unistall just track it internally. That leaves
drivers with less room to botch things up.
v2: Add the hunk lost in an earlier patch to this one (Thierry).
v3: Fix up the totally fumbled logic in drm_irq_install and use the
local variable consistently. Spotted by both Thierry and Laurent.
Shame on me for failing to properly test the rebase version of this
patch ...
Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Only used in some legacy pci drivers, and dereferencing the PCI irq is
actually shorter ...
Since this removes all users for drm_dev_to_irq from the tree except
in drm_irq.c, move the inline helper in there. It'll disappear soon,
too.
v2: Polish commit message (Thierry)
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
The dev->struct_mutex locking in drm_irq.c only protects
dev->irq_enabled. Which isn't really much at all and only prevents
especially nasty ums userspace from concurrently installing the
interrupt handling a few times. Or at least trying.
There are tons of unlocked readers of dev->irqs_enabled in the vblank
wait code (and by extension also in the pageflip code since that uses
the same vblank timestamp engine).
Real modesetting drivers should ensure that nothing can go haywire
with a sane setup teardown sequence. So we only really need this for
the drm_control ioctl, everywhere else this will just paper over
nastiness.
Note that drm/i915 is a bit specially due to the gem+ums combination.
So there we also need to properly protect the entervt and leavevt
ioctls. But it's definitely saner to do everything in one go than to
drop the lock in-between.
Finally there's the gpu reset code in drm/i915. That one's just race
(concurrent userspace calls to for vblank waits of pageflips could
spuriously fail). So wrap it up in with a nice comment since fixing
this is more involved.
v2: Rebase and fix commit message (Thierry)
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This is a ums-only ioctl, and we've only ever supported ums (at least
in upstream) on pci devices. So no point in keeping that piece of
legacy logic abstracted within the drm bus driver.
To keep things work without CONFIG_PCI also add a dummy ioctl.
v2: Block the irq_by_busid ioctl for modeset drivers.
v3: Spelling/whitespace polish (Thierry)
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Checking for both an irq number _and_ whether it's enabled is
redundant. Originally I've thought the drm_dev_to_irq call would break
drivers which do their own irq checking, but those shouldn't have
DRIVER_HAVE_IRQ set as Thierry Reding pointed out. But such drivers
already need to set dev->irq_enabled for other reasons, so we might as
well ditch that check, too.
v2: Also drop the HAVE_IRQ check.
Cc: Thierry Reding <thierry.reding@gmail.com>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
i915 doesn't need this kludge for most platforms. Although we do
appear to need something similar on certain platforms, but we can
be more accurate when we apply the adjustment since we know exactly
why the scanline counter doesn't always quite match the vblank
status.
Also the current code doesn't handle interlaced modes correctly,
and we already deal with interlaced modes in i915 code.
So let's just move the current code to radeon_get_crtc_scanoutpos()
since that's why it was added. For i915 we'll add a more finely
targeted variant.
v2: Fix vpos vs. *vpos bug (Mario)
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Preparation for moving the early vblank IRQ logic into
radeon_get_crtc_scanoutpos().
v2: Fix radeon_drv.c compile warning (Mario)
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
We're currently miscalculating the line and pixel durations for
interlaced modes. crtc_htotal and crtc_vtotal are the full frame
timings, and so is crtc_clock, so we can compute the line
and pixel durations from those w/o any extra adjustments. But
we actually want framedur_ns to be the field, not frame, duration,
so we must divide it by two.
This should make the scanout based vblank timestamp corrections
work correctly with interlaced modes, at least for i915. It all
depends whether we keep the field or frame timings in the display
mode crtc_ timings.
v2: Preserve halve->half typo fix that happened in the meantine
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>