Exemplo n.º 1
0
static int
nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
                 struct drm_nouveau_gem_info *rep)
{
    struct nouveau_cli *cli = nouveau_cli(file_priv);
    struct nouveau_bo *nvbo = nouveau_gem_object(gem);
    struct nouveau_vma *vma;

    if (nvbo->bo.mem.mem_type == TTM_PL_TT)
        rep->domain = NOUVEAU_GEM_DOMAIN_GART;
    else
        rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;

    rep->offset = nvbo->bo.offset;
    if (cli->base.vm) {
        vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
        if (!vma)
            return -EINVAL;

        rep->offset = vma->offset;
    }

    rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
    rep->map_handle = nvbo->bo.addr_space_offset;
    rep->tile_mode = nvbo->tile_mode;
    rep->tile_flags = nvbo->tile_flags;
    return 0;
}
Exemplo n.º 2
0
void
nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
	struct device *dev = drm->dev->dev;
	struct nvkm_vma *vma;
	int ret;

	if (!cli->vm)
		return;

	ret = ttm_bo_reserve(&nvbo->bo, false, false, false, NULL);
	if (ret)
		return;

	vma = nouveau_bo_vma_find(nvbo, cli->vm);
	if (vma) {
		if (--vma->refcount == 0) {
			ret = pm_runtime_get_sync(dev);
			if (!WARN_ON(ret < 0 && ret != -EACCES)) {
				nouveau_gem_object_unmap(nvbo, vma);
				pm_runtime_mark_last_busy(dev);
				pm_runtime_put_autosuspend(dev);
			}
		}
	}
	ttm_bo_unreserve(&nvbo->bo);
}
Exemplo n.º 3
0
int
nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
		      struct drm_file *file_priv)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_fb *pfb = nouveau_fb(drm->device);
	struct drm_nouveau_gem_new *req = data;
	struct nouveau_bo *nvbo = NULL;
	int ret = 0;

	drm->ttm.bdev.dev_mapping = drm->dev->dev_mapping;

	if (!pfb->memtype_valid(pfb, req->info.tile_flags)) {
		NV_ERROR(cli, "bad page flags: 0x%08x\n", req->info.tile_flags);
		return -EINVAL;
	}

	ret = nouveau_gem_new(dev, req->info.size, req->align,
			      req->info.domain, req->info.tile_mode,
			      req->info.tile_flags, &nvbo);
	if (ret)
		return ret;

	ret = drm_gem_handle_create(file_priv, &nvbo->gem, &req->info.handle);
	if (ret == 0) {
		ret = nouveau_gem_info(file_priv, &nvbo->gem, &req->info);
		if (ret)
			drm_gem_handle_delete(file_priv, req->info.handle);
	}

	/* drop reference from allocate - handle holds it now */
	drm_gem_object_unreference_unlocked(&nvbo->gem);
	return ret;
}
Exemplo n.º 4
0
int
nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
	struct device *dev = drm->dev->dev;
	struct nouveau_vma *vma;
	int ret;

	if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50)
		return 0;

	ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
	if (ret)
		return ret;

	ret = pm_runtime_get_sync(dev);
	if (ret < 0 && ret != -EACCES)
		goto out;

	ret = nouveau_vma_new(nvbo, &cli->vmm, &vma);
	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);
out:
	ttm_bo_unreserve(&nvbo->bo);
	return ret;
}
Exemplo n.º 5
0
int
nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
		      struct drm_file *file_priv)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct drm_nouveau_gem_new *req = data;
	struct nouveau_bo *nvbo = NULL;
	int ret = 0;

	ret = nouveau_gem_new(cli, req->info.size, req->align,
			      req->info.domain, req->info.tile_mode,
			      req->info.tile_flags, &nvbo);
	if (ret)
		return ret;

	ret = drm_gem_handle_create(file_priv, &nvbo->gem, &req->info.handle);
	if (ret == 0) {
		ret = nouveau_gem_info(file_priv, &nvbo->gem, &req->info);
		if (ret)
			drm_gem_handle_delete(file_priv, req->info.handle);
	}

	/* drop reference from allocate - handle holds it now */
	drm_gem_object_unreference_unlocked(&nvbo->gem);
	return ret;
}
Exemplo n.º 6
0
int
nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
	struct nvkm_vma *vma;
	struct device *dev = drm->dev->dev;
	int ret;

	if (!cli->vm)
		return 0;

	ret = ttm_bo_reserve(&nvbo->bo, false, false, false, NULL);
	if (ret)
		return ret;

	vma = nouveau_bo_vma_find(nvbo, cli->vm);
	if (!vma) {
		vma = kzalloc(sizeof(*vma), GFP_KERNEL);
		if (!vma) {
			ret = -ENOMEM;
			goto out;
		}

		ret = pm_runtime_get_sync(dev);
		if (ret < 0 && ret != -EACCES)
			goto out;

		ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
		if (ret)
			kfree(vma);

		pm_runtime_mark_last_busy(dev);
		pm_runtime_put_autosuspend(dev);
	} else {
		vma->refcount++;
	}

out:
	ttm_bo_unreserve(&nvbo->bo);
	return ret;
}
Exemplo n.º 7
0
void
nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_vma *vma;
	int ret;

	if (!cli->base.vm)
		return;

	ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
	if (ret)
		return;

	vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
	if (vma) {
		if (--vma->refcount == 0)
			nouveau_gem_object_unmap(nvbo, vma);
	}
	ttm_bo_unreserve(&nvbo->bo);
}
Exemplo n.º 8
0
int
nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
{
    struct nouveau_cli *cli = nouveau_cli(file_priv);
    struct nouveau_bo *nvbo = nouveau_gem_object(gem);
    struct nouveau_vma *vma;
    int ret;

    if (!cli->base.vm)
        return 0;

    ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
    if (ret)
        return ret;

    vma = nouveau_bo_vma_find(nvbo, cli->base.vm);
    if (!vma) {
        vma = kzalloc(sizeof(*vma), GFP_KERNEL);
        if (!vma) {
            ret = -ENOMEM;
            goto out;
        }

        ret = nouveau_bo_vma_add(nvbo, cli->base.vm, vma);
        if (ret) {
            kfree(vma);
            goto out;
        }
    } else {
        vma->refcount++;
    }

out:
    ttm_bo_unreserve(&nvbo->bo);
    return ret;
}
Exemplo n.º 9
0
static int
nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
		 struct drm_nouveau_gem_info *rep)
{
	struct nouveau_cli *cli = nouveau_cli(file_priv);
	struct nouveau_bo *nvbo = nouveau_gem_object(gem);
	struct nouveau_vma *vma;

	if (is_power_of_2(nvbo->valid_domains))
		rep->domain = nvbo->valid_domains;
	else if (nvbo->bo.mem.mem_type == TTM_PL_TT)
		rep->domain = NOUVEAU_GEM_DOMAIN_GART;
	else
		rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
	rep->offset = nvbo->bo.offset;
	if (cli->vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) {
		vma = nouveau_vma_find(nvbo, &cli->vmm);
		if (!vma)
			return -EINVAL;

		rep->offset = vma->addr;
	}

	rep->size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
	rep->map_handle = drm_vma_node_offset_addr(&nvbo->bo.vma_node);
	rep->tile_mode = nvbo->mode;
	rep->tile_flags = nvbo->contig ? 0 : NOUVEAU_GEM_TILE_NONCONTIG;
	if (cli->device.info.family >= NV_DEVICE_INFO_V0_FERMI)
		rep->tile_flags |= nvbo->kind << 8;
	else
	if (cli->device.info.family >= NV_DEVICE_INFO_V0_TESLA)
		rep->tile_flags |= nvbo->kind << 8 | nvbo->comp << 16;
	else
		rep->tile_flags |= nvbo->zeta;
	return 0;
}