aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/cirrus/cirrus_fbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/cirrus/cirrus_fbdev.c')
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_fbdev.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/gpu/drm/cirrus/cirrus_fbdev.c b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
index e25afccaf85b..3541b567bbd8 100644
--- a/drivers/gpu/drm/cirrus/cirrus_fbdev.c
+++ b/drivers/gpu/drm/cirrus/cirrus_fbdev.c
@@ -27,16 +27,51 @@ static void cirrus_dirty_update(struct cirrus_fbdev *afbdev,
27 int bpp = (afbdev->gfb.base.bits_per_pixel + 7)/8; 27 int bpp = (afbdev->gfb.base.bits_per_pixel + 7)/8;
28 int ret; 28 int ret;
29 bool unmap = false; 29 bool unmap = false;
30 bool store_for_later = false;
31 int x2, y2;
32 unsigned long flags;
30 33
31 obj = afbdev->gfb.obj; 34 obj = afbdev->gfb.obj;
32 bo = gem_to_cirrus_bo(obj); 35 bo = gem_to_cirrus_bo(obj);
33 36
37 /*
38 * try and reserve the BO, if we fail with busy
39 * then the BO is being moved and we should
40 * store up the damage until later.
41 */
34 ret = cirrus_bo_reserve(bo, true); 42 ret = cirrus_bo_reserve(bo, true);
35 if (ret) { 43 if (ret) {
36 DRM_ERROR("failed to reserve fb bo\n"); 44 if (ret != -EBUSY)
45 return;
46 store_for_later = true;
47 }
48
49 x2 = x + width - 1;
50 y2 = y + height - 1;
51 spin_lock_irqsave(&afbdev->dirty_lock, flags);
52
53 if (afbdev->y1 < y)
54 y = afbdev->y1;
55 if (afbdev->y2 > y2)
56 y2 = afbdev->y2;
57 if (afbdev->x1 < x)
58 x = afbdev->x1;
59 if (afbdev->x2 > x2)
60 x2 = afbdev->x2;
61
62 if (store_for_later) {
63 afbdev->x1 = x;
64 afbdev->x2 = x2;
65 afbdev->y1 = y;
66 afbdev->y2 = y2;
67 spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
37 return; 68 return;
38 } 69 }
39 70
71 afbdev->x1 = afbdev->y1 = INT_MAX;
72 afbdev->x2 = afbdev->y2 = 0;
73 spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
74
40 if (!bo->kmap.virtual) { 75 if (!bo->kmap.virtual) {
41 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); 76 ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
42 if (ret) { 77 if (ret) {
@@ -268,6 +303,7 @@ int cirrus_fbdev_init(struct cirrus_device *cdev)
268 303
269 cdev->mode_info.gfbdev = gfbdev; 304 cdev->mode_info.gfbdev = gfbdev;
270 gfbdev->helper.funcs = &cirrus_fb_helper_funcs; 305 gfbdev->helper.funcs = &cirrus_fb_helper_funcs;
306 spin_lock_init(&gfbdev->dirty_lock);
271 307
272 ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper, 308 ret = drm_fb_helper_init(cdev->dev, &gfbdev->helper,
273 cdev->num_crtc, CIRRUSFB_CONN_LIMIT); 309 cdev->num_crtc, CIRRUSFB_CONN_LIMIT);