mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 08:33:17 +02:00
drm/nouveau: add helper functions for allocating pinned/cpu-mapped bos
Replace some awkward sequences that are repeated in a number of places with helper functions. Signed-off-by: Ben Skeggs <bskeggs@nvidia.com> Reviewed-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Timur Tabi <ttabi@nvidia.com> Tested-by: Timur Tabi <ttabi@nvidia.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
44f93b209e
commit
627664de4b
|
|
@ -768,9 +768,7 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
|
|||
disp->image[nv_crtc->index] = NULL;
|
||||
}
|
||||
|
||||
nouveau_bo_unmap(nv_crtc->cursor.nvbo);
|
||||
nouveau_bo_unpin(nv_crtc->cursor.nvbo);
|
||||
nouveau_bo_fini(nv_crtc->cursor.nvbo);
|
||||
nouveau_bo_unpin_del(&nv_crtc->cursor.nvbo);
|
||||
nvif_event_dtor(&nv_crtc->vblank);
|
||||
nvif_head_dtor(&nv_crtc->head);
|
||||
kfree(nv_crtc);
|
||||
|
|
@ -1303,6 +1301,7 @@ nv04_crtc_vblank_handler(struct nvif_event *event, void *repv, u32 repc)
|
|||
int
|
||||
nv04_crtc_create(struct drm_device *dev, int crtc_num)
|
||||
{
|
||||
struct nouveau_cli *cli = &nouveau_drm(dev)->client;
|
||||
struct nouveau_display *disp = nouveau_display(dev);
|
||||
struct nouveau_crtc *nv_crtc;
|
||||
struct drm_plane *primary;
|
||||
|
|
@ -1336,20 +1335,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
|
|||
drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs);
|
||||
drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256);
|
||||
|
||||
ret = nouveau_bo_new(&nouveau_drm(dev)->client, 64*64*4, 0x100,
|
||||
NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, NULL, NULL,
|
||||
&nv_crtc->cursor.nvbo);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo,
|
||||
NOUVEAU_GEM_DOMAIN_VRAM, false);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
|
||||
if (ret)
|
||||
nouveau_bo_unpin(nv_crtc->cursor.nvbo);
|
||||
}
|
||||
if (ret)
|
||||
nouveau_bo_fini(nv_crtc->cursor.nvbo);
|
||||
}
|
||||
ret = nouveau_bo_new_map(cli, NOUVEAU_GEM_DOMAIN_VRAM, 64 * 64 * 4, &nv_crtc->cursor.nvbo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv04_cursor_init(nv_crtc);
|
||||
|
||||
|
|
|
|||
|
|
@ -2808,10 +2808,7 @@ nv50_display_destroy(struct drm_device *dev)
|
|||
nvif_object_dtor(&disp->caps);
|
||||
nv50_core_del(&disp->core);
|
||||
|
||||
nouveau_bo_unmap(disp->sync);
|
||||
if (disp->sync)
|
||||
nouveau_bo_unpin(disp->sync);
|
||||
nouveau_bo_fini(disp->sync);
|
||||
nouveau_bo_unpin_del(&disp->sync);
|
||||
|
||||
nouveau_display(dev)->priv = NULL;
|
||||
kfree(disp);
|
||||
|
|
@ -2843,20 +2840,7 @@ nv50_display_create(struct drm_device *dev)
|
|||
dev->mode_config.normalize_zpos = true;
|
||||
|
||||
/* small shared memory area we use for notifiers and semaphores */
|
||||
ret = nouveau_bo_new(&drm->client, 4096, 0x1000,
|
||||
NOUVEAU_GEM_DOMAIN_VRAM,
|
||||
0, 0x0000, NULL, NULL, &disp->sync);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_pin(disp->sync, NOUVEAU_GEM_DOMAIN_VRAM, true);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_map(disp->sync);
|
||||
if (ret)
|
||||
nouveau_bo_unpin(disp->sync);
|
||||
}
|
||||
if (ret)
|
||||
nouveau_bo_fini(disp->sync);
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &disp->sync);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -401,6 +401,61 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nouveau_bo_unpin_del(struct nouveau_bo **pnvbo)
|
||||
{
|
||||
struct nouveau_bo *nvbo = *pnvbo;
|
||||
|
||||
if (!nvbo)
|
||||
return;
|
||||
|
||||
nouveau_bo_unmap(nvbo);
|
||||
nouveau_bo_unpin(nvbo);
|
||||
nouveau_bo_fini(nvbo);
|
||||
|
||||
*pnvbo = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_bo_new_pin(struct nouveau_cli *cli, u32 domain, u32 size, struct nouveau_bo **pnvbo)
|
||||
{
|
||||
struct nouveau_bo *nvbo;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_bo_new(cli, size, 0, domain, 0, 0, NULL, NULL, &nvbo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_bo_pin(nvbo, domain, false);
|
||||
if (ret) {
|
||||
nouveau_bo_fini(nvbo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*pnvbo = nvbo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nouveau_bo_new_map(struct nouveau_cli *cli, u32 domain, u32 size, struct nouveau_bo **pnvbo)
|
||||
{
|
||||
struct nouveau_bo *nvbo;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_bo_new_pin(cli, domain, size, &nvbo);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_bo_map(nvbo);
|
||||
if (ret) {
|
||||
nouveau_bo_unpin_del(&nvbo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*pnvbo = nvbo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_placement_range(struct nouveau_bo *nvbo, uint32_t domain)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ struct nouveau_channel;
|
|||
struct nouveau_cli;
|
||||
struct nouveau_drm;
|
||||
struct nouveau_fence;
|
||||
struct nouveau_vma;
|
||||
|
||||
struct nouveau_bo {
|
||||
struct ttm_buffer_object bo;
|
||||
|
|
@ -89,6 +90,10 @@ void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo);
|
|||
void nouveau_bo_add_io_reserve_lru(struct ttm_buffer_object *bo);
|
||||
void nouveau_bo_del_io_reserve_lru(struct ttm_buffer_object *bo);
|
||||
|
||||
int nouveau_bo_new_pin(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **);
|
||||
int nouveau_bo_new_map(struct nouveau_cli *, u32 domain, u32 size, struct nouveau_bo **);
|
||||
void nouveau_bo_unpin_del(struct nouveau_bo **);
|
||||
|
||||
/* TODO: submit equivalent to TTM generic API upstream? */
|
||||
static inline void __iomem *
|
||||
nvbo_kmap_obj_iovirtual(struct nouveau_bo *nvbo)
|
||||
|
|
|
|||
|
|
@ -105,10 +105,7 @@ nouveau_channel_del(struct nouveau_channel **pchan)
|
|||
nvif_mem_dtor(&chan->mem_userd);
|
||||
nvif_object_dtor(&chan->push.ctxdma);
|
||||
nouveau_vma_del(&chan->push.vma);
|
||||
nouveau_bo_unmap(chan->push.buffer);
|
||||
if (chan->push.buffer && chan->push.buffer->bo.pin_count)
|
||||
nouveau_bo_unpin(chan->push.buffer);
|
||||
nouveau_bo_fini(chan->push.buffer);
|
||||
nouveau_bo_unpin_del(&chan->push.buffer);
|
||||
kfree(chan);
|
||||
}
|
||||
*pchan = NULL;
|
||||
|
|
@ -163,14 +160,7 @@ nouveau_channel_prep(struct nouveau_cli *cli,
|
|||
if (nouveau_vram_pushbuf)
|
||||
target = NOUVEAU_GEM_DOMAIN_VRAM;
|
||||
|
||||
ret = nouveau_bo_new(cli, size, 0, target, 0, 0, NULL, NULL,
|
||||
&chan->push.buffer);
|
||||
if (ret == 0) {
|
||||
ret = nouveau_bo_pin(chan->push.buffer, target, false);
|
||||
if (ret == 0)
|
||||
ret = nouveau_bo_map(chan->push.buffer);
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_map(cli, target, size, &chan->push.buffer);
|
||||
if (ret) {
|
||||
nouveau_channel_del(pchan);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -256,20 +256,15 @@ nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage)
|
|||
chunk->pagemap.ops = &nouveau_dmem_pagemap_ops;
|
||||
chunk->pagemap.owner = drm->dev;
|
||||
|
||||
ret = nouveau_bo_new(&drm->client, DMEM_CHUNK_SIZE, 0,
|
||||
NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, NULL, NULL,
|
||||
&chunk->bo);
|
||||
ret = nouveau_bo_new_pin(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, DMEM_CHUNK_SIZE,
|
||||
&chunk->bo);
|
||||
if (ret)
|
||||
goto out_release;
|
||||
|
||||
ret = nouveau_bo_pin(chunk->bo, NOUVEAU_GEM_DOMAIN_VRAM, false);
|
||||
if (ret)
|
||||
goto out_bo_free;
|
||||
|
||||
ptr = memremap_pages(&chunk->pagemap, numa_node_id());
|
||||
if (IS_ERR(ptr)) {
|
||||
ret = PTR_ERR(ptr);
|
||||
goto out_bo_unpin;
|
||||
goto out_bo_free;
|
||||
}
|
||||
|
||||
mutex_lock(&drm->dmem->mutex);
|
||||
|
|
@ -292,10 +287,8 @@ nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage)
|
|||
|
||||
return 0;
|
||||
|
||||
out_bo_unpin:
|
||||
nouveau_bo_unpin(chunk->bo);
|
||||
out_bo_free:
|
||||
nouveau_bo_fini(chunk->bo);
|
||||
nouveau_bo_unpin_del(&chunk->bo);
|
||||
out_release:
|
||||
release_mem_region(chunk->pagemap.range.start, range_len(&chunk->pagemap.range));
|
||||
out_free:
|
||||
|
|
@ -426,8 +419,7 @@ nouveau_dmem_fini(struct nouveau_drm *drm)
|
|||
|
||||
list_for_each_entry_safe(chunk, tmp, &drm->dmem->chunks, list) {
|
||||
nouveau_dmem_evict_chunk(chunk);
|
||||
nouveau_bo_unpin(chunk->bo);
|
||||
nouveau_bo_fini(chunk->bo);
|
||||
nouveau_bo_unpin_del(&chunk->bo);
|
||||
WARN_ON(chunk->callocated);
|
||||
list_del(&chunk->list);
|
||||
memunmap_pages(&chunk->pagemap);
|
||||
|
|
|
|||
|
|
@ -85,10 +85,8 @@ void
|
|||
nv10_fence_destroy(struct nouveau_drm *drm)
|
||||
{
|
||||
struct nv10_fence_priv *priv = drm->fence;
|
||||
nouveau_bo_unmap(priv->bo);
|
||||
if (priv->bo)
|
||||
nouveau_bo_unpin(priv->bo);
|
||||
nouveau_bo_fini(priv->bo);
|
||||
|
||||
nouveau_bo_unpin_del(&priv->bo);
|
||||
drm->fence = NULL;
|
||||
kfree(priv);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,20 +130,7 @@ nv17_fence_create(struct nouveau_drm *drm)
|
|||
priv->base.context_del = nv10_fence_context_del;
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
ret = nouveau_bo_new(&drm->client, 4096, 0x1000,
|
||||
NOUVEAU_GEM_DOMAIN_VRAM,
|
||||
0, 0x0000, NULL, NULL, &priv->bo);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_pin(priv->bo, NOUVEAU_GEM_DOMAIN_VRAM, false);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_map(priv->bo);
|
||||
if (ret)
|
||||
nouveau_bo_unpin(priv->bo);
|
||||
}
|
||||
if (ret)
|
||||
nouveau_bo_fini(priv->bo);
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &priv->bo);
|
||||
if (ret) {
|
||||
nv10_fence_destroy(drm);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -81,20 +81,7 @@ nv50_fence_create(struct nouveau_drm *drm)
|
|||
priv->base.context_del = nv10_fence_context_del;
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
ret = nouveau_bo_new(&drm->client, 4096, 0x1000,
|
||||
NOUVEAU_GEM_DOMAIN_VRAM,
|
||||
0, 0x0000, NULL, NULL, &priv->bo);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_pin(priv->bo, NOUVEAU_GEM_DOMAIN_VRAM, false);
|
||||
if (!ret) {
|
||||
ret = nouveau_bo_map(priv->bo);
|
||||
if (ret)
|
||||
nouveau_bo_unpin(priv->bo);
|
||||
}
|
||||
if (ret)
|
||||
nouveau_bo_fini(priv->bo);
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_map(&drm->client, NOUVEAU_GEM_DOMAIN_VRAM, PAGE_SIZE, &priv->bo);
|
||||
if (ret) {
|
||||
nv10_fence_destroy(drm);
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -185,10 +185,8 @@ static void
|
|||
nv84_fence_destroy(struct nouveau_drm *drm)
|
||||
{
|
||||
struct nv84_fence_priv *priv = drm->fence;
|
||||
nouveau_bo_unmap(priv->bo);
|
||||
if (priv->bo)
|
||||
nouveau_bo_unpin(priv->bo);
|
||||
nouveau_bo_fini(priv->bo);
|
||||
|
||||
nouveau_bo_unpin_del(&priv->bo);
|
||||
drm->fence = NULL;
|
||||
kfree(priv);
|
||||
}
|
||||
|
|
@ -222,19 +220,8 @@ nv84_fence_create(struct nouveau_drm *drm)
|
|||
* will lose CPU/GPU coherency!
|
||||
*/
|
||||
NOUVEAU_GEM_DOMAIN_GART | NOUVEAU_GEM_DOMAIN_COHERENT;
|
||||
ret = nouveau_bo_new(&drm->client, 16 * drm->chan_total, 0,
|
||||
domain, 0, 0, NULL, NULL, &priv->bo);
|
||||
if (ret == 0) {
|
||||
ret = nouveau_bo_pin(priv->bo, domain, false);
|
||||
if (ret == 0) {
|
||||
ret = nouveau_bo_map(priv->bo);
|
||||
if (ret)
|
||||
nouveau_bo_unpin(priv->bo);
|
||||
}
|
||||
if (ret)
|
||||
nouveau_bo_fini(priv->bo);
|
||||
}
|
||||
|
||||
ret = nouveau_bo_new_map(&drm->client, domain, 16 * drm->chan_total, &priv->bo);
|
||||
if (ret)
|
||||
nv84_fence_destroy(drm);
|
||||
return ret;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user