aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c15
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c17
4 files changed, 28 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index c41e1c200ef5..d8817b4bb189 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -683,17 +683,24 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
683 int ret; 683 int ret;
684 684
685 chan = nvbo->channel; 685 chan = nvbo->channel;
686 if (!chan || nvbo->no_vm) 686 if (!chan || nvbo->no_vm) {
687 chan = dev_priv->channel; 687 chan = dev_priv->channel;
688 mutex_lock(&chan->mutex);
689 }
688 690
689 if (dev_priv->card_type < NV_50) 691 if (dev_priv->card_type < NV_50)
690 ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); 692 ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
691 else 693 else
692 ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem); 694 ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem);
693 if (ret) 695 if (ret == 0) {
694 return ret; 696 ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict,
697 no_wait_reserve,
698 no_wait_gpu, new_mem);
699 }
695 700
696 return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait_reserve, no_wait_gpu, new_mem); 701 if (chan == dev_priv->channel)
702 mutex_unlock(&chan->mutex);
703 return ret;
697} 704}
698 705
699static int 706static int
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 373950e34814..8636478c477a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -145,6 +145,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
145 chan->file_priv = file_priv; 145 chan->file_priv = file_priv;
146 chan->vram_handle = vram_handle; 146 chan->vram_handle = vram_handle;
147 chan->gart_handle = tt_handle; 147 chan->gart_handle = tt_handle;
148 mutex_init(&chan->mutex);
148 149
149 NV_INFO(dev, "Allocating FIFO number %d\n", channel); 150 NV_INFO(dev, "Allocating FIFO number %d\n", channel);
150 151
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 1c7db64c03bf..04bc56cf4f1a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -166,6 +166,8 @@ struct nouveau_channel {
166 struct drm_device *dev; 166 struct drm_device *dev;
167 int id; 167 int id;
168 168
169 struct mutex mutex;
170
169 /* owner of this fifo */ 171 /* owner of this fifo */
170 struct drm_file *file_priv; 172 struct drm_file *file_priv;
171 /* mapping of the fifo itself */ 173 /* mapping of the fifo itself */
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
index 22e83adcc930..bc30dbe11d00 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
@@ -62,11 +62,13 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
62 62
63 ret = -ENODEV; 63 ret = -ENODEV;
64 if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { 64 if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) {
65 mutex_lock(&dev_priv->channel->mutex);
65 if (dev_priv->card_type < NV_50) 66 if (dev_priv->card_type < NV_50)
66 ret = nv04_fbcon_fillrect(info, rect); 67 ret = nv04_fbcon_fillrect(info, rect);
67 else 68 else
68 if (dev_priv->card_type < NV_C0) 69 if (dev_priv->card_type < NV_C0)
69 ret = nv50_fbcon_fillrect(info, rect); 70 ret = nv50_fbcon_fillrect(info, rect);
71 mutex_unlock(&dev_priv->channel->mutex);
70 } 72 }
71 73
72 if (ret == 0) 74 if (ret == 0)
@@ -90,11 +92,13 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
90 92
91 ret = -ENODEV; 93 ret = -ENODEV;
92 if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { 94 if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) {
95 mutex_lock(&dev_priv->channel->mutex);
93 if (dev_priv->card_type < NV_50) 96 if (dev_priv->card_type < NV_50)
94 ret = nv04_fbcon_copyarea(info, image); 97 ret = nv04_fbcon_copyarea(info, image);
95 else 98 else
96 if (dev_priv->card_type < NV_C0) 99 if (dev_priv->card_type < NV_C0)
97 ret = nv50_fbcon_copyarea(info, image); 100 ret = nv50_fbcon_copyarea(info, image);
101 mutex_unlock(&dev_priv->channel->mutex);
98 } 102 }
99 103
100 if (ret == 0) 104 if (ret == 0)
@@ -118,11 +122,13 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
118 122
119 ret = -ENODEV; 123 ret = -ENODEV;
120 if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { 124 if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) {
125 mutex_lock(&dev_priv->channel->mutex);
121 if (dev_priv->card_type < NV_50) 126 if (dev_priv->card_type < NV_50)
122 ret = nv04_fbcon_imageblit(info, image); 127 ret = nv04_fbcon_imageblit(info, image);
123 else 128 else
124 if (dev_priv->card_type < NV_C0) 129 if (dev_priv->card_type < NV_C0)
125 ret = nv50_fbcon_imageblit(info, image); 130 ret = nv50_fbcon_imageblit(info, image);
131 mutex_unlock(&dev_priv->channel->mutex);
126 } 132 }
127 133
128 if (ret == 0) 134 if (ret == 0)
@@ -142,12 +148,15 @@ nouveau_fbcon_sync(struct fb_info *info)
142 struct nouveau_channel *chan = dev_priv->channel; 148 struct nouveau_channel *chan = dev_priv->channel;
143 int ret, i; 149 int ret, i;
144 150
145 if (!chan || !chan->accel_done || 151 if (!chan || !chan->accel_done || in_interrupt() ||
146 info->state != FBINFO_STATE_RUNNING || 152 info->state != FBINFO_STATE_RUNNING ||
147 info->flags & FBINFO_HWACCEL_DISABLED) 153 info->flags & FBINFO_HWACCEL_DISABLED)
148 return 0; 154 return 0;
149 155
150 if (RING_SPACE(chan, 4)) { 156 mutex_lock(&chan->mutex);
157 ret = RING_SPACE(chan, 4);
158 if (ret) {
159 mutex_unlock(&chan->mutex);
151 nouveau_fbcon_gpu_lockup(info); 160 nouveau_fbcon_gpu_lockup(info);
152 return 0; 161 return 0;
153 } 162 }
@@ -158,6 +167,7 @@ nouveau_fbcon_sync(struct fb_info *info)
158 OUT_RING(chan, 0); 167 OUT_RING(chan, 0);
159 nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); 168 nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff);
160 FIRE_RING(chan); 169 FIRE_RING(chan);
170 mutex_unlock(&chan->mutex);
161 171
162 ret = -EBUSY; 172 ret = -EBUSY;
163 for (i = 0; i < 100000; i++) { 173 for (i = 0; i < 100000; i++) {
@@ -353,6 +363,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
353 info->pixmap.flags = FB_PIXMAP_SYSTEM; 363 info->pixmap.flags = FB_PIXMAP_SYSTEM;
354 info->pixmap.scan_align = 1; 364 info->pixmap.scan_align = 1;
355 365
366 mutex_unlock(&dev->struct_mutex);
367
356 if (dev_priv->channel && !nouveau_nofbaccel) { 368 if (dev_priv->channel && !nouveau_nofbaccel) {
357 ret = -ENODEV; 369 ret = -ENODEV;
358 if (dev_priv->card_type < NV_50) 370 if (dev_priv->card_type < NV_50)
@@ -373,7 +385,6 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
373 nouveau_fb->base.height, 385 nouveau_fb->base.height,
374 nvbo->bo.offset, nvbo); 386 nvbo->bo.offset, nvbo);
375 387
376 mutex_unlock(&dev->struct_mutex);
377 vga_switcheroo_client_fb_set(dev->pdev, info); 388 vga_switcheroo_client_fb_set(dev->pdev, info);
378 return 0; 389 return 0;
379 390