Commit 6357c812 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-2019-03-01' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "Three final fixes, one for a feature that is new in this kernel, one
  bochs fix for qemu riscv and one atomic modesetting fix.

  I've left a few of the other late fixes until next as I didn't want to
  throw in anything that wasn't really necessary"

* tag 'drm-fixes-2019-03-01' of git://anongit.freedesktop.org/drm/drm:
  drm/bochs: Fix the ID mismatch error
  drm: Block fb changes for async plane updates
  drm/amd/display: Use vrr friendly pageflip throttling in DC.
parents bf23aba1 17fb465f
...@@ -405,6 +405,7 @@ struct amdgpu_crtc { ...@@ -405,6 +405,7 @@ struct amdgpu_crtc {
struct amdgpu_flip_work *pflip_works; struct amdgpu_flip_work *pflip_works;
enum amdgpu_flip_status pflip_status; enum amdgpu_flip_status pflip_status;
int deferred_flip_completion; int deferred_flip_completion;
u64 last_flip_vblank;
/* pll sharing */ /* pll sharing */
struct amdgpu_atom_ss ss; struct amdgpu_atom_ss ss;
bool ss_enabled; bool ss_enabled;
......
...@@ -303,12 +303,11 @@ static void dm_pflip_high_irq(void *interrupt_params) ...@@ -303,12 +303,11 @@ static void dm_pflip_high_irq(void *interrupt_params)
return; return;
} }
/* Update to correct count(s) if racing with vblank irq */
amdgpu_crtc->last_flip_vblank = drm_crtc_accurate_vblank_count(&amdgpu_crtc->base);
/* wake up userspace */ /* wake up userspace */
if (amdgpu_crtc->event) { if (amdgpu_crtc->event) {
/* Update to correct count(s) if racing with vblank irq */
drm_crtc_accurate_vblank_count(&amdgpu_crtc->base);
drm_crtc_send_vblank_event(&amdgpu_crtc->base, amdgpu_crtc->event); drm_crtc_send_vblank_event(&amdgpu_crtc->base, amdgpu_crtc->event);
/* page flip completed. clean up */ /* page flip completed. clean up */
...@@ -4828,6 +4827,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, ...@@ -4828,6 +4827,8 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc)); to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc));
int planes_count = 0; int planes_count = 0;
unsigned long flags; unsigned long flags;
u64 last_flip_vblank;
bool vrr_active = acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE;
/* update planes when needed */ /* update planes when needed */
for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) { for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
...@@ -4859,6 +4860,16 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, ...@@ -4859,6 +4860,16 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
/* In commit tail framework this cannot happen */ /* In commit tail framework this cannot happen */
WARN_ON(1); WARN_ON(1);
} }
/* For variable refresh rate mode only:
* Get vblank of last completed flip to avoid > 1 vrr flips per
* video frame by use of throttling, but allow flip programming
* anywhere in the possibly large variable vrr vblank interval
* for fine-grained flip timing control and more opportunity to
* avoid stutter on late submission of amdgpu_dm_do_flip() calls.
*/
last_flip_vblank = acrtc_attach->last_flip_vblank;
spin_unlock_irqrestore(&crtc->dev->event_lock, flags); spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
if (!pflip_needed || plane->type == DRM_PLANE_TYPE_OVERLAY) { if (!pflip_needed || plane->type == DRM_PLANE_TYPE_OVERLAY) {
...@@ -4882,10 +4893,18 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, ...@@ -4882,10 +4893,18 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
if (plane->type == DRM_PLANE_TYPE_PRIMARY) if (plane->type == DRM_PLANE_TYPE_PRIMARY)
drm_crtc_vblank_get(crtc); drm_crtc_vblank_get(crtc);
/* Use old throttling in non-vrr fixed refresh rate mode
* to keep flip scheduling based on target vblank counts
* working in a backwards compatible way, e.g., clients
* using GLX_OML_sync_control extension.
*/
if (!vrr_active)
last_flip_vblank = drm_crtc_vblank_count(crtc);
amdgpu_dm_do_flip( amdgpu_dm_do_flip(
crtc, crtc,
fb, fb,
(uint32_t)drm_crtc_vblank_count(crtc) + *wait_for_vblank, (uint32_t) last_flip_vblank + *wait_for_vblank,
dc_state); dc_state);
} }
......
...@@ -154,6 +154,10 @@ static int bochs_pci_probe(struct pci_dev *pdev, ...@@ -154,6 +154,10 @@ static int bochs_pci_probe(struct pci_dev *pdev,
if (IS_ERR(dev)) if (IS_ERR(dev))
return PTR_ERR(dev); return PTR_ERR(dev);
ret = pci_enable_device(pdev);
if (ret)
goto err_free_dev;
dev->pdev = pdev; dev->pdev = pdev;
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
......
...@@ -1602,6 +1602,15 @@ int drm_atomic_helper_async_check(struct drm_device *dev, ...@@ -1602,6 +1602,15 @@ int drm_atomic_helper_async_check(struct drm_device *dev,
old_plane_state->crtc != new_plane_state->crtc) old_plane_state->crtc != new_plane_state->crtc)
return -EINVAL; return -EINVAL;
/*
* FIXME: Since prepare_fb and cleanup_fb are always called on
* the new_plane_state for async updates we need to block framebuffer
* changes. This prevents use of a fb that's been cleaned up and
* double cleanups from occuring.
*/
if (old_plane_state->fb != new_plane_state->fb)
return -EINVAL;
funcs = plane->helper_private; funcs = plane->helper_private;
if (!funcs->atomic_async_update) if (!funcs->atomic_async_update)
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment