diff options
author | Francisco Jerez <currojerez@riseup.net> | 2010-03-18 08:07:47 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-04-08 20:11:54 -0400 |
commit | 78ad0f7bf2bb667729581f099781fc0b7ae58fcc (patch) | |
tree | 634b93b257da7f6ac4b67adcea209b920356fa3f /drivers | |
parent | 40b2a687bd92827ca144d3623cf48377d8f7680d (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.c | 61 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_gem.c | 55 |
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 | ||
175 | static void | ||
176 | set_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 | |||
175 | void | 188 | void |
176 | nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t memtype) | 189 | nouveau_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 | ||
197 | int | 204 | int |
@@ -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); | |||
1124 | extern int nouveau_bo_unpin(struct nouveau_bo *); | 1125 | extern int nouveau_bo_unpin(struct nouveau_bo *); |
1125 | extern int nouveau_bo_map(struct nouveau_bo *); | 1126 | extern int nouveau_bo_map(struct nouveau_bo *); |
1126 | extern void nouveau_bo_unmap(struct nouveau_bo *); | 1127 | extern void nouveau_bo_unmap(struct nouveau_bo *); |
1127 | extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t memtype); | 1128 | extern void nouveau_bo_placement_set(struct nouveau_bo *, uint32_t type, |
1129 | uint32_t busy); | ||
1128 | extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); | 1130 | extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); |
1129 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); | 1131 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); |
1130 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); | 1132 | extern 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 | ||