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>
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>
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>
Using s64 for the timestamping constants is wasteful. Signed 32bit
integers get us a range of over +-2 seconds. Presuming that no-one
wants to a vrefresh rate less than 0.5, we can switch to using int
for the timestamping constants. We save a few bytes in drm_crtc and
avoid a bunch of 64bit math.
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
drm_calc_timestamping_constants() computes the pixel/line/frame
durations based on the crtc_ timing values. The corresponding pixel
clock is in mode->crtc_clock, so we need to use that instead of
mode->clock.
This should fix drm_calc_timestamping_constants() for frame packing
stereo modes.
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
drm_calc_timestamping_constants() makes the math more complex
than necessary.
- multipying the dotclock by 1000 is pointless, just makes all the
numbers bigger
- div64_u64() is also pointless, div_u64 is enough
- pixeldur_ns doesn't need any 64bit math
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Move the long blurp to into the body of the comment, leaving only
a short summary line at the top.
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Rather than using crtc->hwmode, just pass the relevant mode to
drm_calc_vbltimestamp_from_scanoutpos(). This removes the last hwmode
usage from core drm.
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
We don't really use hwmode anymore in i915, so eliminating its use
from the core code seems prudent. Just pass the appropriate mode
to drm_calc_timestamping_constants().
Reviewed-by: mario.kleiner.de@gmail.com
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
We don't have any userspace interfaces that use HZ as a time unit, so
having our own DRM define is useless.
Remove this remnant from the shared drm core days.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Pull trivial tree updates from Jiri Kosina:
"Usual earth-shaking, news-breaking, rocket science pile from
trivial.git"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial: (23 commits)
doc: usb: Fix typo in Documentation/usb/gadget_configs.txt
doc: add missing files to timers/00-INDEX
timekeeping: Fix some trivial typos in comments
mm: Fix some trivial typos in comments
irq: Fix some trivial typos in comments
NUMA: fix typos in Kconfig help text
mm: update 00-INDEX
doc: Documentation/DMA-attributes.txt fix typo
DRM: comment: `halve' -> `half'
Docs: Kconfig: `devlopers' -> `developers'
doc: typo on word accounting in kprobes.c in mutliple architectures
treewide: fix "usefull" typo
treewide: fix "distingush" typo
mm/Kconfig: Grammar s/an/a/
kexec: Typo s/the/then/
Documentation/kvm: Update cpuid documentation for steal time and pv eoi
treewide: Fix common typo in "identify"
__page_to_pfn: Fix typo in comment
Correct some typos for word frequency
clk: fixed-factor: Fix a trivial typo
...
A change in locking of some kms drivers (currently intel-kms) make
the old approach too inaccurate and also incompatible with the
PREEMPT_RT realtime kernel patchset.
The driver->get_scanout_position() method of intel-kms now needs
to aquire a spinlock, which clashes badly with the former
preempt_disable() calls in the drm, and it also introduces larger
delays and timing uncertainty on a contended lock than acceptable.
This patch changes the prototype of driver->get_scanout_position()
to require/allow kms drivers to perform the ktime_get() system time
queries which go along with actual scanout position readout in a way
that provides maximum precision and to return those timestamps to
the drm. kms drivers implementations of get_scanout_position() are
asked to implement timestamping and scanoutpos readout in a way
that is as precise as possible and compatible with preempt_disable()
on a PREMPT_RT kernel. A driver should follow this pattern in
get_scanout_position() for precision and compatibility:
spin_lock...(...);
preempt_disable_rt(); // On a PREEMPT_RT kernel, otherwise omit.
if (stime) *stime = ktime_get();
... Minimum amount of MMIO register reads to get scanout position ...
... no taking of locks allowed here! ...
if (etime) *etime = ktime_get();
preempt_enable_rt(); // On PREEMPT_RT kernel, otherwise omit.
spin_unlock...(...);
v2: Fix formatting of new multi-line code comments.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Preemption handling will get pushed into the kms
drivers in followup patches, to make timestamping
more robust and PREEMPT_RT friendly.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
irq_enabled is only ever 0 or 1, so make it a bool.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>