diff options
Diffstat (limited to 'drivers/gpu/drm/rockchip/rockchip_drm_fb.c')
-rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index f7844883cb76..3b8f652698f8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c | |||
@@ -39,7 +39,6 @@ struct drm_gem_object *rockchip_fb_get_gem_obj(struct drm_framebuffer *fb, | |||
39 | 39 | ||
40 | return rk_fb->obj[plane]; | 40 | return rk_fb->obj[plane]; |
41 | } | 41 | } |
42 | EXPORT_SYMBOL_GPL(rockchip_fb_get_gem_obj); | ||
43 | 42 | ||
44 | static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) | 43 | static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) |
45 | { | 44 | { |
@@ -177,8 +176,23 @@ static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc) | |||
177 | crtc_funcs->wait_for_update(crtc); | 176 | crtc_funcs->wait_for_update(crtc); |
178 | } | 177 | } |
179 | 178 | ||
179 | /* | ||
180 | * We can't use drm_atomic_helper_wait_for_vblanks() because rk3288 and rk3066 | ||
181 | * have hardware counters for neither vblanks nor scanlines, which results in | ||
182 | * a race where: | ||
183 | * | <-- HW vsync irq and reg take effect | ||
184 | * plane_commit --> | | ||
185 | * get_vblank and wait --> | | ||
186 | * | <-- handle_vblank, vblank->count + 1 | ||
187 | * cleanup_fb --> | | ||
188 | * iommu crash --> | | ||
189 | * | <-- HW vsync irq and reg take effect | ||
190 | * | ||
191 | * This function is equivalent but uses rockchip_crtc_wait_for_update() instead | ||
192 | * of waiting for vblank_count to change. | ||
193 | */ | ||
180 | static void | 194 | static void |
181 | rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state) | 195 | rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_state *old_state) |
182 | { | 196 | { |
183 | struct drm_crtc_state *old_crtc_state; | 197 | struct drm_crtc_state *old_crtc_state; |
184 | struct drm_crtc *crtc; | 198 | struct drm_crtc *crtc; |
@@ -194,6 +208,10 @@ rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state) | |||
194 | if (!crtc->state->active) | 208 | if (!crtc->state->active) |
195 | continue; | 209 | continue; |
196 | 210 | ||
211 | if (!drm_atomic_helper_framebuffer_changed(dev, | ||
212 | old_state, crtc)) | ||
213 | continue; | ||
214 | |||
197 | ret = drm_crtc_vblank_get(crtc); | 215 | ret = drm_crtc_vblank_get(crtc); |
198 | if (ret != 0) | 216 | if (ret != 0) |
199 | continue; | 217 | continue; |
@@ -241,7 +259,7 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit) | |||
241 | 259 | ||
242 | drm_atomic_helper_commit_planes(dev, state, true); | 260 | drm_atomic_helper_commit_planes(dev, state, true); |
243 | 261 | ||
244 | rockchip_atomic_wait_for_complete(state); | 262 | rockchip_atomic_wait_for_complete(dev, state); |
245 | 263 | ||
246 | drm_atomic_helper_cleanup_planes(dev, state); | 264 | drm_atomic_helper_cleanup_planes(dev, state); |
247 | 265 | ||