Skip to content

Commit a2dbb7b

Browse files
committed
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "A bunch of change across the board, the main things are some vblank fallout in radeon and nouveau required some work, but I think this should fix it all. There is also one drm fix for an oops in vmwgfx with how we pass the drm master around. The rest is just some amdgpu, i915, imx and rockchip fixes. Probably more than I'd like at this point, but hopefully things settle down now" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (40 commits) drm/amdgpu: Fixup hw vblank counter/ts for new drm_update_vblank_count() (v3) drm/radeon: Fixup hw vblank counter/ts for new drm_update_vblank_count() (v2) drm/radeon: Retry DDC probing on DVI on failure if we got an HPD interrupt drm/amdgpu: add spin lock to protect freed list in vm (v2) drm/amdgpu: partially revert "drm/amdgpu: fix VM_CONTEXT*_PAGE_TABLE_END_ADDR" v2 drm/amdgpu: take a BO reference for the user fence drm/amdgpu: take a BO reference in the display code drm/amdgpu: set snooped flags only on system addresses v2 drm/nouveau: Fix pre-nv50 pageflip events (v4) drm: Fix an unwanted master inheritance v2 drm/amdgpu: fix race condition in amd_sched_entity_push_job drm/amdgpu: add err check for pin userptr drm/i915: take a power domain reference while checking the HDMI live status drm/i915: add MISSING_CASE to a few port/aux power domain helpers drm/i915/ddi: fix intel_display_port_aux_power_domain() after HDMI detect drm/i915: Introduce a gmbus power domain drm/i915: Clean up AUX power domain handling drm/rockchip: Use CRTC vblank event interface drm/rockchip: Fix module autoload for OF platform driver drm/rockchip: vop: fix window origin calculation ...
2 parents 9cfe521 + df4d4aa commit a2dbb7b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+735
-331
lines changed

drivers/gpu/drm/amd/amdgpu/amdgpu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ struct amdgpu_bo {
539539
/* Constant after initialization */
540540
struct amdgpu_device *adev;
541541
struct drm_gem_object gem_base;
542+
struct amdgpu_bo *parent;
542543

543544
struct ttm_bo_kmap_obj dma_buf_vmap;
544545
pid_t pid;
@@ -955,6 +956,8 @@ struct amdgpu_vm {
955956
struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS];
956957
/* for interval tree */
957958
spinlock_t it_lock;
959+
/* protecting freed */
960+
spinlock_t freed_lock;
958961
};
959962

960963
struct amdgpu_vm_manager {

drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
222222
}
223223

224224
p->uf.bo = gem_to_amdgpu_bo(gobj);
225+
amdgpu_bo_ref(p->uf.bo);
226+
drm_gem_object_unreference_unlocked(gobj);
225227
p->uf.offset = fence_data->offset;
226228
} else {
227229
ret = -EINVAL;
@@ -487,7 +489,7 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo
487489
amdgpu_ib_free(parser->adev, &parser->ibs[i]);
488490
kfree(parser->ibs);
489491
if (parser->uf.bo)
490-
drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base);
492+
amdgpu_bo_unref(&parser->uf.bo);
491493
}
492494

493495
static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p,
@@ -776,7 +778,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job)
776778
amdgpu_ib_free(job->adev, &job->ibs[i]);
777779
kfree(job->ibs);
778780
if (job->uf.bo)
779-
drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base);
781+
amdgpu_bo_unref(&job->uf.bo);
780782
return 0;
781783
}
782784

drivers/gpu/drm/amd/amdgpu/amdgpu_display.c

Lines changed: 79 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
7373
struct drm_crtc *crtc = &amdgpuCrtc->base;
7474
unsigned long flags;
7575
unsigned i;
76+
int vpos, hpos, stat, min_udelay;
77+
struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id];
7678

7779
amdgpu_flip_wait_fence(adev, &work->excl);
7880
for (i = 0; i < work->shared_count; ++i)
@@ -81,6 +83,41 @@ static void amdgpu_flip_work_func(struct work_struct *__work)
8183
/* We borrow the event spin lock for protecting flip_status */
8284
spin_lock_irqsave(&crtc->dev->event_lock, flags);
8385

86+
/* If this happens to execute within the "virtually extended" vblank
87+
* interval before the start of the real vblank interval then it needs
88+
* to delay programming the mmio flip until the real vblank is entered.
89+
* This prevents completing a flip too early due to the way we fudge
90+
* our vblank counter and vblank timestamps in order to work around the
91+
* problem that the hw fires vblank interrupts before actual start of
92+
* vblank (when line buffer refilling is done for a frame). It
93+
* complements the fudging logic in amdgpu_get_crtc_scanoutpos() for
94+
* timestamping and amdgpu_get_vblank_counter_kms() for vblank counts.
95+
*
96+
* In practice this won't execute very often unless on very fast
97+
* machines because the time window for this to happen is very small.
98+
*/
99+
for (;;) {
100+
/* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank
101+
* start in hpos, and to the "fudged earlier" vblank start in
102+
* vpos.
103+
*/
104+
stat = amdgpu_get_crtc_scanoutpos(adev->ddev, work->crtc_id,
105+
GET_DISTANCE_TO_VBLANKSTART,
106+
&vpos, &hpos, NULL, NULL,
107+
&crtc->hwmode);
108+
109+
if ((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
110+
(DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) ||
111+
!(vpos >= 0 && hpos <= 0))
112+
break;
113+
114+
/* Sleep at least until estimated real start of hw vblank */
115+
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
116+
min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5);
117+
usleep_range(min_udelay, 2 * min_udelay);
118+
spin_lock_irqsave(&crtc->dev->event_lock, flags);
119+
};
120+
84121
/* do the flip (mmio) */
85122
adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base);
86123
/* set the flip status */
@@ -109,7 +146,7 @@ static void amdgpu_unpin_work_func(struct work_struct *__work)
109146
} else
110147
DRM_ERROR("failed to reserve buffer after flip\n");
111148

112-
drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
149+
amdgpu_bo_unref(&work->old_rbo);
113150
kfree(work->shared);
114151
kfree(work);
115152
}
@@ -148,8 +185,8 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
148185
obj = old_amdgpu_fb->obj;
149186

150187
/* take a reference to the old object */
151-
drm_gem_object_reference(obj);
152188
work->old_rbo = gem_to_amdgpu_bo(obj);
189+
amdgpu_bo_ref(work->old_rbo);
153190

154191
new_amdgpu_fb = to_amdgpu_framebuffer(fb);
155192
obj = new_amdgpu_fb->obj;
@@ -222,7 +259,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
222259
amdgpu_bo_unreserve(new_rbo);
223260

224261
cleanup:
225-
drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
262+
amdgpu_bo_unref(&work->old_rbo);
226263
fence_put(work->excl);
227264
for (i = 0; i < work->shared_count; ++i)
228265
fence_put(work->shared[i]);
@@ -712,6 +749,15 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
712749
* \param dev Device to query.
713750
* \param pipe Crtc to query.
714751
* \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0).
752+
* For driver internal use only also supports these flags:
753+
*
754+
* USE_REAL_VBLANKSTART to use the real start of vblank instead
755+
* of a fudged earlier start of vblank.
756+
*
757+
* GET_DISTANCE_TO_VBLANKSTART to return distance to the
758+
* fudged earlier start of vblank in *vpos and the distance
759+
* to true start of vblank in *hpos.
760+
*
715761
* \param *vpos Location where vertical scanout position should be stored.
716762
* \param *hpos Location where horizontal scanout position should go.
717763
* \param *stime Target location for timestamp taken immediately before
@@ -776,10 +822,40 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
776822
vbl_end = 0;
777823
}
778824

825+
/* Called from driver internal vblank counter query code? */
826+
if (flags & GET_DISTANCE_TO_VBLANKSTART) {
827+
/* Caller wants distance from real vbl_start in *hpos */
828+
*hpos = *vpos - vbl_start;
829+
}
830+
831+
/* Fudge vblank to start a few scanlines earlier to handle the
832+
* problem that vblank irqs fire a few scanlines before start
833+
* of vblank. Some driver internal callers need the true vblank
834+
* start to be used and signal this via the USE_REAL_VBLANKSTART flag.
835+
*
836+
* The cause of the "early" vblank irq is that the irq is triggered
837+
* by the line buffer logic when the line buffer read position enters
838+
* the vblank, whereas our crtc scanout position naturally lags the
839+
* line buffer read position.
840+
*/
841+
if (!(flags & USE_REAL_VBLANKSTART))
842+
vbl_start -= adev->mode_info.crtcs[pipe]->lb_vblank_lead_lines;
843+
779844
/* Test scanout position against vblank region. */
780845
if ((*vpos < vbl_start) && (*vpos >= vbl_end))
781846
in_vbl = false;
782847

848+
/* In vblank? */
849+
if (in_vbl)
850+
ret |= DRM_SCANOUTPOS_IN_VBLANK;
851+
852+
/* Called from driver internal vblank counter query code? */
853+
if (flags & GET_DISTANCE_TO_VBLANKSTART) {
854+
/* Caller wants distance from fudged earlier vbl_start */
855+
*vpos -= vbl_start;
856+
return ret;
857+
}
858+
783859
/* Check if inside vblank area and apply corrective offsets:
784860
* vpos will then be >=0 in video scanout area, but negative
785861
* within vblank area, counting down the number of lines until
@@ -795,32 +871,6 @@ int amdgpu_get_crtc_scanoutpos(struct drm_device *dev, unsigned int pipe,
795871
/* Correct for shifted end of vbl at vbl_end. */
796872
*vpos = *vpos - vbl_end;
797873

798-
/* In vblank? */
799-
if (in_vbl)
800-
ret |= DRM_SCANOUTPOS_IN_VBLANK;
801-
802-
/* Is vpos outside nominal vblank area, but less than
803-
* 1/100 of a frame height away from start of vblank?
804-
* If so, assume this isn't a massively delayed vblank
805-
* interrupt, but a vblank interrupt that fired a few
806-
* microseconds before true start of vblank. Compensate
807-
* by adding a full frame duration to the final timestamp.
808-
* Happens, e.g., on ATI R500, R600.
809-
*
810-
* We only do this if DRM_CALLED_FROM_VBLIRQ.
811-
*/
812-
if ((flags & DRM_CALLED_FROM_VBLIRQ) && !in_vbl) {
813-
vbl_start = mode->crtc_vdisplay;
814-
vtotal = mode->crtc_vtotal;
815-
816-
if (vbl_start - *vpos < vtotal / 100) {
817-
*vpos -= vtotal;
818-
819-
/* Signal this correction as "applied". */
820-
ret |= 0x8;
821-
}
822-
}
823-
824874
return ret;
825875
}
826876

drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data,
235235
AMDGPU_GEM_USERPTR_REGISTER))
236236
return -EINVAL;
237237

238-
if (!(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) ||
239-
!(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) {
238+
if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && (
239+
!(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) ||
240+
!(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) {
240241

241242
/* if we want to write to it we must require anonymous
242243
memory and install a MMU notifier */

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,13 +611,59 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev,
611611
u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe)
612612
{
613613
struct amdgpu_device *adev = dev->dev_private;
614+
int vpos, hpos, stat;
615+
u32 count;
614616

615617
if (pipe >= adev->mode_info.num_crtc) {
616618
DRM_ERROR("Invalid crtc %u\n", pipe);
617619
return -EINVAL;
618620
}
619621

620-
return amdgpu_display_vblank_get_counter(adev, pipe);
622+
/* The hw increments its frame counter at start of vsync, not at start
623+
* of vblank, as is required by DRM core vblank counter handling.
624+
* Cook the hw count here to make it appear to the caller as if it
625+
* incremented at start of vblank. We measure distance to start of
626+
* vblank in vpos. vpos therefore will be >= 0 between start of vblank
627+
* and start of vsync, so vpos >= 0 means to bump the hw frame counter
628+
* result by 1 to give the proper appearance to caller.
629+
*/
630+
if (adev->mode_info.crtcs[pipe]) {
631+
/* Repeat readout if needed to provide stable result if
632+
* we cross start of vsync during the queries.
633+
*/
634+
do {
635+
count = amdgpu_display_vblank_get_counter(adev, pipe);
636+
/* Ask amdgpu_get_crtc_scanoutpos to return vpos as
637+
* distance to start of vblank, instead of regular
638+
* vertical scanout pos.
639+
*/
640+
stat = amdgpu_get_crtc_scanoutpos(
641+
dev, pipe, GET_DISTANCE_TO_VBLANKSTART,
642+
&vpos, &hpos, NULL, NULL,
643+
&adev->mode_info.crtcs[pipe]->base.hwmode);
644+
} while (count != amdgpu_display_vblank_get_counter(adev, pipe));
645+
646+
if (((stat & (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE)) !=
647+
(DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE))) {
648+
DRM_DEBUG_VBL("Query failed! stat %d\n", stat);
649+
} else {
650+
DRM_DEBUG_VBL("crtc %d: dist from vblank start %d\n",
651+
pipe, vpos);
652+
653+
/* Bump counter if we are at >= leading edge of vblank,
654+
* but before vsync where vpos would turn negative and
655+
* the hw counter really increments.
656+
*/
657+
if (vpos >= 0)
658+
count++;
659+
}
660+
} else {
661+
/* Fallback to use value as is. */
662+
count = amdgpu_display_vblank_get_counter(adev, pipe);
663+
DRM_DEBUG_VBL("NULL mode info! Returned count may be wrong.\n");
664+
}
665+
666+
return count;
621667
}
622668

623669
/**

drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ struct amdgpu_crtc {
407407
u32 line_time;
408408
u32 wm_low;
409409
u32 wm_high;
410+
u32 lb_vblank_lead_lines;
410411
struct drm_display_mode hw_mode;
411412
};
412413

@@ -528,6 +529,10 @@ struct amdgpu_framebuffer {
528529
#define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \
529530
((em) == ATOM_ENCODER_MODE_DP_MST))
530531

532+
/* Driver internal use only flags of amdgpu_get_crtc_scanoutpos() */
533+
#define USE_REAL_VBLANKSTART (1 << 30)
534+
#define GET_DISTANCE_TO_VBLANKSTART (1 << 31)
535+
531536
void amdgpu_link_encoder_connector(struct drm_device *dev);
532537

533538
struct drm_connector *

drivers/gpu/drm/amd/amdgpu/amdgpu_object.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo)
100100
list_del_init(&bo->list);
101101
mutex_unlock(&bo->adev->gem.mutex);
102102
drm_gem_object_release(&bo->gem_base);
103+
amdgpu_bo_unref(&bo->parent);
103104
kfree(bo->metadata);
104105
kfree(bo);
105106
}

drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -587,9 +587,13 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
587587
uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem);
588588
int r;
589589

590-
if (gtt->userptr)
591-
amdgpu_ttm_tt_pin_userptr(ttm);
592-
590+
if (gtt->userptr) {
591+
r = amdgpu_ttm_tt_pin_userptr(ttm);
592+
if (r) {
593+
DRM_ERROR("failed to pin userptr\n");
594+
return r;
595+
}
596+
}
593597
gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT);
594598
if (!ttm->num_pages) {
595599
WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n",
@@ -797,11 +801,12 @@ uint32_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
797801
if (mem && mem->mem_type != TTM_PL_SYSTEM)
798802
flags |= AMDGPU_PTE_VALID;
799803

800-
if (mem && mem->mem_type == TTM_PL_TT)
804+
if (mem && mem->mem_type == TTM_PL_TT) {
801805
flags |= AMDGPU_PTE_SYSTEM;
802806

803-
if (!ttm || ttm->caching_state == tt_cached)
804-
flags |= AMDGPU_PTE_SNOOPED;
807+
if (ttm->caching_state == tt_cached)
808+
flags |= AMDGPU_PTE_SNOOPED;
809+
}
805810

806811
if (adev->asic_type >= CHIP_TOPAZ)
807812
flags |= AMDGPU_PTE_EXECUTABLE;

0 commit comments

Comments
 (0)