1d722e3fbSopenharmony_ci/* 2d722e3fbSopenharmony_ci * Copyright 2012 Red Hat Inc. 3d722e3fbSopenharmony_ci * 4d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6d722e3fbSopenharmony_ci * to deal in the Software without restriction, including without limitation 7d722e3fbSopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8d722e3fbSopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9d722e3fbSopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10d722e3fbSopenharmony_ci * 11d722e3fbSopenharmony_ci * The above copyright notice and this permission notice shall be included in 12d722e3fbSopenharmony_ci * all copies or substantial portions of the Software. 13d722e3fbSopenharmony_ci * 14d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17d722e3fbSopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18d722e3fbSopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19d722e3fbSopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20d722e3fbSopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 21d722e3fbSopenharmony_ci * 22d722e3fbSopenharmony_ci * Authors: Ben Skeggs 23d722e3fbSopenharmony_ci */ 24d722e3fbSopenharmony_ci 25d722e3fbSopenharmony_ci#include <stdlib.h> 26d722e3fbSopenharmony_ci#include <stdint.h> 27d722e3fbSopenharmony_ci#include <stddef.h> 28d722e3fbSopenharmony_ci#include <errno.h> 29d722e3fbSopenharmony_ci 30d722e3fbSopenharmony_ci#include "private.h" 31d722e3fbSopenharmony_ci 32d722e3fbSopenharmony_ci#include "nvif/class.h" 33d722e3fbSopenharmony_ci 34d722e3fbSopenharmony_cistatic int 35d722e3fbSopenharmony_ciabi16_chan_nv04(struct nouveau_object *obj) 36d722e3fbSopenharmony_ci{ 37d722e3fbSopenharmony_ci struct nouveau_drm *drm = nouveau_drm(obj); 38d722e3fbSopenharmony_ci struct nv04_fifo *nv04 = obj->data; 39d722e3fbSopenharmony_ci struct drm_nouveau_channel_alloc req = { 40d722e3fbSopenharmony_ci .fb_ctxdma_handle = nv04->vram, 41d722e3fbSopenharmony_ci .tt_ctxdma_handle = nv04->gart 42d722e3fbSopenharmony_ci }; 43d722e3fbSopenharmony_ci int ret; 44d722e3fbSopenharmony_ci 45d722e3fbSopenharmony_ci ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC, 46d722e3fbSopenharmony_ci &req, sizeof(req)); 47d722e3fbSopenharmony_ci if (ret) 48d722e3fbSopenharmony_ci return ret; 49d722e3fbSopenharmony_ci 50d722e3fbSopenharmony_ci nv04->base.channel = req.channel; 51d722e3fbSopenharmony_ci nv04->base.pushbuf = req.pushbuf_domains; 52d722e3fbSopenharmony_ci nv04->notify = req.notifier_handle; 53d722e3fbSopenharmony_ci nv04->base.object->handle = req.channel; 54d722e3fbSopenharmony_ci nv04->base.object->length = sizeof(*nv04); 55d722e3fbSopenharmony_ci return 0; 56d722e3fbSopenharmony_ci} 57d722e3fbSopenharmony_ci 58d722e3fbSopenharmony_cistatic int 59d722e3fbSopenharmony_ciabi16_chan_nvc0(struct nouveau_object *obj) 60d722e3fbSopenharmony_ci{ 61d722e3fbSopenharmony_ci struct nouveau_drm *drm = nouveau_drm(obj); 62d722e3fbSopenharmony_ci struct drm_nouveau_channel_alloc req = {}; 63d722e3fbSopenharmony_ci struct nvc0_fifo *nvc0 = obj->data; 64d722e3fbSopenharmony_ci int ret; 65d722e3fbSopenharmony_ci 66d722e3fbSopenharmony_ci ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC, 67d722e3fbSopenharmony_ci &req, sizeof(req)); 68d722e3fbSopenharmony_ci if (ret) 69d722e3fbSopenharmony_ci return ret; 70d722e3fbSopenharmony_ci 71d722e3fbSopenharmony_ci nvc0->base.channel = req.channel; 72d722e3fbSopenharmony_ci nvc0->base.pushbuf = req.pushbuf_domains; 73d722e3fbSopenharmony_ci nvc0->notify = req.notifier_handle; 74d722e3fbSopenharmony_ci nvc0->base.object->handle = req.channel; 75d722e3fbSopenharmony_ci nvc0->base.object->length = sizeof(*nvc0); 76d722e3fbSopenharmony_ci return 0; 77d722e3fbSopenharmony_ci} 78d722e3fbSopenharmony_ci 79d722e3fbSopenharmony_cistatic int 80d722e3fbSopenharmony_ciabi16_chan_nve0(struct nouveau_object *obj) 81d722e3fbSopenharmony_ci{ 82d722e3fbSopenharmony_ci struct nouveau_drm *drm = nouveau_drm(obj); 83d722e3fbSopenharmony_ci struct drm_nouveau_channel_alloc req = {}; 84d722e3fbSopenharmony_ci struct nve0_fifo *nve0 = obj->data; 85d722e3fbSopenharmony_ci int ret; 86d722e3fbSopenharmony_ci 87d722e3fbSopenharmony_ci if (obj->length > offsetof(struct nve0_fifo, engine)) { 88d722e3fbSopenharmony_ci req.fb_ctxdma_handle = 0xffffffff; 89d722e3fbSopenharmony_ci req.tt_ctxdma_handle = nve0->engine; 90d722e3fbSopenharmony_ci } 91d722e3fbSopenharmony_ci 92d722e3fbSopenharmony_ci ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_CHANNEL_ALLOC, 93d722e3fbSopenharmony_ci &req, sizeof(req)); 94d722e3fbSopenharmony_ci if (ret) 95d722e3fbSopenharmony_ci return ret; 96d722e3fbSopenharmony_ci 97d722e3fbSopenharmony_ci nve0->base.channel = req.channel; 98d722e3fbSopenharmony_ci nve0->base.pushbuf = req.pushbuf_domains; 99d722e3fbSopenharmony_ci nve0->notify = req.notifier_handle; 100d722e3fbSopenharmony_ci nve0->base.object->handle = req.channel; 101d722e3fbSopenharmony_ci nve0->base.object->length = sizeof(*nve0); 102d722e3fbSopenharmony_ci return 0; 103d722e3fbSopenharmony_ci} 104d722e3fbSopenharmony_ci 105d722e3fbSopenharmony_cistatic int 106d722e3fbSopenharmony_ciabi16_engobj(struct nouveau_object *obj) 107d722e3fbSopenharmony_ci{ 108d722e3fbSopenharmony_ci struct nouveau_drm *drm = nouveau_drm(obj); 109d722e3fbSopenharmony_ci struct drm_nouveau_grobj_alloc req = { 110d722e3fbSopenharmony_ci .channel = obj->parent->handle, 111d722e3fbSopenharmony_ci .handle = obj->handle, 112d722e3fbSopenharmony_ci .class = obj->oclass, 113d722e3fbSopenharmony_ci }; 114d722e3fbSopenharmony_ci int ret; 115d722e3fbSopenharmony_ci 116d722e3fbSopenharmony_ci /* Older kernel versions did not have the concept of nouveau- 117d722e3fbSopenharmony_ci * specific classes and abused some NVIDIA-assigned ones for 118d722e3fbSopenharmony_ci * a SW class. The ABI16 layer has compatibility in place to 119d722e3fbSopenharmony_ci * translate these older identifiers to the newer ones. 120d722e3fbSopenharmony_ci * 121d722e3fbSopenharmony_ci * Clients that have been updated to use NVIF are required to 122d722e3fbSopenharmony_ci * use the newer class identifiers, which means that they'll 123d722e3fbSopenharmony_ci * break if running on an older kernel. 124d722e3fbSopenharmony_ci * 125d722e3fbSopenharmony_ci * To handle this case, when using ABI16, we translate to the 126d722e3fbSopenharmony_ci * older values which work on any kernel. 127d722e3fbSopenharmony_ci */ 128d722e3fbSopenharmony_ci switch (req.class) { 129d722e3fbSopenharmony_ci case NVIF_CLASS_SW_NV04 : req.class = 0x006e; break; 130d722e3fbSopenharmony_ci case NVIF_CLASS_SW_NV10 : req.class = 0x016e; break; 131d722e3fbSopenharmony_ci case NVIF_CLASS_SW_NV50 : req.class = 0x506e; break; 132d722e3fbSopenharmony_ci case NVIF_CLASS_SW_GF100: req.class = 0x906e; break; 133d722e3fbSopenharmony_ci default: 134d722e3fbSopenharmony_ci break; 135d722e3fbSopenharmony_ci } 136d722e3fbSopenharmony_ci 137d722e3fbSopenharmony_ci ret = drmCommandWrite(drm->fd, DRM_NOUVEAU_GROBJ_ALLOC, 138d722e3fbSopenharmony_ci &req, sizeof(req)); 139d722e3fbSopenharmony_ci if (ret) 140d722e3fbSopenharmony_ci return ret; 141d722e3fbSopenharmony_ci 142d722e3fbSopenharmony_ci obj->length = sizeof(struct nouveau_object *); 143d722e3fbSopenharmony_ci return 0; 144d722e3fbSopenharmony_ci} 145d722e3fbSopenharmony_ci 146d722e3fbSopenharmony_cistatic int 147d722e3fbSopenharmony_ciabi16_ntfy(struct nouveau_object *obj) 148d722e3fbSopenharmony_ci{ 149d722e3fbSopenharmony_ci struct nouveau_drm *drm = nouveau_drm(obj); 150d722e3fbSopenharmony_ci struct nv04_notify *ntfy = obj->data; 151d722e3fbSopenharmony_ci struct drm_nouveau_notifierobj_alloc req = { 152d722e3fbSopenharmony_ci .channel = obj->parent->handle, 153d722e3fbSopenharmony_ci .handle = ntfy->object->handle, 154d722e3fbSopenharmony_ci .size = ntfy->length, 155d722e3fbSopenharmony_ci }; 156d722e3fbSopenharmony_ci int ret; 157d722e3fbSopenharmony_ci 158d722e3fbSopenharmony_ci ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, 159d722e3fbSopenharmony_ci &req, sizeof(req)); 160d722e3fbSopenharmony_ci if (ret) 161d722e3fbSopenharmony_ci return ret; 162d722e3fbSopenharmony_ci 163d722e3fbSopenharmony_ci ntfy->offset = req.offset; 164d722e3fbSopenharmony_ci ntfy->object->length = sizeof(*ntfy); 165d722e3fbSopenharmony_ci return 0; 166d722e3fbSopenharmony_ci} 167d722e3fbSopenharmony_ci 168d722e3fbSopenharmony_cidrm_private int 169d722e3fbSopenharmony_ciabi16_sclass(struct nouveau_object *obj, struct nouveau_sclass **psclass) 170d722e3fbSopenharmony_ci{ 171d722e3fbSopenharmony_ci struct nouveau_sclass *sclass; 172d722e3fbSopenharmony_ci struct nouveau_device *dev; 173d722e3fbSopenharmony_ci 174d722e3fbSopenharmony_ci if (!(sclass = calloc(8, sizeof(*sclass)))) 175d722e3fbSopenharmony_ci return -ENOMEM; 176d722e3fbSopenharmony_ci *psclass = sclass; 177d722e3fbSopenharmony_ci 178d722e3fbSopenharmony_ci switch (obj->oclass) { 179d722e3fbSopenharmony_ci case NOUVEAU_FIFO_CHANNEL_CLASS: 180d722e3fbSopenharmony_ci /* Older kernel versions were exposing the wrong video engine 181d722e3fbSopenharmony_ci * classes on certain G98:GF100 boards. This has since been 182d722e3fbSopenharmony_ci * corrected, but ABI16 has compatibility in place to avoid 183d722e3fbSopenharmony_ci * breaking older userspace. 184d722e3fbSopenharmony_ci * 185d722e3fbSopenharmony_ci * Clients that have been updated to use NVIF are required to 186d722e3fbSopenharmony_ci * use the correct classes, which means that they'll break if 187d722e3fbSopenharmony_ci * running on an older kernel. 188d722e3fbSopenharmony_ci * 189d722e3fbSopenharmony_ci * To handle this issue, if using the older kernel interfaces, 190d722e3fbSopenharmony_ci * we'll magic up a list containing the vdec classes that the 191d722e3fbSopenharmony_ci * kernel will accept for these boards. Clients should make 192d722e3fbSopenharmony_ci * use of this information instead of hardcoding classes for 193d722e3fbSopenharmony_ci * specific chipsets. 194d722e3fbSopenharmony_ci */ 195d722e3fbSopenharmony_ci dev = (struct nouveau_device *)obj->parent; 196d722e3fbSopenharmony_ci if (dev->chipset >= 0x98 && 197d722e3fbSopenharmony_ci dev->chipset != 0xa0 && 198d722e3fbSopenharmony_ci dev->chipset < 0xc0) { 199d722e3fbSopenharmony_ci *sclass++ = (struct nouveau_sclass){ 200d722e3fbSopenharmony_ci GT212_MSVLD, -1, -1 201d722e3fbSopenharmony_ci }; 202d722e3fbSopenharmony_ci *sclass++ = (struct nouveau_sclass){ 203d722e3fbSopenharmony_ci GT212_MSPDEC, -1, -1 204d722e3fbSopenharmony_ci }; 205d722e3fbSopenharmony_ci *sclass++ = (struct nouveau_sclass){ 206d722e3fbSopenharmony_ci GT212_MSPPP, -1, -1 207d722e3fbSopenharmony_ci }; 208d722e3fbSopenharmony_ci } 209d722e3fbSopenharmony_ci break; 210d722e3fbSopenharmony_ci default: 211d722e3fbSopenharmony_ci break; 212d722e3fbSopenharmony_ci } 213d722e3fbSopenharmony_ci 214d722e3fbSopenharmony_ci return sclass - *psclass; 215d722e3fbSopenharmony_ci} 216d722e3fbSopenharmony_ci 217d722e3fbSopenharmony_cidrm_private void 218d722e3fbSopenharmony_ciabi16_delete(struct nouveau_object *obj) 219d722e3fbSopenharmony_ci{ 220d722e3fbSopenharmony_ci struct nouveau_drm *drm = nouveau_drm(obj); 221d722e3fbSopenharmony_ci if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { 222d722e3fbSopenharmony_ci struct drm_nouveau_channel_free req; 223d722e3fbSopenharmony_ci req.channel = obj->handle; 224d722e3fbSopenharmony_ci drmCommandWrite(drm->fd, DRM_NOUVEAU_CHANNEL_FREE, 225d722e3fbSopenharmony_ci &req, sizeof(req)); 226d722e3fbSopenharmony_ci } else { 227d722e3fbSopenharmony_ci struct drm_nouveau_gpuobj_free req; 228d722e3fbSopenharmony_ci req.channel = obj->parent->handle; 229d722e3fbSopenharmony_ci req.handle = obj->handle; 230d722e3fbSopenharmony_ci drmCommandWrite(drm->fd, DRM_NOUVEAU_GPUOBJ_FREE, 231d722e3fbSopenharmony_ci &req, sizeof(req)); 232d722e3fbSopenharmony_ci } 233d722e3fbSopenharmony_ci} 234d722e3fbSopenharmony_ci 235d722e3fbSopenharmony_cidrm_private bool 236d722e3fbSopenharmony_ciabi16_object(struct nouveau_object *obj, int (**func)(struct nouveau_object *)) 237d722e3fbSopenharmony_ci{ 238d722e3fbSopenharmony_ci struct nouveau_object *parent = obj->parent; 239d722e3fbSopenharmony_ci 240d722e3fbSopenharmony_ci /* nouveau_object::length is (ab)used to determine whether the 241d722e3fbSopenharmony_ci * object is a legacy object (!=0), or a real NVIF object. 242d722e3fbSopenharmony_ci */ 243d722e3fbSopenharmony_ci if ((parent->length != 0 && parent->oclass == NOUVEAU_DEVICE_CLASS) || 244d722e3fbSopenharmony_ci (parent->length == 0 && parent->oclass == NV_DEVICE)) { 245d722e3fbSopenharmony_ci if (obj->oclass == NOUVEAU_FIFO_CHANNEL_CLASS) { 246d722e3fbSopenharmony_ci struct nouveau_device *dev = (void *)parent; 247d722e3fbSopenharmony_ci if (dev->chipset < 0xc0) 248d722e3fbSopenharmony_ci *func = abi16_chan_nv04; 249d722e3fbSopenharmony_ci else 250d722e3fbSopenharmony_ci if (dev->chipset < 0xe0) 251d722e3fbSopenharmony_ci *func = abi16_chan_nvc0; 252d722e3fbSopenharmony_ci else 253d722e3fbSopenharmony_ci *func = abi16_chan_nve0; 254d722e3fbSopenharmony_ci return true; 255d722e3fbSopenharmony_ci } 256d722e3fbSopenharmony_ci } else 257d722e3fbSopenharmony_ci if ((parent->length != 0 && 258d722e3fbSopenharmony_ci parent->oclass == NOUVEAU_FIFO_CHANNEL_CLASS)) { 259d722e3fbSopenharmony_ci if (obj->oclass == NOUVEAU_NOTIFIER_CLASS) { 260d722e3fbSopenharmony_ci *func = abi16_ntfy; 261d722e3fbSopenharmony_ci return true; 262d722e3fbSopenharmony_ci } 263d722e3fbSopenharmony_ci 264d722e3fbSopenharmony_ci *func = abi16_engobj; 265d722e3fbSopenharmony_ci return false; /* try NVIF, if supported, before calling func */ 266d722e3fbSopenharmony_ci } 267d722e3fbSopenharmony_ci 268d722e3fbSopenharmony_ci *func = NULL; 269d722e3fbSopenharmony_ci return false; 270d722e3fbSopenharmony_ci} 271d722e3fbSopenharmony_ci 272d722e3fbSopenharmony_cidrm_private void 273d722e3fbSopenharmony_ciabi16_bo_info(struct nouveau_bo *bo, struct drm_nouveau_gem_info *info) 274d722e3fbSopenharmony_ci{ 275d722e3fbSopenharmony_ci struct nouveau_bo_priv *nvbo = nouveau_bo(bo); 276d722e3fbSopenharmony_ci 277d722e3fbSopenharmony_ci nvbo->map_handle = info->map_handle; 278d722e3fbSopenharmony_ci bo->handle = info->handle; 279d722e3fbSopenharmony_ci bo->size = info->size; 280d722e3fbSopenharmony_ci bo->offset = info->offset; 281d722e3fbSopenharmony_ci 282d722e3fbSopenharmony_ci bo->flags = 0; 283d722e3fbSopenharmony_ci if (info->domain & NOUVEAU_GEM_DOMAIN_VRAM) 284d722e3fbSopenharmony_ci bo->flags |= NOUVEAU_BO_VRAM; 285d722e3fbSopenharmony_ci if (info->domain & NOUVEAU_GEM_DOMAIN_GART) 286d722e3fbSopenharmony_ci bo->flags |= NOUVEAU_BO_GART; 287d722e3fbSopenharmony_ci if (!(info->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG)) 288d722e3fbSopenharmony_ci bo->flags |= NOUVEAU_BO_CONTIG; 289d722e3fbSopenharmony_ci if (nvbo->map_handle) 290d722e3fbSopenharmony_ci bo->flags |= NOUVEAU_BO_MAP; 291d722e3fbSopenharmony_ci 292d722e3fbSopenharmony_ci if (bo->device->chipset >= 0xc0) { 293d722e3fbSopenharmony_ci bo->config.nvc0.memtype = (info->tile_flags & 0xff00) >> 8; 294d722e3fbSopenharmony_ci bo->config.nvc0.tile_mode = info->tile_mode; 295d722e3fbSopenharmony_ci } else 296d722e3fbSopenharmony_ci if (bo->device->chipset >= 0x80 || bo->device->chipset == 0x50) { 297d722e3fbSopenharmony_ci bo->config.nv50.memtype = (info->tile_flags & 0x07f00) >> 8 | 298d722e3fbSopenharmony_ci (info->tile_flags & 0x30000) >> 9; 299d722e3fbSopenharmony_ci bo->config.nv50.tile_mode = info->tile_mode << 4; 300d722e3fbSopenharmony_ci } else { 301d722e3fbSopenharmony_ci bo->config.nv04.surf_flags = info->tile_flags & 7; 302d722e3fbSopenharmony_ci bo->config.nv04.surf_pitch = info->tile_mode; 303d722e3fbSopenharmony_ci } 304d722e3fbSopenharmony_ci} 305d722e3fbSopenharmony_ci 306d722e3fbSopenharmony_cidrm_private int 307d722e3fbSopenharmony_ciabi16_bo_init(struct nouveau_bo *bo, uint32_t alignment, 308d722e3fbSopenharmony_ci union nouveau_bo_config *config) 309d722e3fbSopenharmony_ci{ 310d722e3fbSopenharmony_ci struct nouveau_device *dev = bo->device; 311d722e3fbSopenharmony_ci struct nouveau_drm *drm = nouveau_drm(&dev->object); 312d722e3fbSopenharmony_ci struct drm_nouveau_gem_new req = {}; 313d722e3fbSopenharmony_ci struct drm_nouveau_gem_info *info = &req.info; 314d722e3fbSopenharmony_ci int ret; 315d722e3fbSopenharmony_ci 316d722e3fbSopenharmony_ci if (bo->flags & NOUVEAU_BO_VRAM) 317d722e3fbSopenharmony_ci info->domain |= NOUVEAU_GEM_DOMAIN_VRAM; 318d722e3fbSopenharmony_ci if (bo->flags & NOUVEAU_BO_GART) 319d722e3fbSopenharmony_ci info->domain |= NOUVEAU_GEM_DOMAIN_GART; 320d722e3fbSopenharmony_ci if (!info->domain) 321d722e3fbSopenharmony_ci info->domain |= NOUVEAU_GEM_DOMAIN_VRAM | 322d722e3fbSopenharmony_ci NOUVEAU_GEM_DOMAIN_GART; 323d722e3fbSopenharmony_ci 324d722e3fbSopenharmony_ci if (bo->flags & NOUVEAU_BO_MAP) 325d722e3fbSopenharmony_ci info->domain |= NOUVEAU_GEM_DOMAIN_MAPPABLE; 326d722e3fbSopenharmony_ci 327d722e3fbSopenharmony_ci if (bo->flags & NOUVEAU_BO_COHERENT) 328d722e3fbSopenharmony_ci info->domain |= NOUVEAU_GEM_DOMAIN_COHERENT; 329d722e3fbSopenharmony_ci 330d722e3fbSopenharmony_ci if (!(bo->flags & NOUVEAU_BO_CONTIG)) 331d722e3fbSopenharmony_ci info->tile_flags = NOUVEAU_GEM_TILE_NONCONTIG; 332d722e3fbSopenharmony_ci 333d722e3fbSopenharmony_ci info->size = bo->size; 334d722e3fbSopenharmony_ci req.align = alignment; 335d722e3fbSopenharmony_ci 336d722e3fbSopenharmony_ci if (config) { 337d722e3fbSopenharmony_ci if (dev->chipset >= 0xc0) { 338d722e3fbSopenharmony_ci info->tile_flags = (config->nvc0.memtype & 0xff) << 8; 339d722e3fbSopenharmony_ci info->tile_mode = config->nvc0.tile_mode; 340d722e3fbSopenharmony_ci } else 341d722e3fbSopenharmony_ci if (dev->chipset >= 0x80 || dev->chipset == 0x50) { 342d722e3fbSopenharmony_ci info->tile_flags = (config->nv50.memtype & 0x07f) << 8 | 343d722e3fbSopenharmony_ci (config->nv50.memtype & 0x180) << 9; 344d722e3fbSopenharmony_ci info->tile_mode = config->nv50.tile_mode >> 4; 345d722e3fbSopenharmony_ci } else { 346d722e3fbSopenharmony_ci info->tile_flags = config->nv04.surf_flags & 7; 347d722e3fbSopenharmony_ci info->tile_mode = config->nv04.surf_pitch; 348d722e3fbSopenharmony_ci } 349d722e3fbSopenharmony_ci } 350d722e3fbSopenharmony_ci 351d722e3fbSopenharmony_ci if (!nouveau_device(dev)->have_bo_usage) 352d722e3fbSopenharmony_ci info->tile_flags &= 0x0000ff00; 353d722e3fbSopenharmony_ci 354d722e3fbSopenharmony_ci ret = drmCommandWriteRead(drm->fd, DRM_NOUVEAU_GEM_NEW, 355d722e3fbSopenharmony_ci &req, sizeof(req)); 356d722e3fbSopenharmony_ci if (ret == 0) 357d722e3fbSopenharmony_ci abi16_bo_info(bo, &req.info); 358d722e3fbSopenharmony_ci return ret; 359d722e3fbSopenharmony_ci} 360