diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bo.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bo.c | 67 |
1 files changed, 36 insertions, 31 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 028719fddf7..957d1762984 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "nouveau_dma.h" | 34 | #include "nouveau_dma.h" |
35 | 35 | ||
36 | #include <linux/log2.h> | 36 | #include <linux/log2.h> |
37 | #include <linux/slab.h> | ||
37 | 38 | ||
38 | static void | 39 | static void |
39 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) | 40 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) |
@@ -71,7 +72,7 @@ nouveau_bo_fixup_align(struct drm_device *dev, | |||
71 | * many small buffers. | 72 | * many small buffers. |
72 | */ | 73 | */ |
73 | if (dev_priv->card_type == NV_50) { | 74 | if (dev_priv->card_type == NV_50) { |
74 | uint32_t block_size = nouveau_mem_fb_amount(dev) >> 15; | 75 | uint32_t block_size = dev_priv->vram_size >> 15; |
75 | int i; | 76 | int i; |
76 | 77 | ||
77 | switch (tile_flags) { | 78 | switch (tile_flags) { |
@@ -153,7 +154,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
153 | 154 | ||
154 | nvbo->placement.fpfn = 0; | 155 | nvbo->placement.fpfn = 0; |
155 | nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; | 156 | nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; |
156 | nouveau_bo_placement_set(nvbo, flags); | 157 | nouveau_bo_placement_set(nvbo, flags, 0); |
157 | 158 | ||
158 | nvbo->channel = chan; | 159 | nvbo->channel = chan; |
159 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, | 160 | ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, |
@@ -172,26 +173,33 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
172 | return 0; | 173 | return 0; |
173 | } | 174 | } |
174 | 175 | ||
176 | static void | ||
177 | set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags) | ||
178 | { | ||
179 | *n = 0; | ||
180 | |||
181 | if (type & TTM_PL_FLAG_VRAM) | ||
182 | pl[(*n)++] = TTM_PL_FLAG_VRAM | flags; | ||
183 | if (type & TTM_PL_FLAG_TT) | ||
184 | pl[(*n)++] = TTM_PL_FLAG_TT | flags; | ||
185 | if (type & TTM_PL_FLAG_SYSTEM) | ||
186 | pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags; | ||
187 | } | ||
188 | |||
175 | void | 189 | void |
176 | nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype) | 190 | nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) |
177 | { | 191 | { |
178 | int n = 0; | 192 | struct ttm_placement *pl = &nvbo->placement; |
179 | 193 | uint32_t flags = TTM_PL_MASK_CACHING | | |
180 | if (memtype & TTM_PL_FLAG_VRAM) | 194 | (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0); |
181 | nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING; | 195 | |
182 | if (memtype & TTM_PL_FLAG_TT) | 196 | pl->placement = nvbo->placements; |
183 | nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; | 197 | set_placement_list(nvbo->placements, &pl->num_placement, |
184 | if (memtype & TTM_PL_FLAG_SYSTEM) | 198 | type, flags); |
185 | nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; | 199 | |
186 | nvbo->placement.placement = nvbo->placements; | 200 | pl->busy_placement = nvbo->busy_placements; |
187 | nvbo->placement.busy_placement = nvbo->placements; | 201 | set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, |
188 | nvbo->placement.num_placement = n; | 202 | type | busy, flags); |
189 | nvbo->placement.num_busy_placement = n; | ||
190 | |||
191 | if (nvbo->pin_refcnt) { | ||
192 | while (n--) | ||
193 | nvbo->placements[n] |= TTM_PL_FLAG_NO_EVICT; | ||
194 | } | ||
195 | } | 203 | } |
196 | 204 | ||
197 | int | 205 | int |
@@ -199,7 +207,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) | |||
199 | { | 207 | { |
200 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); | 208 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); |
201 | struct ttm_buffer_object *bo = &nvbo->bo; | 209 | struct ttm_buffer_object *bo = &nvbo->bo; |
202 | int ret, i; | 210 | int ret; |
203 | 211 | ||
204 | if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { | 212 | if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { |
205 | NV_ERROR(nouveau_bdev(bo->bdev)->dev, | 213 | NV_ERROR(nouveau_bdev(bo->bdev)->dev, |
@@ -215,9 +223,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) | |||
215 | if (ret) | 223 | if (ret) |
216 | goto out; | 224 | goto out; |
217 | 225 | ||
218 | nouveau_bo_placement_set(nvbo, memtype); | 226 | nouveau_bo_placement_set(nvbo, memtype, 0); |
219 | for (i = 0; i < nvbo->placement.num_placement; i++) | ||
220 | nvbo->placements[i] |= TTM_PL_FLAG_NO_EVICT; | ||
221 | 227 | ||
222 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); | 228 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); |
223 | if (ret == 0) { | 229 | if (ret == 0) { |
@@ -244,7 +250,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) | |||
244 | { | 250 | { |
245 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); | 251 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); |
246 | struct ttm_buffer_object *bo = &nvbo->bo; | 252 | struct ttm_buffer_object *bo = &nvbo->bo; |
247 | int ret, i; | 253 | int ret; |
248 | 254 | ||
249 | if (--nvbo->pin_refcnt) | 255 | if (--nvbo->pin_refcnt) |
250 | return 0; | 256 | return 0; |
@@ -253,8 +259,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) | |||
253 | if (ret) | 259 | if (ret) |
254 | return ret; | 260 | return ret; |
255 | 261 | ||
256 | for (i = 0; i < nvbo->placement.num_placement; i++) | 262 | nouveau_bo_placement_set(nvbo, bo->mem.placement, 0); |
257 | nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT; | ||
258 | 263 | ||
259 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); | 264 | ret = ttm_bo_validate(bo, &nvbo->placement, false, false); |
260 | if (ret == 0) { | 265 | if (ret == 0) { |
@@ -395,8 +400,8 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
395 | man->io_addr = NULL; | 400 | man->io_addr = NULL; |
396 | man->io_offset = drm_get_resource_start(dev, 1); | 401 | man->io_offset = drm_get_resource_start(dev, 1); |
397 | man->io_size = drm_get_resource_len(dev, 1); | 402 | man->io_size = drm_get_resource_len(dev, 1); |
398 | if (man->io_size > nouveau_mem_fb_amount(dev)) | 403 | if (man->io_size > dev_priv->vram_size) |
399 | man->io_size = nouveau_mem_fb_amount(dev); | 404 | man->io_size = dev_priv->vram_size; |
400 | 405 | ||
401 | man->gpu_offset = dev_priv->vm_vram_base; | 406 | man->gpu_offset = dev_priv->vm_vram_base; |
402 | break; | 407 | break; |
@@ -439,11 +444,11 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) | |||
439 | 444 | ||
440 | switch (bo->mem.mem_type) { | 445 | switch (bo->mem.mem_type) { |
441 | case TTM_PL_VRAM: | 446 | case TTM_PL_VRAM: |
442 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT | | 447 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT, |
443 | TTM_PL_FLAG_SYSTEM); | 448 | TTM_PL_FLAG_SYSTEM); |
444 | break; | 449 | break; |
445 | default: | 450 | default: |
446 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); | 451 | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0); |
447 | break; | 452 | break; |
448 | } | 453 | } |
449 | 454 | ||