Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
   1/*
   2 * Copyright (C) 2006 Ben Skeggs.
   3 *
   4 * All Rights Reserved.
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining
   7 * a copy of this software and associated documentation files (the
   8 * "Software"), to deal in the Software without restriction, including
   9 * without limitation the rights to use, copy, modify, merge, publish,
  10 * distribute, sublicense, and/or sell copies of the Software, and to
  11 * permit persons to whom the Software is furnished to do so, subject to
  12 * the following conditions:
  13 *
  14 * The above copyright notice and this permission notice (including the
  15 * next paragraph) shall be included in all copies or substantial
  16 * portions of the Software.
  17 *
  18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  21 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
  22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25 *
  26 */
  27
  28/*
  29 * Authors:
  30 *   Ben Skeggs <darktama@iinet.net.au>
  31 */
  32
  33#include "drmP.h"
  34#include "drm.h"
  35#include "nouveau_drv.h"
  36#include "nouveau_drm.h"
  37#include "nouveau_ramht.h"
  38#include "nouveau_vm.h"
  39#include "nv50_display.h"
  40
  41struct nouveau_gpuobj_method {
  42	struct list_head head;
  43	u32 mthd;
  44	int (*exec)(struct nouveau_channel *, u32 class, u32 mthd, u32 data);
  45};
  46
  47struct nouveau_gpuobj_class {
  48	struct list_head head;
  49	struct list_head methods;
  50	u32 id;
  51	u32 engine;
  52};
  53
  54int
  55nouveau_gpuobj_class_new(struct drm_device *dev, u32 class, u32 engine)
  56{
  57	struct drm_nouveau_private *dev_priv = dev->dev_private;
  58	struct nouveau_gpuobj_class *oc;
  59
  60	oc = kzalloc(sizeof(*oc), GFP_KERNEL);
  61	if (!oc)
  62		return -ENOMEM;
  63
  64	INIT_LIST_HEAD(&oc->methods);
  65	oc->id = class;
  66	oc->engine = engine;
  67	list_add(&oc->head, &dev_priv->classes);
  68	return 0;
  69}
  70
  71int
  72nouveau_gpuobj_mthd_new(struct drm_device *dev, u32 class, u32 mthd,
  73			int (*exec)(struct nouveau_channel *, u32, u32, u32))
  74{
  75	struct drm_nouveau_private *dev_priv = dev->dev_private;
  76	struct nouveau_gpuobj_method *om;
  77	struct nouveau_gpuobj_class *oc;
  78
  79	list_for_each_entry(oc, &dev_priv->classes, head) {
  80		if (oc->id == class)
  81			goto found;
  82	}
  83
  84	return -EINVAL;
  85
  86found:
  87	om = kzalloc(sizeof(*om), GFP_KERNEL);
  88	if (!om)
  89		return -ENOMEM;
  90
  91	om->mthd = mthd;
  92	om->exec = exec;
  93	list_add(&om->head, &oc->methods);
  94	return 0;
  95}
  96
  97int
  98nouveau_gpuobj_mthd_call(struct nouveau_channel *chan,
  99			 u32 class, u32 mthd, u32 data)
 100{
 101	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
 102	struct nouveau_gpuobj_method *om;
 103	struct nouveau_gpuobj_class *oc;
 104
 105	list_for_each_entry(oc, &dev_priv->classes, head) {
 106		if (oc->id != class)
 107			continue;
 108
 109		list_for_each_entry(om, &oc->methods, head) {
 110			if (om->mthd == mthd)
 111				return om->exec(chan, class, mthd, data);
 112		}
 113	}
 114
 115	return -ENOENT;
 116}
 117
 118int
 119nouveau_gpuobj_mthd_call2(struct drm_device *dev, int chid,
 120			  u32 class, u32 mthd, u32 data)
 121{
 122	struct drm_nouveau_private *dev_priv = dev->dev_private;
 123	struct nouveau_channel *chan = NULL;
 124	unsigned long flags;
 125	int ret = -EINVAL;
 126
 127	spin_lock_irqsave(&dev_priv->channels.lock, flags);
 128	if (chid >= 0 && chid < dev_priv->engine.fifo.channels)
 129		chan = dev_priv->channels.ptr[chid];
 130	if (chan)
 131		ret = nouveau_gpuobj_mthd_call(chan, class, mthd, data);
 132	spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
 133	return ret;
 134}
 135
 136/* NVidia uses context objects to drive drawing operations.
 137
 138   Context objects can be selected into 8 subchannels in the FIFO,
 139   and then used via DMA command buffers.
 140
 141   A context object is referenced by a user defined handle (CARD32). The HW
 142   looks up graphics objects in a hash table in the instance RAM.
 143
 144   An entry in the hash table consists of 2 CARD32. The first CARD32 contains
 145   the handle, the second one a bitfield, that contains the address of the
 146   object in instance RAM.
 147
 148   The format of the second CARD32 seems to be:
 149
 150   NV4 to NV30:
 151
 152   15: 0  instance_addr >> 4
 153   17:16  engine (here uses 1 = graphics)
 154   28:24  channel id (here uses 0)
 155   31	  valid (use 1)
 156
 157   NV40:
 158
 159   15: 0  instance_addr >> 4   (maybe 19-0)
 160   21:20  engine (here uses 1 = graphics)
 161   I'm unsure about the other bits, but using 0 seems to work.
 162
 163   The key into the hash table depends on the object handle and channel id and
 164   is given as:
 165*/
 166
 167int
 168nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
 169		   uint32_t size, int align, uint32_t flags,
 170		   struct nouveau_gpuobj **gpuobj_ret)
 171{
 172	struct drm_nouveau_private *dev_priv = dev->dev_private;
 173	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
 174	struct nouveau_gpuobj *gpuobj;
 175	struct drm_mm_node *ramin = NULL;
 176	int ret, i;
 177
 178	NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
 179		 chan ? chan->id : -1, size, align, flags);
 180
 181	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
 182	if (!gpuobj)
 183		return -ENOMEM;
 184	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
 185	gpuobj->dev = dev;
 186	gpuobj->flags = flags;
 187	kref_init(&gpuobj->refcount);
 188	gpuobj->size = size;
 189
 190	spin_lock(&dev_priv->ramin_lock);
 191	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
 192	spin_unlock(&dev_priv->ramin_lock);
 193
 194	if (!(flags & NVOBJ_FLAG_VM) && chan) {
 195		ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0);
 196		if (ramin)
 197			ramin = drm_mm_get_block(ramin, size, align);
 198		if (!ramin) {
 199			nouveau_gpuobj_ref(NULL, &gpuobj);
 200			return -ENOMEM;
 201		}
 202
 203		gpuobj->pinst = chan->ramin->pinst;
 204		if (gpuobj->pinst != ~0)
 205			gpuobj->pinst += ramin->start;
 206
 207		gpuobj->cinst = ramin->start;
 208		gpuobj->vinst = ramin->start + chan->ramin->vinst;
 209		gpuobj->node  = ramin;
 210	} else {
 211		ret = instmem->get(gpuobj, chan, size, align);
 212		if (ret) {
 213			nouveau_gpuobj_ref(NULL, &gpuobj);
 214			return ret;
 215		}
 216
 217		ret = -ENOSYS;
 218		if (!(flags & NVOBJ_FLAG_DONT_MAP))
 219			ret = instmem->map(gpuobj);
 220		if (ret)
 221			gpuobj->pinst = ~0;
 222
 223		gpuobj->cinst = NVOBJ_CINST_GLOBAL;
 224	}
 225
 226	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
 227		for (i = 0; i < gpuobj->size; i += 4)
 228			nv_wo32(gpuobj, i, 0);
 229		instmem->flush(dev);
 230	}
 231
 232
 233	*gpuobj_ret = gpuobj;
 234	return 0;
 235}
 236
 237int
 238nouveau_gpuobj_init(struct drm_device *dev)
 239{
 240	struct drm_nouveau_private *dev_priv = dev->dev_private;
 241
 242	NV_DEBUG(dev, "\n");
 243
 244	INIT_LIST_HEAD(&dev_priv->gpuobj_list);
 245	INIT_LIST_HEAD(&dev_priv->classes);
 246	spin_lock_init(&dev_priv->ramin_lock);
 247	dev_priv->ramin_base = ~0;
 248
 249	return 0;
 250}
 251
 252void
 253nouveau_gpuobj_takedown(struct drm_device *dev)
 254{
 255	struct drm_nouveau_private *dev_priv = dev->dev_private;
 256	struct nouveau_gpuobj_method *om, *tm;
 257	struct nouveau_gpuobj_class *oc, *tc;
 258
 259	NV_DEBUG(dev, "\n");
 260
 261	list_for_each_entry_safe(oc, tc, &dev_priv->classes, head) {
 262		list_for_each_entry_safe(om, tm, &oc->methods, head) {
 263			list_del(&om->head);
 264			kfree(om);
 265		}
 266		list_del(&oc->head);
 267		kfree(oc);
 268	}
 269
 270	BUG_ON(!list_empty(&dev_priv->gpuobj_list));
 271}
 272
 273
 274static void
 275nouveau_gpuobj_del(struct kref *ref)
 276{
 277	struct nouveau_gpuobj *gpuobj =
 278		container_of(ref, struct nouveau_gpuobj, refcount);
 279	struct drm_device *dev = gpuobj->dev;
 280	struct drm_nouveau_private *dev_priv = dev->dev_private;
 281	struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
 282	int i;
 283
 284	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
 285
 286	if (gpuobj->node && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
 287		for (i = 0; i < gpuobj->size; i += 4)
 288			nv_wo32(gpuobj, i, 0);
 289		instmem->flush(dev);
 290	}
 291
 292	if (gpuobj->dtor)
 293		gpuobj->dtor(dev, gpuobj);
 294
 295	if (gpuobj->cinst == NVOBJ_CINST_GLOBAL) {
 296		if (gpuobj->node) {
 297			instmem->unmap(gpuobj);
 298			instmem->put(gpuobj);
 299		}
 300	} else {
 301		if (gpuobj->node) {
 302			spin_lock(&dev_priv->ramin_lock);
 303			drm_mm_put_block(gpuobj->node);
 304			spin_unlock(&dev_priv->ramin_lock);
 305		}
 306	}
 307
 308	spin_lock(&dev_priv->ramin_lock);
 309	list_del(&gpuobj->list);
 310	spin_unlock(&dev_priv->ramin_lock);
 311
 312	kfree(gpuobj);
 313}
 314
 315void
 316nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr)
 317{
 318	if (ref)
 319		kref_get(&ref->refcount);
 320
 321	if (*ptr)
 322		kref_put(&(*ptr)->refcount, nouveau_gpuobj_del);
 323
 324	*ptr = ref;
 325}
 326
 327int
 328nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst,
 329			u32 size, u32 flags, struct nouveau_gpuobj **pgpuobj)
 330{
 331	struct drm_nouveau_private *dev_priv = dev->dev_private;
 332	struct nouveau_gpuobj *gpuobj = NULL;
 333	int i;
 334
 335	NV_DEBUG(dev,
 336		 "pinst=0x%08x vinst=0x%010llx size=0x%08x flags=0x%08x\n",
 337		 pinst, vinst, size, flags);
 338
 339	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
 340	if (!gpuobj)
 341		return -ENOMEM;
 342	NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
 343	gpuobj->dev = dev;
 344	gpuobj->flags = flags;
 345	kref_init(&gpuobj->refcount);
 346	gpuobj->size  = size;
 347	gpuobj->pinst = pinst;
 348	gpuobj->cinst = NVOBJ_CINST_GLOBAL;
 349	gpuobj->vinst = vinst;
 350
 351	if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
 352		for (i = 0; i < gpuobj->size; i += 4)
 353			nv_wo32(gpuobj, i, 0);
 354		dev_priv->engine.instmem.flush(dev);
 355	}
 356
 357	spin_lock(&dev_priv->ramin_lock);
 358	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
 359	spin_unlock(&dev_priv->ramin_lock);
 360	*pgpuobj = gpuobj;
 361	return 0;
 362}
 363
 364/*
 365   DMA objects are used to reference a piece of memory in the
 366   framebuffer, PCI or AGP address space. Each object is 16 bytes big
 367   and looks as follows:
 368
 369   entry[0]
 370   11:0  class (seems like I can always use 0 here)
 371   12    page table present?
 372   13    page entry linear?
 373   15:14 access: 0 rw, 1 ro, 2 wo
 374   17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP
 375   31:20 dma adjust (bits 0-11 of the address)
 376   entry[1]
 377   dma limit (size of transfer)
 378   entry[X]
 379   1     0 readonly, 1 readwrite
 380   31:12 dma frame address of the page (bits 12-31 of the address)
 381   entry[N]
 382   page table terminator, same value as the first pte, as does nvidia
 383   rivatv uses 0xffffffff
 384
 385   Non linear page tables need a list of frame addresses afterwards,
 386   the rivatv project has some info on this.
 387
 388   The method below creates a DMA object in instance RAM and returns a handle
 389   to it that can be used to set up context objects.
 390*/
 391
 392void
 393nv50_gpuobj_dma_init(struct nouveau_gpuobj *obj, u32 offset, int class,
 394		     u64 base, u64 size, int target, int access,
 395		     u32 type, u32 comp)
 396{
 397	struct drm_nouveau_private *dev_priv = obj->dev->dev_private;
 398	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
 399	u32 flags0;
 400
 401	flags0  = (comp << 29) | (type << 22) | class;
 402	flags0 |= 0x00100000;
 403
 404	switch (access) {
 405	case NV_MEM_ACCESS_RO: flags0 |= 0x00040000; break;
 406	case NV_MEM_ACCESS_RW:
 407	case NV_MEM_ACCESS_WO: flags0 |= 0x00080000; break;
 408	default:
 409		break;
 410	}
 411
 412	switch (target) {
 413	case NV_MEM_TARGET_VRAM:
 414		flags0 |= 0x00010000;
 415		break;
 416	case NV_MEM_TARGET_PCI:
 417		flags0 |= 0x00020000;
 418		break;
 419	case NV_MEM_TARGET_PCI_NOSNOOP:
 420		flags0 |= 0x00030000;
 421		break;
 422	case NV_MEM_TARGET_GART:
 423		base += dev_priv->gart_info.aper_base;
 424	default:
 425		flags0 &= ~0x00100000;
 426		break;
 427	}
 428
 429	/* convert to base + limit */
 430	size = (base + size) - 1;
 431
 432	nv_wo32(obj, offset + 0x00, flags0);
 433	nv_wo32(obj, offset + 0x04, lower_32_bits(size));
 434	nv_wo32(obj, offset + 0x08, lower_32_bits(base));
 435	nv_wo32(obj, offset + 0x0c, upper_32_bits(size) << 24 |
 436				    upper_32_bits(base));
 437	nv_wo32(obj, offset + 0x10, 0x00000000);
 438	nv_wo32(obj, offset + 0x14, 0x00000000);
 439
 440	pinstmem->flush(obj->dev);
 441}
 442
 443int
 444nv50_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, u64 size,
 445		    int target, int access, u32 type, u32 comp,
 446		    struct nouveau_gpuobj **pobj)
 447{
 448	struct drm_device *dev = chan->dev;
 449	int ret;
 450
 451	ret = nouveau_gpuobj_new(dev, chan, 24, 16, NVOBJ_FLAG_ZERO_FREE, pobj);
 452	if (ret)
 453		return ret;
 454
 455	nv50_gpuobj_dma_init(*pobj, 0, class, base, size, target,
 456			     access, type, comp);
 457	return 0;
 458}
 459
 460int
 461nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base,
 462		       u64 size, int access, int target,
 463		       struct nouveau_gpuobj **pobj)
 464{
 465	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
 466	struct drm_device *dev = chan->dev;
 467	struct nouveau_gpuobj *obj;
 468	u32 flags0, flags2;
 469	int ret;
 470
 471	if (dev_priv->card_type >= NV_50) {
 472		u32 comp = (target == NV_MEM_TARGET_VM) ? NV_MEM_COMP_VM : 0;
 473		u32 type = (target == NV_MEM_TARGET_VM) ? NV_MEM_TYPE_VM : 0;
 474
 475		return nv50_gpuobj_dma_new(chan, class, base, size,
 476					   target, access, type, comp, pobj);
 477	}
 478
 479	if (target == NV_MEM_TARGET_GART) {
 480		struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma;
 481
 482		if (dev_priv->gart_info.type == NOUVEAU_GART_PDMA) {
 483			if (base == 0) {
 484				nouveau_gpuobj_ref(gart, pobj);
 485				return 0;
 486			}
 487
 488			base   = nouveau_sgdma_get_physical(dev, base);
 489			target = NV_MEM_TARGET_PCI;
 490		} else {
 491			base += dev_priv->gart_info.aper_base;
 492			if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
 493				target = NV_MEM_TARGET_PCI_NOSNOOP;
 494			else
 495				target = NV_MEM_TARGET_PCI;
 496		}
 497	}
 498
 499	flags0  = class;
 500	flags0 |= 0x00003000; /* PT present, PT linear */
 501	flags2  = 0;
 502
 503	switch (target) {
 504	case NV_MEM_TARGET_PCI:
 505		flags0 |= 0x00020000;
 506		break;
 507	case NV_MEM_TARGET_PCI_NOSNOOP:
 508		flags0 |= 0x00030000;
 509		break;
 510	default:
 511		break;
 512	}
 513
 514	switch (access) {
 515	case NV_MEM_ACCESS_RO:
 516		flags0 |= 0x00004000;
 517		break;
 518	case NV_MEM_ACCESS_WO:
 519		flags0 |= 0x00008000;
 520	default:
 521		flags2 |= 0x00000002;
 522		break;
 523	}
 524
 525	flags0 |= (base & 0x00000fff) << 20;
 526	flags2 |= (base & 0xfffff000);
 527
 528	ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
 529	if (ret)
 530		return ret;
 531
 532	nv_wo32(obj, 0x00, flags0);
 533	nv_wo32(obj, 0x04, size - 1);
 534	nv_wo32(obj, 0x08, flags2);
 535	nv_wo32(obj, 0x0c, flags2);
 536
 537	obj->engine = NVOBJ_ENGINE_SW;
 538	obj->class  = class;
 539	*pobj = obj;
 540	return 0;
 541}
 542
 543/* Context objects in the instance RAM have the following structure.
 544 * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes.
 545
 546   NV4 - NV30:
 547
 548   entry[0]
 549   11:0 class
 550   12   chroma key enable
 551   13   user clip enable
 552   14   swizzle enable
 553   17:15 patch config:
 554       scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre
 555   18   synchronize enable
 556   19   endian: 1 big, 0 little
 557   21:20 dither mode
 558   23    single step enable
 559   24    patch status: 0 invalid, 1 valid
 560   25    context_surface 0: 1 valid
 561   26    context surface 1: 1 valid
 562   27    context pattern: 1 valid
 563   28    context rop: 1 valid
 564   29,30 context beta, beta4
 565   entry[1]
 566   7:0   mono format
 567   15:8  color format
 568   31:16 notify instance address
 569   entry[2]
 570   15:0  dma 0 instance address
 571   31:16 dma 1 instance address
 572   entry[3]
 573   dma method traps
 574
 575   NV40:
 576   No idea what the exact format is. Here's what can be deducted:
 577
 578   entry[0]:
 579   11:0  class  (maybe uses more bits here?)
 580   17    user clip enable
 581   21:19 patch config
 582   25    patch status valid ?
 583   entry[1]:
 584   15:0  DMA notifier  (maybe 20:0)
 585   entry[2]:
 586   15:0  DMA 0 instance (maybe 20:0)
 587   24    big endian
 588   entry[3]:
 589   15:0  DMA 1 instance (maybe 20:0)
 590   entry[4]:
 591   entry[5]:
 592   set to 0?
 593*/
 594static int
 595nouveau_gpuobj_sw_new(struct nouveau_channel *chan, u32 handle, u16 class)
 596{
 597	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
 598	struct nouveau_gpuobj *gpuobj;
 599	int ret;
 600
 601	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
 602	if (!gpuobj)
 603		return -ENOMEM;
 604	gpuobj->dev = chan->dev;
 605	gpuobj->engine = NVOBJ_ENGINE_SW;
 606	gpuobj->class = class;
 607	kref_init(&gpuobj->refcount);
 608	gpuobj->cinst = 0x40;
 609
 610	spin_lock(&dev_priv->ramin_lock);
 611	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
 612	spin_unlock(&dev_priv->ramin_lock);
 613
 614	ret = nouveau_ramht_insert(chan, handle, gpuobj);
 615	nouveau_gpuobj_ref(NULL, &gpuobj);
 616	return ret;
 617}
 618
 619int
 620nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class)
 621{
 622	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
 623	struct drm_device *dev = chan->dev;
 624	struct nouveau_gpuobj_class *oc;
 625	int ret;
 626
 627	NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);
 628
 629	list_for_each_entry(oc, &dev_priv->classes, head) {
 630		struct nouveau_exec_engine *eng = dev_priv->eng[oc->engine];
 631
 632		if (oc->id != class)
 633			continue;
 634
 635		if (oc->engine == NVOBJ_ENGINE_SW)
 636			return nouveau_gpuobj_sw_new(chan, handle, class);
 637
 638		if (!chan->engctx[oc->engine]) {
 639			ret = eng->context_new(chan, oc->engine);
 640			if (ret)
 641				return ret;
 642		}
 643
 644		return eng->object_new(chan, oc->engine, handle, class);
 645	}
 646
 647	NV_ERROR(dev, "illegal object class: 0x%x\n", class);
 648	return -EINVAL;
 649}
 650
 651static int
 652nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
 653{
 654	struct drm_device *dev = chan->dev;
 655	struct drm_nouveau_private *dev_priv = dev->dev_private;
 656	uint32_t size;
 657	uint32_t base;
 658	int ret;
 659
 660	NV_DEBUG(dev, "ch%d\n", chan->id);
 661
 662	/* Base amount for object storage (4KiB enough?) */
 663	size = 0x2000;
 664	base = 0;
 665
 666	if (dev_priv->card_type == NV_50) {
 667		/* Various fixed table thingos */
 668		size += 0x1400; /* mostly unknown stuff */
 669		size += 0x4000; /* vm pd */
 670		base  = 0x6000;
 671		/* RAMHT, not sure about setting size yet, 32KiB to be safe */
 672		size += 0x8000;
 673		/* RAMFC */
 674		size += 0x1000;
 675	}
 676
 677	ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin);
 678	if (ret) {
 679		NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret);
 680		return ret;
 681	}
 682
 683	ret = drm_mm_init(&chan->ramin_heap, base, size);
 684	if (ret) {
 685		NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
 686		nouveau_gpuobj_ref(NULL, &chan->ramin);
 687		return ret;
 688	}
 689
 690	return 0;
 691}
 692
 693static int
 694nvc0_gpuobj_channel_init(struct nouveau_channel *chan, struct nouveau_vm *vm)
 695{
 696	struct drm_device *dev = chan->dev;
 697	struct nouveau_gpuobj *pgd = NULL;
 698	struct nouveau_vm_pgd *vpgd;
 699	int ret, i;
 700
 701	ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, &chan->ramin);
 702	if (ret)
 703		return ret;
 704
 705	/* create page directory for this vm if none currently exists,
 706	 * will be destroyed automagically when last reference to the
 707	 * vm is removed
 708	 */
 709	if (list_empty(&vm->pgd_list)) {
 710		ret = nouveau_gpuobj_new(dev, NULL, 65536, 0x1000, 0, &pgd);
 711		if (ret)
 712			return ret;
 713	}
 714	nouveau_vm_ref(vm, &chan->vm, pgd);
 715	nouveau_gpuobj_ref(NULL, &pgd);
 716
 717	/* point channel at vm's page directory */
 718	vpgd = list_first_entry(&vm->pgd_list, struct nouveau_vm_pgd, head);
 719	nv_wo32(chan->ramin, 0x0200, lower_32_bits(vpgd->obj->vinst));
 720	nv_wo32(chan->ramin, 0x0204, upper_32_bits(vpgd->obj->vinst));
 721	nv_wo32(chan->ramin, 0x0208, 0xffffffff);
 722	nv_wo32(chan->ramin, 0x020c, 0x000000ff);
 723
 724	/* map display semaphore buffers into channel's vm */
 725	for (i = 0; i < 2; i++) {
 726		struct nv50_display_crtc *dispc = &nv50_display(dev)->crtc[i];
 727
 728		ret = nouveau_bo_vma_add(dispc->sem.bo, chan->vm,
 729					 &chan->dispc_vma[i]);
 730		if (ret)
 731			return ret;
 732	}
 733
 734	return 0;
 735}
 736
 737int
 738nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
 739			    uint32_t vram_h, uint32_t tt_h)
 740{
 741	struct drm_device *dev = chan->dev;
 742	struct drm_nouveau_private *dev_priv = dev->dev_private;
 743	struct nouveau_fpriv *fpriv = nouveau_fpriv(chan->file_priv);
 744	struct nouveau_vm *vm = fpriv ? fpriv->vm : dev_priv->chan_vm;
 745	struct nouveau_gpuobj *vram = NULL, *tt = NULL;
 746	int ret, i;
 747
 748	NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
 749	if (dev_priv->card_type == NV_C0)
 750		return nvc0_gpuobj_channel_init(chan, vm);
 751
 752	/* Allocate a chunk of memory for per-channel object storage */
 753	ret = nouveau_gpuobj_channel_init_pramin(chan);
 754	if (ret) {
 755		NV_ERROR(dev, "init pramin\n");
 756		return ret;
 757	}
 758
 759	/* NV50 VM
 760	 *  - Allocate per-channel page-directory
 761	 *  - Link with shared channel VM
 762	 */
 763	if (vm) {
 764		u32 pgd_offs = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200;
 765		u64 vm_vinst = chan->ramin->vinst + pgd_offs;
 766		u32 vm_pinst = chan->ramin->pinst;
 767
 768		if (vm_pinst != ~0)
 769			vm_pinst += pgd_offs;
 770
 771		ret = nouveau_gpuobj_new_fake(dev, vm_pinst, vm_vinst, 0x4000,
 772					      0, &chan->vm_pd);
 773		if (ret)
 774			return ret;
 775
 776		nouveau_vm_ref(vm, &chan->vm, chan->vm_pd);
 777	}
 778
 779	/* RAMHT */
 780	if (dev_priv->card_type < NV_50) {
 781		nouveau_ramht_ref(dev_priv->ramht, &chan->ramht, NULL);
 782	} else {
 783		struct nouveau_gpuobj *ramht = NULL;
 784
 785		ret = nouveau_gpuobj_new(dev, chan, 0x8000, 16,
 786					 NVOBJ_FLAG_ZERO_ALLOC, &ramht);
 787		if (ret)
 788			return ret;
 789
 790		ret = nouveau_ramht_new(dev, ramht, &chan->ramht);
 791		nouveau_gpuobj_ref(NULL, &ramht);
 792		if (ret)
 793			return ret;
 794
 795		/* dma objects for display sync channel semaphore blocks */
 796		for (i = 0; i < 2; i++) {
 797			struct nouveau_gpuobj *sem = NULL;
 798			struct nv50_display_crtc *dispc =
 799				&nv50_display(dev)->crtc[i];
 800			u64 offset = dispc->sem.bo->bo.offset;
 801
 802			ret = nouveau_gpuobj_dma_new(chan, 0x3d, offset, 0xfff,
 803						     NV_MEM_ACCESS_RW,
 804						     NV_MEM_TARGET_VRAM, &sem);
 805			if (ret)
 806				return ret;
 807
 808			ret = nouveau_ramht_insert(chan, NvEvoSema0 + i, sem);
 809			nouveau_gpuobj_ref(NULL, &sem);
 810			if (ret)
 811				return ret;
 812		}
 813	}
 814
 815	/* VRAM ctxdma */
 816	if (dev_priv->card_type >= NV_50) {
 817		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
 818					     0, (1ULL << 40), NV_MEM_ACCESS_RW,
 819					     NV_MEM_TARGET_VM, &vram);
 820		if (ret) {
 821			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
 822			return ret;
 823		}
 824	} else {
 825		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
 826					     0, dev_priv->fb_available_size,
 827					     NV_MEM_ACCESS_RW,
 828					     NV_MEM_TARGET_VRAM, &vram);
 829		if (ret) {
 830			NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
 831			return ret;
 832		}
 833	}
 834
 835	ret = nouveau_ramht_insert(chan, vram_h, vram);
 836	nouveau_gpuobj_ref(NULL, &vram);
 837	if (ret) {
 838		NV_ERROR(dev, "Error adding VRAM ctxdma to RAMHT: %d\n", ret);
 839		return ret;
 840	}
 841
 842	/* TT memory ctxdma */
 843	if (dev_priv->card_type >= NV_50) {
 844		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
 845					     0, (1ULL << 40), NV_MEM_ACCESS_RW,
 846					     NV_MEM_TARGET_VM, &tt);
 847	} else {
 848		ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
 849					     0, dev_priv->gart_info.aper_size,
 850					     NV_MEM_ACCESS_RW,
 851					     NV_MEM_TARGET_GART, &tt);
 852	}
 853
 854	if (ret) {
 855		NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret);
 856		return ret;
 857	}
 858
 859	ret = nouveau_ramht_insert(chan, tt_h, tt);
 860	nouveau_gpuobj_ref(NULL, &tt);
 861	if (ret) {
 862		NV_ERROR(dev, "Error adding TT ctxdma to RAMHT: %d\n", ret);
 863		return ret;
 864	}
 865
 866	return 0;
 867}
 868
 869void
 870nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
 871{
 872	struct drm_device *dev = chan->dev;
 873	struct drm_nouveau_private *dev_priv = dev->dev_private;
 874	int i;
 875
 876	NV_DEBUG(dev, "ch%d\n", chan->id);
 877
 878	if (dev_priv->card_type >= NV_50) {
 879		struct nv50_display *disp = nv50_display(dev);
 880
 881		for (i = 0; i < 2; i++) {
 882			struct nv50_display_crtc *dispc = &disp->crtc[i];
 883			nouveau_bo_vma_del(dispc->sem.bo, &chan->dispc_vma[i]);
 884		}
 885
 886		nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd);
 887		nouveau_gpuobj_ref(NULL, &chan->vm_pd);
 888	}
 889
 890	if (drm_mm_initialized(&chan->ramin_heap))
 891		drm_mm_takedown(&chan->ramin_heap);
 892	nouveau_gpuobj_ref(NULL, &chan->ramin);
 893}
 894
 895int
 896nouveau_gpuobj_suspend(struct drm_device *dev)
 897{
 898	struct drm_nouveau_private *dev_priv = dev->dev_private;
 899	struct nouveau_gpuobj *gpuobj;
 900	int i;
 901
 902	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
 903		if (gpuobj->cinst != NVOBJ_CINST_GLOBAL)
 904			continue;
 905
 906		gpuobj->suspend = vmalloc(gpuobj->size);
 907		if (!gpuobj->suspend) {
 908			nouveau_gpuobj_resume(dev);
 909			return -ENOMEM;
 910		}
 911
 912		for (i = 0; i < gpuobj->size; i += 4)
 913			gpuobj->suspend[i/4] = nv_ro32(gpuobj, i);
 914	}
 915
 916	return 0;
 917}
 918
 919void
 920nouveau_gpuobj_resume(struct drm_device *dev)
 921{
 922	struct drm_nouveau_private *dev_priv = dev->dev_private;
 923	struct nouveau_gpuobj *gpuobj;
 924	int i;
 925
 926	list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
 927		if (!gpuobj->suspend)
 928			continue;
 929
 930		for (i = 0; i < gpuobj->size; i += 4)
 931			nv_wo32(gpuobj, i, gpuobj->suspend[i/4]);
 932
 933		vfree(gpuobj->suspend);
 934		gpuobj->suspend = NULL;
 935	}
 936
 937	dev_priv->engine.instmem.flush(dev);
 938}
 939
 940int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
 941			      struct drm_file *file_priv)
 942{
 943	struct drm_nouveau_grobj_alloc *init = data;
 944	struct nouveau_channel *chan;
 945	int ret;
 946
 947	if (init->handle == ~0)
 948		return -EINVAL;
 949
 950	chan = nouveau_channel_get(file_priv, init->channel);
 951	if (IS_ERR(chan))
 952		return PTR_ERR(chan);
 953
 954	if (nouveau_ramht_find(chan, init->handle)) {
 955		ret = -EEXIST;
 956		goto out;
 957	}
 958
 959	ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class);
 960	if (ret) {
 961		NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
 962			 ret, init->channel, init->handle);
 963	}
 964
 965out:
 966	nouveau_channel_put(&chan);
 967	return ret;
 968}
 969
 970int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
 971			      struct drm_file *file_priv)
 972{
 973	struct drm_nouveau_gpuobj_free *objfree = data;
 974	struct nouveau_channel *chan;
 975	int ret;
 976
 977	chan = nouveau_channel_get(file_priv, objfree->channel);
 978	if (IS_ERR(chan))
 979		return PTR_ERR(chan);
 980
 981	/* Synchronize with the user channel */
 982	nouveau_channel_idle(chan);
 983
 984	ret = nouveau_ramht_remove(chan, objfree->handle);
 985	nouveau_channel_put(&chan);
 986	return ret;
 987}
 988
 989u32
 990nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset)
 991{
 992	struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
 993	struct drm_device *dev = gpuobj->dev;
 994	unsigned long flags;
 995
 996	if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
 997		u64  ptr = gpuobj->vinst + offset;
 998		u32 base = ptr >> 16;
 999		u32  val;
1000
1001		spin_lock_irqsave(&dev_priv->vm_lock, flags);
1002		if (dev_priv->ramin_base != base) {
1003			dev_priv->ramin_base = base;
1004			nv_wr32(dev, 0x001700, dev_priv->ramin_base);
1005		}
1006		val = nv_rd32(dev, 0x700000 + (ptr & 0xffff));
1007		spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
1008		return val;
1009	}
1010
1011	return nv_ri32(dev, gpuobj->pinst + offset);
1012}
1013
1014void
1015nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val)
1016{
1017	struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
1018	struct drm_device *dev = gpuobj->dev;
1019	unsigned long flags;
1020
1021	if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
1022		u64  ptr = gpuobj->vinst + offset;
1023		u32 base = ptr >> 16;
1024
1025		spin_lock_irqsave(&dev_priv->vm_lock, flags);
1026		if (dev_priv->ramin_base != base) {
1027			dev_priv->ramin_base = base;
1028			nv_wr32(dev, 0x001700, dev_priv->ramin_base);
1029		}
1030		nv_wr32(dev, 0x700000 + (ptr & 0xffff), val);
1031		spin_unlock_irqrestore(&dev_priv->vm_lock, flags);
1032		return;
1033	}
1034
1035	nv_wi32(dev, gpuobj->pinst + offset, val);
1036}