Back to index

libdrm  2.4.37
abi16.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2012 Red Hat Inc.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
00017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
00018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Authors: Ben Skeggs
00023  */
00024 
00025 #include <stdlib.h>
00026 #include <stdint.h>
00027 
00028 #include "private.h"
00029 
00030 int
00031 abi16_chan_nv04(struct nouveau_object *obj)
00032 {
00033        struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
00034        struct nv04_fifo *nv04 = obj->data;
00035        struct drm_nouveau_channel_alloc req = {nv04->vram, nv04->gart};
00036        int ret;
00037 
00038        ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
00039                               &req, sizeof(req));
00040        if (ret)
00041               return ret;
00042 
00043        nv04->base.channel = req.channel;
00044        nv04->base.pushbuf = req.pushbuf_domains;
00045        nv04->notify = req.notifier_handle;
00046        nv04->base.object->handle = req.channel;
00047        nv04->base.object->length = sizeof(*nv04);
00048        return 0;
00049 }
00050 
00051 int
00052 abi16_chan_nvc0(struct nouveau_object *obj)
00053 {
00054        struct nouveau_device *dev = (struct nouveau_device *)obj->parent;
00055        struct drm_nouveau_channel_alloc req = {};
00056        struct nvc0_fifo *nvc0 = obj->data;
00057        int ret;
00058 
00059        ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_CHANNEL_ALLOC,
00060                               &req, sizeof(req));
00061        if (ret)
00062               return ret;
00063 
00064        nvc0->base.channel = req.channel;
00065        nvc0->base.pushbuf = req.pushbuf_domains;
00066        nvc0->notify = req.notifier_handle;
00067        nvc0->base.object->handle = req.channel;
00068        nvc0->base.object->length = sizeof(*nvc0);
00069        return 0;
00070 }
00071 
00072 int
00073 abi16_engobj(struct nouveau_object *obj)
00074 {
00075        struct drm_nouveau_grobj_alloc req = {
00076               obj->parent->handle, obj->handle, obj->oclass
00077        };
00078        struct nouveau_device *dev;
00079        int ret;
00080 
00081        dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
00082        ret = drmCommandWrite(dev->fd, DRM_NOUVEAU_GROBJ_ALLOC,
00083                            &req, sizeof(req));
00084        if (ret)
00085               return ret;
00086 
00087        obj->length = sizeof(struct nouveau_object *);
00088        return 0;
00089 }
00090 
00091 int
00092 abi16_ntfy(struct nouveau_object *obj)
00093 {
00094        struct nv04_notify *ntfy = obj->data;
00095        struct drm_nouveau_notifierobj_alloc req = {
00096               obj->parent->handle, ntfy->object->handle, ntfy->length
00097        };
00098        struct nouveau_device *dev;
00099        int ret;
00100 
00101        dev = nouveau_object_find(obj, NOUVEAU_DEVICE_CLASS);
00102        ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC,
00103                               &req, sizeof(req));
00104        if (ret)
00105               return ret;
00106 
00107        ntfy->offset = req.offset;
00108        ntfy->object->length = sizeof(*ntfy);
00109        return 0;
00110 }
00111 
00112 void
00113 abi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info)
00114 {
00115        struct nouveau_bo_priv *nvbo = nouveau_bo(bo);
00116 
00117        nvbo->map_handle = info->map_handle;
00118        bo->handle = info->handle;
00119        bo->size = info->size;
00120        bo->offset = info->offset;
00121 
00122        bo->flags = 0;
00123        if (info->domain & NOUVEAU_GEM_DOMAIN_VRAM)
00124               bo->flags |= NOUVEAU_BO_VRAM;
00125        if (info->domain & NOUVEAU_GEM_DOMAIN_GART)
00126               bo->flags |= NOUVEAU_BO_GART;
00127        if (!(info->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG))
00128               bo->flags |= NOUVEAU_BO_CONTIG;
00129        if (nvbo->map_handle)
00130               bo->flags |= NOUVEAU_BO_MAP;
00131 
00132        if (bo->device->chipset >= 0xc0) {
00133               bo->config.nvc0.memtype   = (info->tile_flags & 0xff00) >> 8;
00134               bo->config.nvc0.tile_mode = info->tile_mode;
00135        } else
00136        if (bo->device->chipset >= 0x80 || bo->device->chipset == 0x50) {
00137               bo->config.nv50.memtype   = (info->tile_flags & 0x07f00) >> 8 |
00138                                        (info->tile_flags & 0x30000) >> 9;
00139               bo->config.nv50.tile_mode = info->tile_mode << 4;
00140        } else {
00141               bo->config.nv04.surf_flags = info->tile_flags & 7;
00142               bo->config.nv04.surf_pitch = info->tile_mode;
00143        }
00144 }
00145 
00146 int
00147 abi16_bo_init(struct nouveau_bo *bo, uint32_t alignment,
00148              union nouveau_bo_config *config)
00149 {
00150        struct nouveau_device *dev = bo->device;
00151        struct drm_nouveau_gem_new req = {};
00152        struct drm_nouveau_gem_info *info = &req.info;
00153        int ret;
00154 
00155        if (bo->flags & NOUVEAU_BO_VRAM)
00156               info->domain |= NOUVEAU_GEM_DOMAIN_VRAM;
00157        if (bo->flags & NOUVEAU_BO_GART)
00158               info->domain |= NOUVEAU_GEM_DOMAIN_GART;
00159        if (!info->domain)
00160               info->domain |= NOUVEAU_GEM_DOMAIN_VRAM |
00161                             NOUVEAU_GEM_DOMAIN_GART;
00162 
00163        if (bo->flags & NOUVEAU_BO_MAP)
00164               info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE;
00165 
00166        if (!(bo->flags & NOUVEAU_BO_CONTIG))
00167               info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG;
00168 
00169        info->size = bo->size;
00170        req.align = alignment;
00171 
00172        if (config) {
00173               if (dev->chipset >= 0xc0) {
00174                      info->tile_flags = (config->nvc0.memtype & 0xff) << 8;
00175                      info->tile_mode  = config->nvc0.tile_mode;
00176               } else
00177               if (dev->chipset >= 0x80 || dev->chipset == 0x50) {
00178                      info->tile_flags = (config->nv50.memtype & 0x07f) << 8 |
00179                                       (config->nv50.memtype & 0x180) << 9;
00180                      info->tile_mode  = config->nv50.tile_mode >> 4;
00181               } else {
00182                      info->tile_flags = config->nv04.surf_flags & 7;
00183                      info->tile_mode  = config->nv04.surf_pitch;
00184               }
00185        }
00186 
00187        if (!nouveau_device(dev)->have_bo_usage)
00188               info->tile_flags &= 0x0000ff00;
00189 
00190        ret = drmCommandWriteRead(dev->fd, DRM_NOUVEAU_GEM_NEW,
00191                               &req, sizeof(req));
00192        if (ret == 0)
00193               abi16_bo_info(bo, &req.info);
00194        return ret;
00195 }