diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu.h | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 67 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 108 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 24 |
16 files changed, 277 insertions, 99 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 306f75700bf8..048cfe073dae 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h | |||
@@ -496,6 +496,7 @@ struct amdgpu_bo_va_mapping { | |||
496 | 496 | ||
497 | /* bo virtual addresses in a specific vm */ | 497 | /* bo virtual addresses in a specific vm */ |
498 | struct amdgpu_bo_va { | 498 | struct amdgpu_bo_va { |
499 | struct mutex mutex; | ||
499 | /* protected by bo being reserved */ | 500 | /* protected by bo being reserved */ |
500 | struct list_head bo_list; | 501 | struct list_head bo_list; |
501 | struct fence *last_pt_update; | 502 | struct fence *last_pt_update; |
@@ -538,6 +539,7 @@ struct amdgpu_bo { | |||
538 | /* Constant after initialization */ | 539 | /* Constant after initialization */ |
539 | struct amdgpu_device *adev; | 540 | struct amdgpu_device *adev; |
540 | struct drm_gem_object gem_base; | 541 | struct drm_gem_object gem_base; |
542 | struct amdgpu_bo *parent; | ||
541 | 543 | ||
542 | struct ttm_bo_kmap_obj dma_buf_vmap; | 544 | struct ttm_bo_kmap_obj dma_buf_vmap; |
543 | pid_t pid; | 545 | pid_t pid; |
@@ -928,8 +930,6 @@ struct amdgpu_vm_id { | |||
928 | }; | 930 | }; |
929 | 931 | ||
930 | struct amdgpu_vm { | 932 | struct amdgpu_vm { |
931 | struct mutex mutex; | ||
932 | |||
933 | struct rb_root va; | 933 | struct rb_root va; |
934 | 934 | ||
935 | /* protecting invalidated */ | 935 | /* protecting invalidated */ |
@@ -956,6 +956,8 @@ struct amdgpu_vm { | |||
956 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; | 956 | struct amdgpu_vm_id ids[AMDGPU_MAX_RINGS]; |
957 | /* for interval tree */ | 957 | /* for interval tree */ |
958 | spinlock_t it_lock; | 958 | spinlock_t it_lock; |
959 | /* protecting freed */ | ||
960 | spinlock_t freed_lock; | ||
959 | }; | 961 | }; |
960 | 962 | ||
961 | struct amdgpu_vm_manager { | 963 | struct amdgpu_vm_manager { |
@@ -1262,7 +1264,8 @@ struct amdgpu_cs_parser { | |||
1262 | struct ww_acquire_ctx ticket; | 1264 | struct ww_acquire_ctx ticket; |
1263 | 1265 | ||
1264 | /* user fence */ | 1266 | /* user fence */ |
1265 | struct amdgpu_user_fence uf; | 1267 | struct amdgpu_user_fence uf; |
1268 | struct amdgpu_bo_list_entry uf_entry; | ||
1266 | }; | 1269 | }; |
1267 | 1270 | ||
1268 | struct amdgpu_job { | 1271 | struct amdgpu_job { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 3afcf0237c25..25a3e2485cc2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -127,6 +127,37 @@ int amdgpu_cs_get_ring(struct amdgpu_device *adev, u32 ip_type, | |||
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, | ||
131 | struct drm_amdgpu_cs_chunk_fence *fence_data) | ||
132 | { | ||
133 | struct drm_gem_object *gobj; | ||
134 | uint32_t handle; | ||
135 | |||
136 | handle = fence_data->handle; | ||
137 | gobj = drm_gem_object_lookup(p->adev->ddev, p->filp, | ||
138 | fence_data->handle); | ||
139 | if (gobj == NULL) | ||
140 | return -EINVAL; | ||
141 | |||
142 | p->uf.bo = amdgpu_bo_ref(gem_to_amdgpu_bo(gobj)); | ||
143 | p->uf.offset = fence_data->offset; | ||
144 | |||
145 | if (amdgpu_ttm_tt_has_userptr(p->uf.bo->tbo.ttm)) { | ||
146 | drm_gem_object_unreference_unlocked(gobj); | ||
147 | return -EINVAL; | ||
148 | } | ||
149 | |||
150 | p->uf_entry.robj = amdgpu_bo_ref(p->uf.bo); | ||
151 | p->uf_entry.prefered_domains = AMDGPU_GEM_DOMAIN_GTT; | ||
152 | p->uf_entry.allowed_domains = AMDGPU_GEM_DOMAIN_GTT; | ||
153 | p->uf_entry.priority = 0; | ||
154 | p->uf_entry.tv.bo = &p->uf_entry.robj->tbo; | ||
155 | p->uf_entry.tv.shared = true; | ||
156 | |||
157 | drm_gem_object_unreference_unlocked(gobj); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
130 | int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | 161 | int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) |
131 | { | 162 | { |
132 | union drm_amdgpu_cs *cs = data; | 163 | union drm_amdgpu_cs *cs = data; |
@@ -207,26 +238,15 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
207 | 238 | ||
208 | case AMDGPU_CHUNK_ID_FENCE: | 239 | case AMDGPU_CHUNK_ID_FENCE: |
209 | size = sizeof(struct drm_amdgpu_cs_chunk_fence); | 240 | size = sizeof(struct drm_amdgpu_cs_chunk_fence); |
210 | if (p->chunks[i].length_dw * sizeof(uint32_t) >= size) { | 241 | if (p->chunks[i].length_dw * sizeof(uint32_t) < size) { |
211 | uint32_t handle; | ||
212 | struct drm_gem_object *gobj; | ||
213 | struct drm_amdgpu_cs_chunk_fence *fence_data; | ||
214 | |||
215 | fence_data = (void *)p->chunks[i].kdata; | ||
216 | handle = fence_data->handle; | ||
217 | gobj = drm_gem_object_lookup(p->adev->ddev, | ||
218 | p->filp, handle); | ||
219 | if (gobj == NULL) { | ||
220 | ret = -EINVAL; | ||
221 | goto free_partial_kdata; | ||
222 | } | ||
223 | |||
224 | p->uf.bo = gem_to_amdgpu_bo(gobj); | ||
225 | p->uf.offset = fence_data->offset; | ||
226 | } else { | ||
227 | ret = -EINVAL; | 242 | ret = -EINVAL; |
228 | goto free_partial_kdata; | 243 | goto free_partial_kdata; |
229 | } | 244 | } |
245 | |||
246 | ret = amdgpu_cs_user_fence_chunk(p, (void *)p->chunks[i].kdata); | ||
247 | if (ret) | ||
248 | goto free_partial_kdata; | ||
249 | |||
230 | break; | 250 | break; |
231 | 251 | ||
232 | case AMDGPU_CHUNK_ID_DEPENDENCIES: | 252 | case AMDGPU_CHUNK_ID_DEPENDENCIES: |
@@ -389,6 +409,9 @@ static int amdgpu_cs_parser_relocs(struct amdgpu_cs_parser *p) | |||
389 | p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm, | 409 | p->vm_bos = amdgpu_vm_get_bos(p->adev, &fpriv->vm, |
390 | &p->validated); | 410 | &p->validated); |
391 | 411 | ||
412 | if (p->uf.bo) | ||
413 | list_add(&p->uf_entry.tv.head, &p->validated); | ||
414 | |||
392 | if (need_mmap_lock) | 415 | if (need_mmap_lock) |
393 | down_read(¤t->mm->mmap_sem); | 416 | down_read(¤t->mm->mmap_sem); |
394 | 417 | ||
@@ -486,8 +509,8 @@ static void amdgpu_cs_parser_fini(struct amdgpu_cs_parser *parser, int error, bo | |||
486 | for (i = 0; i < parser->num_ibs; i++) | 509 | for (i = 0; i < parser->num_ibs; i++) |
487 | amdgpu_ib_free(parser->adev, &parser->ibs[i]); | 510 | amdgpu_ib_free(parser->adev, &parser->ibs[i]); |
488 | kfree(parser->ibs); | 511 | kfree(parser->ibs); |
489 | if (parser->uf.bo) | 512 | amdgpu_bo_unref(&parser->uf.bo); |
490 | drm_gem_object_unreference_unlocked(&parser->uf.bo->gem_base); | 513 | amdgpu_bo_unref(&parser->uf_entry.robj); |
491 | } | 514 | } |
492 | 515 | ||
493 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, | 516 | static int amdgpu_bo_vm_update_pte(struct amdgpu_cs_parser *p, |
@@ -776,7 +799,7 @@ static int amdgpu_cs_free_job(struct amdgpu_job *job) | |||
776 | amdgpu_ib_free(job->adev, &job->ibs[i]); | 799 | amdgpu_ib_free(job->adev, &job->ibs[i]); |
777 | kfree(job->ibs); | 800 | kfree(job->ibs); |
778 | if (job->uf.bo) | 801 | if (job->uf.bo) |
779 | drm_gem_object_unreference_unlocked(&job->uf.bo->gem_base); | 802 | amdgpu_bo_unref(&job->uf.bo); |
780 | return 0; | 803 | return 0; |
781 | } | 804 | } |
782 | 805 | ||
@@ -784,8 +807,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
784 | { | 807 | { |
785 | struct amdgpu_device *adev = dev->dev_private; | 808 | struct amdgpu_device *adev = dev->dev_private; |
786 | union drm_amdgpu_cs *cs = data; | 809 | union drm_amdgpu_cs *cs = data; |
787 | struct amdgpu_fpriv *fpriv = filp->driver_priv; | ||
788 | struct amdgpu_vm *vm = &fpriv->vm; | ||
789 | struct amdgpu_cs_parser parser = {}; | 810 | struct amdgpu_cs_parser parser = {}; |
790 | bool reserved_buffers = false; | 811 | bool reserved_buffers = false; |
791 | int i, r; | 812 | int i, r; |
@@ -803,7 +824,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
803 | r = amdgpu_cs_handle_lockup(adev, r); | 824 | r = amdgpu_cs_handle_lockup(adev, r); |
804 | return r; | 825 | return r; |
805 | } | 826 | } |
806 | mutex_lock(&vm->mutex); | ||
807 | r = amdgpu_cs_parser_relocs(&parser); | 827 | r = amdgpu_cs_parser_relocs(&parser); |
808 | if (r == -ENOMEM) | 828 | if (r == -ENOMEM) |
809 | DRM_ERROR("Not enough memory for command submission!\n"); | 829 | DRM_ERROR("Not enough memory for command submission!\n"); |
@@ -888,7 +908,6 @@ int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
888 | 908 | ||
889 | out: | 909 | out: |
890 | amdgpu_cs_parser_fini(&parser, r, reserved_buffers); | 910 | amdgpu_cs_parser_fini(&parser, r, reserved_buffers); |
891 | mutex_unlock(&vm->mutex); | ||
892 | r = amdgpu_cs_handle_lockup(adev, r); | 911 | r = amdgpu_cs_handle_lockup(adev, r); |
893 | return r; | 912 | return r; |
894 | } | 913 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index e173a5a02f0d..5580d3420c3a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | |||
@@ -73,6 +73,8 @@ static void amdgpu_flip_work_func(struct work_struct *__work) | |||
73 | struct drm_crtc *crtc = &amdgpuCrtc->base; | 73 | struct drm_crtc *crtc = &amdgpuCrtc->base; |
74 | unsigned long flags; | 74 | unsigned long flags; |
75 | unsigned i; | 75 | unsigned i; |
76 | int vpos, hpos, stat, min_udelay; | ||
77 | struct drm_vblank_crtc *vblank = &crtc->dev->vblank[work->crtc_id]; | ||
76 | 78 | ||
77 | amdgpu_flip_wait_fence(adev, &work->excl); | 79 | amdgpu_flip_wait_fence(adev, &work->excl); |
78 | for (i = 0; i < work->shared_count; ++i) | 80 | for (i = 0; i < work->shared_count; ++i) |
@@ -81,6 +83,41 @@ static void amdgpu_flip_work_func(struct work_struct *__work) | |||
81 | /* We borrow the event spin lock for protecting flip_status */ | 83 | /* We borrow the event spin lock for protecting flip_status */ |
82 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | 84 | spin_lock_irqsave(&crtc->dev->event_lock, flags); |
83 | 85 | ||
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 | |||
84 | /* do the flip (mmio) */ | 121 | /* do the flip (mmio) */ |
85 | adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); | 122 | adev->mode_info.funcs->page_flip(adev, work->crtc_id, work->base); |
86 | /* set the flip status */ | 123 | /* set the flip status */ |
@@ -109,7 +146,7 @@ static void amdgpu_unpin_work_func(struct work_struct *__work) | |||
109 | } else | 146 | } else |
110 | DRM_ERROR("failed to reserve buffer after flip\n"); | 147 | DRM_ERROR("failed to reserve buffer after flip\n"); |
111 | 148 | ||
112 | drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); | 149 | amdgpu_bo_unref(&work->old_rbo); |
113 | kfree(work->shared); | 150 | kfree(work->shared); |
114 | kfree(work); | 151 | kfree(work); |
115 | } | 152 | } |
@@ -148,8 +185,8 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc, | |||
148 | obj = old_amdgpu_fb->obj; | 185 | obj = old_amdgpu_fb->obj; |
149 | 186 | ||
150 | /* take a reference to the old object */ | 187 | /* take a reference to the old object */ |
151 | drm_gem_object_reference(obj); | ||
152 | work->old_rbo = gem_to_amdgpu_bo(obj); | 188 | work->old_rbo = gem_to_amdgpu_bo(obj); |
189 | amdgpu_bo_ref(work->old_rbo); | ||
153 | 190 | ||
154 | new_amdgpu_fb = to_amdgpu_framebuffer(fb); | 191 | new_amdgpu_fb = to_amdgpu_framebuffer(fb); |
155 | obj = new_amdgpu_fb->obj; | 192 | obj = new_amdgpu_fb->obj; |
@@ -222,7 +259,7 @@ pflip_cleanup: | |||
222 | amdgpu_bo_unreserve(new_rbo); | 259 | amdgpu_bo_unreserve(new_rbo); |
223 | 260 | ||
224 | cleanup: | 261 | cleanup: |
225 | drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base); | 262 | amdgpu_bo_unref(&work->old_rbo); |
226 | fence_put(work->excl); | 263 | fence_put(work->excl); |
227 | for (i = 0; i < work->shared_count; ++i) | 264 | for (i = 0; i < work->shared_count; ++i) |
228 | fence_put(work->shared[i]); | 265 | fence_put(work->shared[i]); |
@@ -712,6 +749,15 @@ bool amdgpu_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
712 | * \param dev Device to query. | 749 | * \param dev Device to query. |
713 | * \param pipe Crtc to query. | 750 | * \param pipe Crtc to query. |
714 | * \param flags Flags from caller (DRM_CALLED_FROM_VBLIRQ or 0). | 751 | * \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 | * | ||
715 | * \param *vpos Location where vertical scanout position should be stored. | 761 | * \param *vpos Location where vertical scanout position should be stored. |
716 | * \param *hpos Location where horizontal scanout position should go. | 762 | * \param *hpos Location where horizontal scanout position should go. |
717 | * \param *stime Target location for timestamp taken immediately before | 763 | * \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, | |||
776 | vbl_end = 0; | 822 | vbl_end = 0; |
777 | } | 823 | } |
778 | 824 | ||
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 | |||
779 | /* Test scanout position against vblank region. */ | 844 | /* Test scanout position against vblank region. */ |
780 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) | 845 | if ((*vpos < vbl_start) && (*vpos >= vbl_end)) |
781 | in_vbl = false; | 846 | in_vbl = false; |
782 | 847 | ||
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 | |||
783 | /* Check if inside vblank area and apply corrective offsets: | 859 | /* Check if inside vblank area and apply corrective offsets: |
784 | * vpos will then be >=0 in video scanout area, but negative | 860 | * vpos will then be >=0 in video scanout area, but negative |
785 | * within vblank area, counting down the number of lines until | 861 | * 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, | |||
795 | /* Correct for shifted end of vbl at vbl_end. */ | 871 | /* Correct for shifted end of vbl at vbl_end. */ |
796 | *vpos = *vpos - vbl_end; | 872 | *vpos = *vpos - vbl_end; |
797 | 873 | ||
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 | |||
824 | return ret; | 874 | return ret; |
825 | } | 875 | } |
826 | 876 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 00c5b580f56c..9c253c535d26 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | |||
@@ -115,12 +115,9 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri | |||
115 | struct amdgpu_vm *vm = &fpriv->vm; | 115 | struct amdgpu_vm *vm = &fpriv->vm; |
116 | struct amdgpu_bo_va *bo_va; | 116 | struct amdgpu_bo_va *bo_va; |
117 | int r; | 117 | int r; |
118 | mutex_lock(&vm->mutex); | ||
119 | r = amdgpu_bo_reserve(rbo, false); | 118 | r = amdgpu_bo_reserve(rbo, false); |
120 | if (r) { | 119 | if (r) |
121 | mutex_unlock(&vm->mutex); | ||
122 | return r; | 120 | return r; |
123 | } | ||
124 | 121 | ||
125 | bo_va = amdgpu_vm_bo_find(vm, rbo); | 122 | bo_va = amdgpu_vm_bo_find(vm, rbo); |
126 | if (!bo_va) { | 123 | if (!bo_va) { |
@@ -129,7 +126,6 @@ int amdgpu_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_pri | |||
129 | ++bo_va->ref_count; | 126 | ++bo_va->ref_count; |
130 | } | 127 | } |
131 | amdgpu_bo_unreserve(rbo); | 128 | amdgpu_bo_unreserve(rbo); |
132 | mutex_unlock(&vm->mutex); | ||
133 | return 0; | 129 | return 0; |
134 | } | 130 | } |
135 | 131 | ||
@@ -142,10 +138,8 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
142 | struct amdgpu_vm *vm = &fpriv->vm; | 138 | struct amdgpu_vm *vm = &fpriv->vm; |
143 | struct amdgpu_bo_va *bo_va; | 139 | struct amdgpu_bo_va *bo_va; |
144 | int r; | 140 | int r; |
145 | mutex_lock(&vm->mutex); | ||
146 | r = amdgpu_bo_reserve(rbo, true); | 141 | r = amdgpu_bo_reserve(rbo, true); |
147 | if (r) { | 142 | if (r) { |
148 | mutex_unlock(&vm->mutex); | ||
149 | dev_err(adev->dev, "leaking bo va because " | 143 | dev_err(adev->dev, "leaking bo va because " |
150 | "we fail to reserve bo (%d)\n", r); | 144 | "we fail to reserve bo (%d)\n", r); |
151 | return; | 145 | return; |
@@ -157,7 +151,6 @@ void amdgpu_gem_object_close(struct drm_gem_object *obj, | |||
157 | } | 151 | } |
158 | } | 152 | } |
159 | amdgpu_bo_unreserve(rbo); | 153 | amdgpu_bo_unreserve(rbo); |
160 | mutex_unlock(&vm->mutex); | ||
161 | } | 154 | } |
162 | 155 | ||
163 | static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) | 156 | static int amdgpu_gem_handle_lockup(struct amdgpu_device *adev, int r) |
@@ -242,8 +235,9 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, | |||
242 | AMDGPU_GEM_USERPTR_REGISTER)) | 235 | AMDGPU_GEM_USERPTR_REGISTER)) |
243 | return -EINVAL; | 236 | return -EINVAL; |
244 | 237 | ||
245 | if (!(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || | 238 | if (!(args->flags & AMDGPU_GEM_USERPTR_READONLY) && ( |
246 | !(args->flags & AMDGPU_GEM_USERPTR_REGISTER)) { | 239 | !(args->flags & AMDGPU_GEM_USERPTR_ANONONLY) || |
240 | !(args->flags & AMDGPU_GEM_USERPTR_REGISTER))) { | ||
247 | 241 | ||
248 | /* if we want to write to it we must require anonymous | 242 | /* if we want to write to it we must require anonymous |
249 | memory and install a MMU notifier */ | 243 | memory and install a MMU notifier */ |
@@ -483,6 +477,14 @@ static void amdgpu_gem_va_update_vm(struct amdgpu_device *adev, | |||
483 | if (domain == AMDGPU_GEM_DOMAIN_CPU) | 477 | if (domain == AMDGPU_GEM_DOMAIN_CPU) |
484 | goto error_unreserve; | 478 | goto error_unreserve; |
485 | } | 479 | } |
480 | list_for_each_entry(entry, &duplicates, head) { | ||
481 | domain = amdgpu_mem_type_to_domain(entry->bo->mem.mem_type); | ||
482 | /* if anything is swapped out don't swap it in here, | ||
483 | just abort and wait for the next CS */ | ||
484 | if (domain == AMDGPU_GEM_DOMAIN_CPU) | ||
485 | goto error_unreserve; | ||
486 | } | ||
487 | |||
486 | r = amdgpu_vm_update_page_directory(adev, bo_va->vm); | 488 | r = amdgpu_vm_update_page_directory(adev, bo_va->vm); |
487 | if (r) | 489 | if (r) |
488 | goto error_unreserve; | 490 | goto error_unreserve; |
@@ -553,7 +555,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
553 | gobj = drm_gem_object_lookup(dev, filp, args->handle); | 555 | gobj = drm_gem_object_lookup(dev, filp, args->handle); |
554 | if (gobj == NULL) | 556 | if (gobj == NULL) |
555 | return -ENOENT; | 557 | return -ENOENT; |
556 | mutex_lock(&fpriv->vm.mutex); | ||
557 | rbo = gem_to_amdgpu_bo(gobj); | 558 | rbo = gem_to_amdgpu_bo(gobj); |
558 | INIT_LIST_HEAD(&list); | 559 | INIT_LIST_HEAD(&list); |
559 | INIT_LIST_HEAD(&duplicates); | 560 | INIT_LIST_HEAD(&duplicates); |
@@ -568,7 +569,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
568 | } | 569 | } |
569 | r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); | 570 | r = ttm_eu_reserve_buffers(&ticket, &list, true, &duplicates); |
570 | if (r) { | 571 | if (r) { |
571 | mutex_unlock(&fpriv->vm.mutex); | ||
572 | drm_gem_object_unreference_unlocked(gobj); | 572 | drm_gem_object_unreference_unlocked(gobj); |
573 | return r; | 573 | return r; |
574 | } | 574 | } |
@@ -577,7 +577,6 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
577 | if (!bo_va) { | 577 | if (!bo_va) { |
578 | ttm_eu_backoff_reservation(&ticket, &list); | 578 | ttm_eu_backoff_reservation(&ticket, &list); |
579 | drm_gem_object_unreference_unlocked(gobj); | 579 | drm_gem_object_unreference_unlocked(gobj); |
580 | mutex_unlock(&fpriv->vm.mutex); | ||
581 | return -ENOENT; | 580 | return -ENOENT; |
582 | } | 581 | } |
583 | 582 | ||
@@ -602,7 +601,7 @@ int amdgpu_gem_va_ioctl(struct drm_device *dev, void *data, | |||
602 | ttm_eu_backoff_reservation(&ticket, &list); | 601 | ttm_eu_backoff_reservation(&ticket, &list); |
603 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) | 602 | if (!r && !(args->flags & AMDGPU_VM_DELAY_UPDATE)) |
604 | amdgpu_gem_va_update_vm(adev, bo_va, args->operation); | 603 | amdgpu_gem_va_update_vm(adev, bo_va, args->operation); |
605 | mutex_unlock(&fpriv->vm.mutex); | 604 | |
606 | drm_gem_object_unreference_unlocked(gobj); | 605 | drm_gem_object_unreference_unlocked(gobj); |
607 | return r; | 606 | return r; |
608 | } | 607 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1618e2294a16..e23843f4d877 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | |||
@@ -611,13 +611,59 @@ void amdgpu_driver_preclose_kms(struct drm_device *dev, | |||
611 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) | 611 | u32 amdgpu_get_vblank_counter_kms(struct drm_device *dev, unsigned int pipe) |
612 | { | 612 | { |
613 | struct amdgpu_device *adev = dev->dev_private; | 613 | struct amdgpu_device *adev = dev->dev_private; |
614 | int vpos, hpos, stat; | ||
615 | u32 count; | ||
614 | 616 | ||
615 | if (pipe >= adev->mode_info.num_crtc) { | 617 | if (pipe >= adev->mode_info.num_crtc) { |
616 | DRM_ERROR("Invalid crtc %u\n", pipe); | 618 | DRM_ERROR("Invalid crtc %u\n", pipe); |
617 | return -EINVAL; | 619 | return -EINVAL; |
618 | } | 620 | } |
619 | 621 | ||
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; | ||
621 | } | 667 | } |
622 | 668 | ||
623 | /** | 669 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index b62c1710cab6..064ebb347074 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h | |||
@@ -407,6 +407,7 @@ struct amdgpu_crtc { | |||
407 | u32 line_time; | 407 | u32 line_time; |
408 | u32 wm_low; | 408 | u32 wm_low; |
409 | u32 wm_high; | 409 | u32 wm_high; |
410 | u32 lb_vblank_lead_lines; | ||
410 | struct drm_display_mode hw_mode; | 411 | struct drm_display_mode hw_mode; |
411 | }; | 412 | }; |
412 | 413 | ||
@@ -528,6 +529,10 @@ struct amdgpu_framebuffer { | |||
528 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ | 529 | #define ENCODER_MODE_IS_DP(em) (((em) == ATOM_ENCODER_MODE_DP) || \ |
529 | ((em) == ATOM_ENCODER_MODE_DP_MST)) | 530 | ((em) == ATOM_ENCODER_MODE_DP_MST)) |
530 | 531 | ||
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 | |||
531 | void amdgpu_link_encoder_connector(struct drm_device *dev); | 536 | void amdgpu_link_encoder_connector(struct drm_device *dev); |
532 | 537 | ||
533 | struct drm_connector * | 538 | struct drm_connector * |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c index 0d524384ff79..c3ce103b6a33 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | |||
@@ -100,6 +100,7 @@ static void amdgpu_ttm_bo_destroy(struct ttm_buffer_object *tbo) | |||
100 | list_del_init(&bo->list); | 100 | list_del_init(&bo->list); |
101 | mutex_unlock(&bo->adev->gem.mutex); | 101 | mutex_unlock(&bo->adev->gem.mutex); |
102 | drm_gem_object_release(&bo->gem_base); | 102 | drm_gem_object_release(&bo->gem_base); |
103 | amdgpu_bo_unref(&bo->parent); | ||
103 | kfree(bo->metadata); | 104 | kfree(bo->metadata); |
104 | kfree(bo); | 105 | kfree(bo); |
105 | } | 106 | } |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index d4bac5f49939..8a1752ff3d8e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | |||
@@ -587,9 +587,13 @@ static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm, | |||
587 | uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem); | 587 | uint32_t flags = amdgpu_ttm_tt_pte_flags(gtt->adev, ttm, bo_mem); |
588 | int r; | 588 | int r; |
589 | 589 | ||
590 | if (gtt->userptr) | 590 | if (gtt->userptr) { |
591 | amdgpu_ttm_tt_pin_userptr(ttm); | 591 | r = amdgpu_ttm_tt_pin_userptr(ttm); |
592 | 592 | if (r) { | |
593 | DRM_ERROR("failed to pin userptr\n"); | ||
594 | return r; | ||
595 | } | ||
596 | } | ||
593 | gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); | 597 | gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); |
594 | if (!ttm->num_pages) { | 598 | if (!ttm->num_pages) { |
595 | WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", | 599 | 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, | |||
797 | if (mem && mem->mem_type != TTM_PL_SYSTEM) | 801 | if (mem && mem->mem_type != TTM_PL_SYSTEM) |
798 | flags |= AMDGPU_PTE_VALID; | 802 | flags |= AMDGPU_PTE_VALID; |
799 | 803 | ||
800 | if (mem && mem->mem_type == TTM_PL_TT) | 804 | if (mem && mem->mem_type == TTM_PL_TT) { |
801 | flags |= AMDGPU_PTE_SYSTEM; | 805 | flags |= AMDGPU_PTE_SYSTEM; |
802 | 806 | ||
803 | if (!ttm || ttm->caching_state == tt_cached) | 807 | if (ttm->caching_state == tt_cached) |
804 | flags |= AMDGPU_PTE_SNOOPED; | 808 | flags |= AMDGPU_PTE_SNOOPED; |
809 | } | ||
805 | 810 | ||
806 | if (adev->asic_type >= CHIP_TOPAZ) | 811 | if (adev->asic_type >= CHIP_TOPAZ) |
807 | flags |= AMDGPU_PTE_EXECUTABLE; | 812 | flags |= AMDGPU_PTE_EXECUTABLE; |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 03f0c3bae516..a745eeeb5d82 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | |||
@@ -392,7 +392,10 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
392 | ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */ | 392 | ib->ptr[ib->length_dw++] = 0x00000001; /* session cmd */ |
393 | ib->ptr[ib->length_dw++] = handle; | 393 | ib->ptr[ib->length_dw++] = handle; |
394 | 394 | ||
395 | ib->ptr[ib->length_dw++] = 0x00000030; /* len */ | 395 | if ((ring->adev->vce.fw_version >> 24) >= 52) |
396 | ib->ptr[ib->length_dw++] = 0x00000040; /* len */ | ||
397 | else | ||
398 | ib->ptr[ib->length_dw++] = 0x00000030; /* len */ | ||
396 | ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */ | 399 | ib->ptr[ib->length_dw++] = 0x01000001; /* create cmd */ |
397 | ib->ptr[ib->length_dw++] = 0x00000000; | 400 | ib->ptr[ib->length_dw++] = 0x00000000; |
398 | ib->ptr[ib->length_dw++] = 0x00000042; | 401 | ib->ptr[ib->length_dw++] = 0x00000042; |
@@ -404,6 +407,12 @@ int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, | |||
404 | ib->ptr[ib->length_dw++] = 0x00000100; | 407 | ib->ptr[ib->length_dw++] = 0x00000100; |
405 | ib->ptr[ib->length_dw++] = 0x0000000c; | 408 | ib->ptr[ib->length_dw++] = 0x0000000c; |
406 | ib->ptr[ib->length_dw++] = 0x00000000; | 409 | ib->ptr[ib->length_dw++] = 0x00000000; |
410 | if ((ring->adev->vce.fw_version >> 24) >= 52) { | ||
411 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
412 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
413 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
414 | ib->ptr[ib->length_dw++] = 0x00000000; | ||
415 | } | ||
407 | 416 | ||
408 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ | 417 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ |
409 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ | 418 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 159ce54bbd8d..b53d273eb7a1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | |||
@@ -885,17 +885,21 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, | |||
885 | struct amdgpu_bo_va_mapping *mapping; | 885 | struct amdgpu_bo_va_mapping *mapping; |
886 | int r; | 886 | int r; |
887 | 887 | ||
888 | spin_lock(&vm->freed_lock); | ||
888 | while (!list_empty(&vm->freed)) { | 889 | while (!list_empty(&vm->freed)) { |
889 | mapping = list_first_entry(&vm->freed, | 890 | mapping = list_first_entry(&vm->freed, |
890 | struct amdgpu_bo_va_mapping, list); | 891 | struct amdgpu_bo_va_mapping, list); |
891 | list_del(&mapping->list); | 892 | list_del(&mapping->list); |
892 | 893 | spin_unlock(&vm->freed_lock); | |
893 | r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); | 894 | r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); |
894 | kfree(mapping); | 895 | kfree(mapping); |
895 | if (r) | 896 | if (r) |
896 | return r; | 897 | return r; |
897 | 898 | ||
899 | spin_lock(&vm->freed_lock); | ||
898 | } | 900 | } |
901 | spin_unlock(&vm->freed_lock); | ||
902 | |||
899 | return 0; | 903 | return 0; |
900 | 904 | ||
901 | } | 905 | } |
@@ -922,8 +926,9 @@ int amdgpu_vm_clear_invalids(struct amdgpu_device *adev, | |||
922 | bo_va = list_first_entry(&vm->invalidated, | 926 | bo_va = list_first_entry(&vm->invalidated, |
923 | struct amdgpu_bo_va, vm_status); | 927 | struct amdgpu_bo_va, vm_status); |
924 | spin_unlock(&vm->status_lock); | 928 | spin_unlock(&vm->status_lock); |
925 | 929 | mutex_lock(&bo_va->mutex); | |
926 | r = amdgpu_vm_bo_update(adev, bo_va, NULL); | 930 | r = amdgpu_vm_bo_update(adev, bo_va, NULL); |
931 | mutex_unlock(&bo_va->mutex); | ||
927 | if (r) | 932 | if (r) |
928 | return r; | 933 | return r; |
929 | 934 | ||
@@ -967,7 +972,7 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, | |||
967 | INIT_LIST_HEAD(&bo_va->valids); | 972 | INIT_LIST_HEAD(&bo_va->valids); |
968 | INIT_LIST_HEAD(&bo_va->invalids); | 973 | INIT_LIST_HEAD(&bo_va->invalids); |
969 | INIT_LIST_HEAD(&bo_va->vm_status); | 974 | INIT_LIST_HEAD(&bo_va->vm_status); |
970 | 975 | mutex_init(&bo_va->mutex); | |
971 | list_add_tail(&bo_va->bo_list, &bo->va); | 976 | list_add_tail(&bo_va->bo_list, &bo->va); |
972 | 977 | ||
973 | return bo_va; | 978 | return bo_va; |
@@ -1045,7 +1050,9 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
1045 | mapping->offset = offset; | 1050 | mapping->offset = offset; |
1046 | mapping->flags = flags; | 1051 | mapping->flags = flags; |
1047 | 1052 | ||
1053 | mutex_lock(&bo_va->mutex); | ||
1048 | list_add(&mapping->list, &bo_va->invalids); | 1054 | list_add(&mapping->list, &bo_va->invalids); |
1055 | mutex_unlock(&bo_va->mutex); | ||
1049 | spin_lock(&vm->it_lock); | 1056 | spin_lock(&vm->it_lock); |
1050 | interval_tree_insert(&mapping->it, &vm->va); | 1057 | interval_tree_insert(&mapping->it, &vm->va); |
1051 | spin_unlock(&vm->it_lock); | 1058 | spin_unlock(&vm->it_lock); |
@@ -1076,6 +1083,11 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, | |||
1076 | if (r) | 1083 | if (r) |
1077 | goto error_free; | 1084 | goto error_free; |
1078 | 1085 | ||
1086 | /* Keep a reference to the page table to avoid freeing | ||
1087 | * them up in the wrong order. | ||
1088 | */ | ||
1089 | pt->parent = amdgpu_bo_ref(vm->page_directory); | ||
1090 | |||
1079 | r = amdgpu_vm_clear_bo(adev, pt); | 1091 | r = amdgpu_vm_clear_bo(adev, pt); |
1080 | if (r) { | 1092 | if (r) { |
1081 | amdgpu_bo_unref(&pt); | 1093 | amdgpu_bo_unref(&pt); |
@@ -1121,7 +1133,7 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
1121 | bool valid = true; | 1133 | bool valid = true; |
1122 | 1134 | ||
1123 | saddr /= AMDGPU_GPU_PAGE_SIZE; | 1135 | saddr /= AMDGPU_GPU_PAGE_SIZE; |
1124 | 1136 | mutex_lock(&bo_va->mutex); | |
1125 | list_for_each_entry(mapping, &bo_va->valids, list) { | 1137 | list_for_each_entry(mapping, &bo_va->valids, list) { |
1126 | if (mapping->it.start == saddr) | 1138 | if (mapping->it.start == saddr) |
1127 | break; | 1139 | break; |
@@ -1135,20 +1147,25 @@ int amdgpu_vm_bo_unmap(struct amdgpu_device *adev, | |||
1135 | break; | 1147 | break; |
1136 | } | 1148 | } |
1137 | 1149 | ||
1138 | if (&mapping->list == &bo_va->invalids) | 1150 | if (&mapping->list == &bo_va->invalids) { |
1151 | mutex_unlock(&bo_va->mutex); | ||
1139 | return -ENOENT; | 1152 | return -ENOENT; |
1153 | } | ||
1140 | } | 1154 | } |
1141 | 1155 | mutex_unlock(&bo_va->mutex); | |
1142 | list_del(&mapping->list); | 1156 | list_del(&mapping->list); |
1143 | spin_lock(&vm->it_lock); | 1157 | spin_lock(&vm->it_lock); |
1144 | interval_tree_remove(&mapping->it, &vm->va); | 1158 | interval_tree_remove(&mapping->it, &vm->va); |
1145 | spin_unlock(&vm->it_lock); | 1159 | spin_unlock(&vm->it_lock); |
1146 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1160 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
1147 | 1161 | ||
1148 | if (valid) | 1162 | if (valid) { |
1163 | spin_lock(&vm->freed_lock); | ||
1149 | list_add(&mapping->list, &vm->freed); | 1164 | list_add(&mapping->list, &vm->freed); |
1150 | else | 1165 | spin_unlock(&vm->freed_lock); |
1166 | } else { | ||
1151 | kfree(mapping); | 1167 | kfree(mapping); |
1168 | } | ||
1152 | 1169 | ||
1153 | return 0; | 1170 | return 0; |
1154 | } | 1171 | } |
@@ -1181,7 +1198,9 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
1181 | interval_tree_remove(&mapping->it, &vm->va); | 1198 | interval_tree_remove(&mapping->it, &vm->va); |
1182 | spin_unlock(&vm->it_lock); | 1199 | spin_unlock(&vm->it_lock); |
1183 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); | 1200 | trace_amdgpu_vm_bo_unmap(bo_va, mapping); |
1201 | spin_lock(&vm->freed_lock); | ||
1184 | list_add(&mapping->list, &vm->freed); | 1202 | list_add(&mapping->list, &vm->freed); |
1203 | spin_unlock(&vm->freed_lock); | ||
1185 | } | 1204 | } |
1186 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { | 1205 | list_for_each_entry_safe(mapping, next, &bo_va->invalids, list) { |
1187 | list_del(&mapping->list); | 1206 | list_del(&mapping->list); |
@@ -1190,8 +1209,8 @@ void amdgpu_vm_bo_rmv(struct amdgpu_device *adev, | |||
1190 | spin_unlock(&vm->it_lock); | 1209 | spin_unlock(&vm->it_lock); |
1191 | kfree(mapping); | 1210 | kfree(mapping); |
1192 | } | 1211 | } |
1193 | |||
1194 | fence_put(bo_va->last_pt_update); | 1212 | fence_put(bo_va->last_pt_update); |
1213 | mutex_destroy(&bo_va->mutex); | ||
1195 | kfree(bo_va); | 1214 | kfree(bo_va); |
1196 | } | 1215 | } |
1197 | 1216 | ||
@@ -1236,13 +1255,13 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1236 | vm->ids[i].id = 0; | 1255 | vm->ids[i].id = 0; |
1237 | vm->ids[i].flushed_updates = NULL; | 1256 | vm->ids[i].flushed_updates = NULL; |
1238 | } | 1257 | } |
1239 | mutex_init(&vm->mutex); | ||
1240 | vm->va = RB_ROOT; | 1258 | vm->va = RB_ROOT; |
1241 | spin_lock_init(&vm->status_lock); | 1259 | spin_lock_init(&vm->status_lock); |
1242 | INIT_LIST_HEAD(&vm->invalidated); | 1260 | INIT_LIST_HEAD(&vm->invalidated); |
1243 | INIT_LIST_HEAD(&vm->cleared); | 1261 | INIT_LIST_HEAD(&vm->cleared); |
1244 | INIT_LIST_HEAD(&vm->freed); | 1262 | INIT_LIST_HEAD(&vm->freed); |
1245 | spin_lock_init(&vm->it_lock); | 1263 | spin_lock_init(&vm->it_lock); |
1264 | spin_lock_init(&vm->freed_lock); | ||
1246 | pd_size = amdgpu_vm_directory_size(adev); | 1265 | pd_size = amdgpu_vm_directory_size(adev); |
1247 | pd_entries = amdgpu_vm_num_pdes(adev); | 1266 | pd_entries = amdgpu_vm_num_pdes(adev); |
1248 | 1267 | ||
@@ -1320,7 +1339,6 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm) | |||
1320 | fence_put(vm->ids[i].flushed_updates); | 1339 | fence_put(vm->ids[i].flushed_updates); |
1321 | } | 1340 | } |
1322 | 1341 | ||
1323 | mutex_destroy(&vm->mutex); | ||
1324 | } | 1342 | } |
1325 | 1343 | ||
1326 | /** | 1344 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index cb0f7747e3dc..4dcc8fba5792 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c | |||
@@ -1250,7 +1250,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, | |||
1250 | u32 pixel_period; | 1250 | u32 pixel_period; |
1251 | u32 line_time = 0; | 1251 | u32 line_time = 0; |
1252 | u32 latency_watermark_a = 0, latency_watermark_b = 0; | 1252 | u32 latency_watermark_a = 0, latency_watermark_b = 0; |
1253 | u32 tmp, wm_mask; | 1253 | u32 tmp, wm_mask, lb_vblank_lead_lines = 0; |
1254 | 1254 | ||
1255 | if (amdgpu_crtc->base.enabled && num_heads && mode) { | 1255 | if (amdgpu_crtc->base.enabled && num_heads && mode) { |
1256 | pixel_period = 1000000 / (u32)mode->clock; | 1256 | pixel_period = 1000000 / (u32)mode->clock; |
@@ -1333,6 +1333,7 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, | |||
1333 | (adev->mode_info.disp_priority == 2)) { | 1333 | (adev->mode_info.disp_priority == 2)) { |
1334 | DRM_DEBUG_KMS("force priority to high\n"); | 1334 | DRM_DEBUG_KMS("force priority to high\n"); |
1335 | } | 1335 | } |
1336 | lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
1336 | } | 1337 | } |
1337 | 1338 | ||
1338 | /* select wm A */ | 1339 | /* select wm A */ |
@@ -1357,6 +1358,8 @@ static void dce_v10_0_program_watermarks(struct amdgpu_device *adev, | |||
1357 | amdgpu_crtc->line_time = line_time; | 1358 | amdgpu_crtc->line_time = line_time; |
1358 | amdgpu_crtc->wm_high = latency_watermark_a; | 1359 | amdgpu_crtc->wm_high = latency_watermark_a; |
1359 | amdgpu_crtc->wm_low = latency_watermark_b; | 1360 | amdgpu_crtc->wm_low = latency_watermark_b; |
1361 | /* Save number of lines the linebuffer leads before the scanout */ | ||
1362 | amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; | ||
1360 | } | 1363 | } |
1361 | 1364 | ||
1362 | /** | 1365 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c index 5af3721851d6..8f1e51128b33 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c | |||
@@ -1238,7 +1238,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, | |||
1238 | u32 pixel_period; | 1238 | u32 pixel_period; |
1239 | u32 line_time = 0; | 1239 | u32 line_time = 0; |
1240 | u32 latency_watermark_a = 0, latency_watermark_b = 0; | 1240 | u32 latency_watermark_a = 0, latency_watermark_b = 0; |
1241 | u32 tmp, wm_mask; | 1241 | u32 tmp, wm_mask, lb_vblank_lead_lines = 0; |
1242 | 1242 | ||
1243 | if (amdgpu_crtc->base.enabled && num_heads && mode) { | 1243 | if (amdgpu_crtc->base.enabled && num_heads && mode) { |
1244 | pixel_period = 1000000 / (u32)mode->clock; | 1244 | pixel_period = 1000000 / (u32)mode->clock; |
@@ -1321,6 +1321,7 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, | |||
1321 | (adev->mode_info.disp_priority == 2)) { | 1321 | (adev->mode_info.disp_priority == 2)) { |
1322 | DRM_DEBUG_KMS("force priority to high\n"); | 1322 | DRM_DEBUG_KMS("force priority to high\n"); |
1323 | } | 1323 | } |
1324 | lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
1324 | } | 1325 | } |
1325 | 1326 | ||
1326 | /* select wm A */ | 1327 | /* select wm A */ |
@@ -1345,6 +1346,8 @@ static void dce_v11_0_program_watermarks(struct amdgpu_device *adev, | |||
1345 | amdgpu_crtc->line_time = line_time; | 1346 | amdgpu_crtc->line_time = line_time; |
1346 | amdgpu_crtc->wm_high = latency_watermark_a; | 1347 | amdgpu_crtc->wm_high = latency_watermark_a; |
1347 | amdgpu_crtc->wm_low = latency_watermark_b; | 1348 | amdgpu_crtc->wm_low = latency_watermark_b; |
1349 | /* Save number of lines the linebuffer leads before the scanout */ | ||
1350 | amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; | ||
1348 | } | 1351 | } |
1349 | 1352 | ||
1350 | /** | 1353 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 4f7b49a6dc50..42d954dc436d 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c | |||
@@ -1193,7 +1193,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, | |||
1193 | u32 pixel_period; | 1193 | u32 pixel_period; |
1194 | u32 line_time = 0; | 1194 | u32 line_time = 0; |
1195 | u32 latency_watermark_a = 0, latency_watermark_b = 0; | 1195 | u32 latency_watermark_a = 0, latency_watermark_b = 0; |
1196 | u32 tmp, wm_mask; | 1196 | u32 tmp, wm_mask, lb_vblank_lead_lines = 0; |
1197 | 1197 | ||
1198 | if (amdgpu_crtc->base.enabled && num_heads && mode) { | 1198 | if (amdgpu_crtc->base.enabled && num_heads && mode) { |
1199 | pixel_period = 1000000 / (u32)mode->clock; | 1199 | pixel_period = 1000000 / (u32)mode->clock; |
@@ -1276,6 +1276,7 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, | |||
1276 | (adev->mode_info.disp_priority == 2)) { | 1276 | (adev->mode_info.disp_priority == 2)) { |
1277 | DRM_DEBUG_KMS("force priority to high\n"); | 1277 | DRM_DEBUG_KMS("force priority to high\n"); |
1278 | } | 1278 | } |
1279 | lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); | ||
1279 | } | 1280 | } |
1280 | 1281 | ||
1281 | /* select wm A */ | 1282 | /* select wm A */ |
@@ -1302,6 +1303,8 @@ static void dce_v8_0_program_watermarks(struct amdgpu_device *adev, | |||
1302 | amdgpu_crtc->line_time = line_time; | 1303 | amdgpu_crtc->line_time = line_time; |
1303 | amdgpu_crtc->wm_high = latency_watermark_a; | 1304 | amdgpu_crtc->wm_high = latency_watermark_a; |
1304 | amdgpu_crtc->wm_low = latency_watermark_b; | 1305 | amdgpu_crtc->wm_low = latency_watermark_b; |
1306 | /* Save number of lines the linebuffer leads before the scanout */ | ||
1307 | amdgpu_crtc->lb_vblank_lead_lines = lb_vblank_lead_lines; | ||
1305 | } | 1308 | } |
1306 | 1309 | ||
1307 | /** | 1310 | /** |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index 7427d8cd4c43..ed8abb58a785 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c | |||
@@ -513,7 +513,7 @@ static int gmc_v7_0_gart_enable(struct amdgpu_device *adev) | |||
513 | WREG32(mmVM_L2_CNTL3, tmp); | 513 | WREG32(mmVM_L2_CNTL3, tmp); |
514 | /* setup context0 */ | 514 | /* setup context0 */ |
515 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); | 515 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); |
516 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1); | 516 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12); |
517 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); | 517 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); |
518 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | 518 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
519 | (u32)(adev->dummy_page.addr >> 12)); | 519 | (u32)(adev->dummy_page.addr >> 12)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index cb0e50ebb528..d39028440814 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c | |||
@@ -657,7 +657,7 @@ static int gmc_v8_0_gart_enable(struct amdgpu_device *adev) | |||
657 | WREG32(mmVM_L2_CNTL4, tmp); | 657 | WREG32(mmVM_L2_CNTL4, tmp); |
658 | /* setup context0 */ | 658 | /* setup context0 */ |
659 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); | 659 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_START_ADDR, adev->mc.gtt_start >> 12); |
660 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, (adev->mc.gtt_end >> 12) - 1); | 660 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_END_ADDR, adev->mc.gtt_end >> 12); |
661 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); | 661 | WREG32(mmVM_CONTEXT0_PAGE_TABLE_BASE_ADDR, adev->gart.table_addr >> 12); |
662 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, | 662 | WREG32(mmVM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, |
663 | (u32)(adev->dummy_page.addr >> 12)); | 663 | (u32)(adev->dummy_page.addr >> 12)); |
diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 6a52db6ad8d7..370c6c9d81c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | |||
@@ -40,6 +40,9 @@ | |||
40 | 40 | ||
41 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 | 41 | #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT 0x04 |
42 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 | 42 | #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK 0x10 |
43 | #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0 0x8616 | ||
44 | #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1 0x8617 | ||
45 | #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2 0x8618 | ||
43 | 46 | ||
44 | #define VCE_V3_0_FW_SIZE (384 * 1024) | 47 | #define VCE_V3_0_FW_SIZE (384 * 1024) |
45 | #define VCE_V3_0_STACK_SIZE (64 * 1024) | 48 | #define VCE_V3_0_STACK_SIZE (64 * 1024) |
@@ -130,9 +133,11 @@ static int vce_v3_0_start(struct amdgpu_device *adev) | |||
130 | 133 | ||
131 | /* set BUSY flag */ | 134 | /* set BUSY flag */ |
132 | WREG32_P(mmVCE_STATUS, 1, ~1); | 135 | WREG32_P(mmVCE_STATUS, 1, ~1); |
133 | 136 | if (adev->asic_type >= CHIP_STONEY) | |
134 | WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, | 137 | WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001); |
135 | ~VCE_VCPU_CNTL__CLK_EN_MASK); | 138 | else |
139 | WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK, | ||
140 | ~VCE_VCPU_CNTL__CLK_EN_MASK); | ||
136 | 141 | ||
137 | WREG32_P(mmVCE_SOFT_RESET, | 142 | WREG32_P(mmVCE_SOFT_RESET, |
138 | VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, | 143 | VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK, |
@@ -391,8 +396,12 @@ static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx) | |||
391 | WREG32(mmVCE_LMI_SWAP_CNTL, 0); | 396 | WREG32(mmVCE_LMI_SWAP_CNTL, 0); |
392 | WREG32(mmVCE_LMI_SWAP_CNTL1, 0); | 397 | WREG32(mmVCE_LMI_SWAP_CNTL1, 0); |
393 | WREG32(mmVCE_LMI_VM_CTRL, 0); | 398 | WREG32(mmVCE_LMI_VM_CTRL, 0); |
394 | 399 | if (adev->asic_type >= CHIP_STONEY) { | |
395 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); | 400 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8)); |
401 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8)); | ||
402 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8)); | ||
403 | } else | ||
404 | WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8)); | ||
396 | offset = AMDGPU_VCE_FIRMWARE_OFFSET; | 405 | offset = AMDGPU_VCE_FIRMWARE_OFFSET; |
397 | size = VCE_V3_0_FW_SIZE; | 406 | size = VCE_V3_0_FW_SIZE; |
398 | WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); | 407 | WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff); |
@@ -576,6 +585,11 @@ static int vce_v3_0_process_interrupt(struct amdgpu_device *adev, | |||
576 | struct amdgpu_iv_entry *entry) | 585 | struct amdgpu_iv_entry *entry) |
577 | { | 586 | { |
578 | DRM_DEBUG("IH: VCE\n"); | 587 | DRM_DEBUG("IH: VCE\n"); |
588 | |||
589 | WREG32_P(mmVCE_SYS_INT_STATUS, | ||
590 | VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK, | ||
591 | ~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK); | ||
592 | |||
579 | switch (entry->src_data) { | 593 | switch (entry->src_data) { |
580 | case 0: | 594 | case 0: |
581 | amdgpu_fence_process(&adev->vce.ring[0]); | 595 | amdgpu_fence_process(&adev->vce.ring[0]); |