aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/rockchip/rockchip_drm_fb.c')
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_fb.c24
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}
42EXPORT_SYMBOL_GPL(rockchip_fb_get_gem_obj);
43 42
44static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) 43static 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 */
180static void 194static void
181rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state) 195rockchip_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