aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-03-18 08:07:47 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-04-08 20:11:54 -0400
commit78ad0f7bf2bb667729581f099781fc0b7ae58fcc (patch)
tree634b93b257da7f6ac4b67adcea209b920356fa3f /drivers
parent40b2a687bd92827ca144d3623cf48377d8f7680d (diff)
drm/nouveau: Make use of TTM busy_placements.
Previously we were filling it the same as "placements", but in some cases there're valid alternatives that we were ignoring completely. Keeping a back-up memory type helps on several low-mem situations. Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c61
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c55
3 files changed, 61 insertions, 59 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 026612471c92..418d881050a0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -153,7 +153,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
153 153
154 nvbo->placement.fpfn = 0; 154 nvbo->placement.fpfn = 0;
155 nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0; 155 nvbo->placement.lpfn = mappable ? dev_priv->fb_mappable_pages : 0;
156 nouveau_bo_placement_set(nvbo, flags); 156 nouveau_bo_placement_set(nvbo, flags, 0);
157 157
158 nvbo->channel = chan; 158 nvbo->channel = chan;
159 ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size, 159 ret = ttm_bo_init(&dev_priv->ttm.bdev, &nvbo->bo, size,
@@ -172,26 +172,33 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan,
172 return 0; 172 return 0;
173} 173}
174 174
175static void
176set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
177{
178 *n = 0;
179
180 if (type & TTM_PL_FLAG_VRAM)
181 pl[(*n)++] = TTM_PL_FLAG_VRAM | flags;
182 if (type & TTM_PL_FLAG_TT)
183 pl[(*n)++] = TTM_PL_FLAG_TT | flags;
184 if (type & TTM_PL_FLAG_SYSTEM)
185 pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
186}
187
175void 188void
176nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype) 189nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
177{ 190{
178 int n = 0; 191 struct ttm_placement *pl = &nvbo->placement;
179 192 uint32_t flags = TTM_PL_MASK_CACHING |
180 if (memtype & TTM_PL_FLAG_VRAM) 193 (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0);
181 nvbo->placements[n++] = TTM_PL_FLAG_VRAM | TTM_PL_MASK_CACHING; 194
182 if (memtype & TTM_PL_FLAG_TT) 195 pl->placement = nvbo->placements;
183 nvbo->placements[n++] = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING; 196 set_placement_list(nvbo->placements, &pl->num_placement,
184 if (memtype & TTM_PL_FLAG_SYSTEM) 197 type, flags);
185 nvbo->placements[n++] = TTM_PL_FLAG_SYSTEM | TTM_PL_MASK_CACHING; 198
186 nvbo->placement.placement = nvbo->placements; 199 pl->busy_placement = nvbo->busy_placements;
187 nvbo->placement.busy_placement = nvbo->placements; 200 set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
188 nvbo->placement.num_placement = n; 201 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} 202}
196 203
197int 204int
@@ -199,7 +206,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
199{ 206{
200 struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); 207 struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
201 struct ttm_buffer_object *bo = &nvbo->bo; 208 struct ttm_buffer_object *bo = &nvbo->bo;
202 int ret, i; 209 int ret;
203 210
204 if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) { 211 if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
205 NV_ERROR(nouveau_bdev(bo->bdev)->dev, 212 NV_ERROR(nouveau_bdev(bo->bdev)->dev,
@@ -215,9 +222,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
215 if (ret) 222 if (ret)
216 goto out; 223 goto out;
217 224
218 nouveau_bo_placement_set(nvbo, memtype); 225 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 226
222 ret = ttm_bo_validate(bo, &nvbo->placement, false, false); 227 ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
223 if (ret == 0) { 228 if (ret == 0) {
@@ -244,7 +249,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
244{ 249{
245 struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); 250 struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev);
246 struct ttm_buffer_object *bo = &nvbo->bo; 251 struct ttm_buffer_object *bo = &nvbo->bo;
247 int ret, i; 252 int ret;
248 253
249 if (--nvbo->pin_refcnt) 254 if (--nvbo->pin_refcnt)
250 return 0; 255 return 0;
@@ -253,8 +258,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
253 if (ret) 258 if (ret)
254 return ret; 259 return ret;
255 260
256 for (i = 0; i < nvbo->placement.num_placement; i++) 261 nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
257 nvbo->placements[i] &= ~TTM_PL_FLAG_NO_EVICT;
258 262
259 ret = ttm_bo_validate(bo, &nvbo->placement, false, false); 263 ret = ttm_bo_validate(bo, &nvbo->placement, false, false);
260 if (ret == 0) { 264 if (ret == 0) {
@@ -439,10 +443,11 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
439 443
440 switch (bo->mem.mem_type) { 444 switch (bo->mem.mem_type) {
441 case TTM_PL_VRAM: 445 case TTM_PL_VRAM:
442 nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT); 446 nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT,
447 TTM_PL_FLAG_SYSTEM);
443 break; 448 break;
444 default: 449 default:
445 nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); 450 nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0);
446 break; 451 break;
447 } 452 }
448 453
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index d8b559011777..fd17fae9369c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -76,6 +76,7 @@ struct nouveau_bo {
76 struct ttm_buffer_object bo; 76 struct ttm_buffer_object bo;
77 struct ttm_placement placement; 77 struct ttm_placement placement;
78 u32 placements[3]; 78 u32 placements[3];
79 u32 busy_placements[3];
79 struct ttm_bo_kmap_obj kmap; 80 struct ttm_bo_kmap_obj kmap;
80 struct list_head head; 81 struct list_head head;
81 82
@@ -1124,7 +1125,8 @@ extern int nouveau_bo_pin(struct nouveau_bo *, uint32_t flags);
1124extern int nouveau_bo_unpin(struct nouveau_bo *); 1125extern int nouveau_bo_unpin(struct nouveau_bo *);
1125extern int nouveau_bo_map(struct nouveau_bo *); 1126extern int nouveau_bo_map(struct nouveau_bo *);
1126extern void nouveau_bo_unmap(struct nouveau_bo *); 1127extern void nouveau_bo_unmap(struct nouveau_bo *);
1127extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype); 1128extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type,
1129 uint32_t busy);
1128extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); 1130extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index);
1129extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); 1131extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val);
1130extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); 1132extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index);
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index 0d22f66f1c79..1bc0b38a5167 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -180,40 +180,35 @@ nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
180{ 180{
181 struct nouveau_bo *nvbo = gem->driver_private; 181 struct nouveau_bo *nvbo = gem->driver_private;
182 struct ttm_buffer_object *bo = &nvbo->bo; 182 struct ttm_buffer_object *bo = &nvbo->bo;
183 uint64_t flags; 183 uint32_t domains = valid_domains &
184 (write_domains ? write_domains : read_domains);
185 uint32_t pref_flags = 0, valid_flags = 0;
184 186
185 if (!valid_domains || (!read_domains && !write_domains)) 187 if (!domains)
186 return -EINVAL; 188 return -EINVAL;
187 189
188 if (write_domains) { 190 if (valid_domains & NOUVEAU_GEM_DOMAIN_VRAM)
189 if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && 191 valid_flags |= TTM_PL_FLAG_VRAM;
190 (write_domains & NOUVEAU_GEM_DOMAIN_VRAM)) 192
191 flags = TTM_PL_FLAG_VRAM; 193 if (valid_domains & NOUVEAU_GEM_DOMAIN_GART)
192 else 194 valid_flags |= TTM_PL_FLAG_TT;
193 if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && 195
194 (write_domains & NOUVEAU_GEM_DOMAIN_GART)) 196 if ((domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
195 flags = TTM_PL_FLAG_TT; 197 bo->mem.mem_type == TTM_PL_VRAM)
196 else 198 pref_flags |= TTM_PL_FLAG_VRAM;
197 return -EINVAL; 199
198 } else { 200 else if ((domains & NOUVEAU_GEM_DOMAIN_GART) &&
199 if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && 201 bo->mem.mem_type == TTM_PL_TT)
200 (read_domains & NOUVEAU_GEM_DOMAIN_VRAM) && 202 pref_flags |= TTM_PL_FLAG_TT;
201 bo->mem.mem_type == TTM_PL_VRAM) 203
202 flags = TTM_PL_FLAG_VRAM; 204 else if (domains & NOUVEAU_GEM_DOMAIN_VRAM)
203 else 205 pref_flags |= TTM_PL_FLAG_VRAM;
204 if ((valid_domains & NOUVEAU_GEM_DOMAIN_GART) && 206
205 (read_domains & NOUVEAU_GEM_DOMAIN_GART) && 207 else
206 bo->mem.mem_type == TTM_PL_TT) 208 pref_flags |= TTM_PL_FLAG_TT;
207 flags = TTM_PL_FLAG_TT; 209
208 else 210 nouveau_bo_placement_set(nvbo, pref_flags, valid_flags);
209 if ((valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) &&
210 (read_domains & NOUVEAU_GEM_DOMAIN_VRAM))
211 flags = TTM_PL_FLAG_VRAM;
212 else
213 flags = TTM_PL_FLAG_TT;
214 }
215 211
216 nouveau_bo_placement_set(nvbo, flags);
217 return 0; 212 return 0;
218} 213}
219 214