nouveau_object.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  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. * Authors:
  29. * Ben Skeggs <darktama@iinet.net.au>
  30. */
  31. #include "drmP.h"
  32. #include "drm.h"
  33. #include "nouveau_drv.h"
  34. #include "nouveau_drm.h"
  35. #include "nouveau_ramht.h"
  36. struct nouveau_gpuobj_method {
  37. struct list_head head;
  38. u32 mthd;
  39. int (*exec)(struct nouveau_channel *, u32 class, u32 mthd, u32 data);
  40. };
  41. struct nouveau_gpuobj_class {
  42. struct list_head head;
  43. struct list_head methods;
  44. u32 id;
  45. u32 engine;
  46. };
  47. int
  48. nouveau_gpuobj_class_new(struct drm_device *dev, u32 class, u32 engine)
  49. {
  50. struct drm_nouveau_private *dev_priv = dev->dev_private;
  51. struct nouveau_gpuobj_class *oc;
  52. oc = kzalloc(sizeof(*oc), GFP_KERNEL);
  53. if (!oc)
  54. return -ENOMEM;
  55. INIT_LIST_HEAD(&oc->methods);
  56. oc->id = class;
  57. oc->engine = engine;
  58. list_add(&oc->head, &dev_priv->classes);
  59. return 0;
  60. }
  61. int
  62. nouveau_gpuobj_mthd_new(struct drm_device *dev, u32 class, u32 mthd,
  63. int (*exec)(struct nouveau_channel *, u32, u32, u32))
  64. {
  65. struct drm_nouveau_private *dev_priv = dev->dev_private;
  66. struct nouveau_gpuobj_method *om;
  67. struct nouveau_gpuobj_class *oc;
  68. list_for_each_entry(oc, &dev_priv->classes, head) {
  69. if (oc->id == class)
  70. goto found;
  71. }
  72. return -EINVAL;
  73. found:
  74. om = kzalloc(sizeof(*om), GFP_KERNEL);
  75. if (!om)
  76. return -ENOMEM;
  77. om->mthd = mthd;
  78. om->exec = exec;
  79. list_add(&om->head, &oc->methods);
  80. return 0;
  81. }
  82. int
  83. nouveau_gpuobj_mthd_call(struct nouveau_channel *chan,
  84. u32 class, u32 mthd, u32 data)
  85. {
  86. struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
  87. struct nouveau_gpuobj_method *om;
  88. struct nouveau_gpuobj_class *oc;
  89. list_for_each_entry(oc, &dev_priv->classes, head) {
  90. if (oc->id != class)
  91. continue;
  92. list_for_each_entry(om, &oc->methods, head) {
  93. if (om->mthd == mthd)
  94. return om->exec(chan, class, mthd, data);
  95. }
  96. }
  97. return -ENOENT;
  98. }
  99. int
  100. nouveau_gpuobj_mthd_call2(struct drm_device *dev, int chid,
  101. u32 class, u32 mthd, u32 data)
  102. {
  103. struct drm_nouveau_private *dev_priv = dev->dev_private;
  104. struct nouveau_channel *chan = NULL;
  105. unsigned long flags;
  106. int ret = -EINVAL;
  107. spin_lock_irqsave(&dev_priv->channels.lock, flags);
  108. if (chid > 0 && chid < dev_priv->engine.fifo.channels)
  109. chan = dev_priv->channels.ptr[chid];
  110. if (chan)
  111. ret = nouveau_gpuobj_mthd_call(chan, class, mthd, data);
  112. spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
  113. return ret;
  114. }
  115. /* NVidia uses context objects to drive drawing operations.
  116. Context objects can be selected into 8 subchannels in the FIFO,
  117. and then used via DMA command buffers.
  118. A context object is referenced by a user defined handle (CARD32). The HW
  119. looks up graphics objects in a hash table in the instance RAM.
  120. An entry in the hash table consists of 2 CARD32. The first CARD32 contains
  121. the handle, the second one a bitfield, that contains the address of the
  122. object in instance RAM.
  123. The format of the second CARD32 seems to be:
  124. NV4 to NV30:
  125. 15: 0 instance_addr >> 4
  126. 17:16 engine (here uses 1 = graphics)
  127. 28:24 channel id (here uses 0)
  128. 31 valid (use 1)
  129. NV40:
  130. 15: 0 instance_addr >> 4 (maybe 19-0)
  131. 21:20 engine (here uses 1 = graphics)
  132. I'm unsure about the other bits, but using 0 seems to work.
  133. The key into the hash table depends on the object handle and channel id and
  134. is given as:
  135. */
  136. int
  137. nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan,
  138. uint32_t size, int align, uint32_t flags,
  139. struct nouveau_gpuobj **gpuobj_ret)
  140. {
  141. struct drm_nouveau_private *dev_priv = dev->dev_private;
  142. struct nouveau_engine *engine = &dev_priv->engine;
  143. struct nouveau_gpuobj *gpuobj;
  144. struct drm_mm_node *ramin = NULL;
  145. int ret;
  146. NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n",
  147. chan ? chan->id : -1, size, align, flags);
  148. if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL)
  149. return -EINVAL;
  150. gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
  151. if (!gpuobj)
  152. return -ENOMEM;
  153. NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
  154. gpuobj->dev = dev;
  155. gpuobj->flags = flags;
  156. kref_init(&gpuobj->refcount);
  157. gpuobj->size = size;
  158. spin_lock(&dev_priv->ramin_lock);
  159. list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
  160. spin_unlock(&dev_priv->ramin_lock);
  161. if (chan) {
  162. NV_DEBUG(dev, "channel heap\n");
  163. ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0);
  164. if (ramin)
  165. ramin = drm_mm_get_block(ramin, size, align);
  166. if (!ramin) {
  167. nouveau_gpuobj_ref(NULL, &gpuobj);
  168. return -ENOMEM;
  169. }
  170. } else {
  171. NV_DEBUG(dev, "global heap\n");
  172. /* allocate backing pages, sets vinst */
  173. ret = engine->instmem.populate(dev, gpuobj, &size, align);
  174. if (ret) {
  175. nouveau_gpuobj_ref(NULL, &gpuobj);
  176. return ret;
  177. }
  178. /* try and get aperture space */
  179. do {
  180. if (drm_mm_pre_get(&dev_priv->ramin_heap))
  181. return -ENOMEM;
  182. spin_lock(&dev_priv->ramin_lock);
  183. ramin = drm_mm_search_free(&dev_priv->ramin_heap, size,
  184. align, 0);
  185. if (ramin == NULL) {
  186. spin_unlock(&dev_priv->ramin_lock);
  187. nouveau_gpuobj_ref(NULL, &gpuobj);
  188. return -ENOMEM;
  189. }
  190. ramin = drm_mm_get_block_atomic(ramin, size, align);
  191. spin_unlock(&dev_priv->ramin_lock);
  192. } while (ramin == NULL);
  193. /* on nv50 it's ok to fail, we have a fallback path */
  194. if (!ramin && dev_priv->card_type < NV_50) {
  195. nouveau_gpuobj_ref(NULL, &gpuobj);
  196. return -ENOMEM;
  197. }
  198. }
  199. /* if we got a chunk of the aperture, map pages into it */
  200. gpuobj->im_pramin = ramin;
  201. if (!chan && gpuobj->im_pramin && dev_priv->ramin_available) {
  202. ret = engine->instmem.bind(dev, gpuobj);
  203. if (ret) {
  204. nouveau_gpuobj_ref(NULL, &gpuobj);
  205. return ret;
  206. }
  207. }
  208. /* calculate the various different addresses for the object */
  209. if (chan) {
  210. gpuobj->pinst = chan->ramin->pinst;
  211. if (gpuobj->pinst != ~0)
  212. gpuobj->pinst += gpuobj->im_pramin->start;
  213. if (dev_priv->card_type < NV_50) {
  214. gpuobj->cinst = gpuobj->pinst;
  215. } else {
  216. gpuobj->cinst = gpuobj->im_pramin->start;
  217. gpuobj->vinst = gpuobj->im_pramin->start +
  218. chan->ramin->vinst;
  219. }
  220. } else {
  221. if (gpuobj->im_pramin)
  222. gpuobj->pinst = gpuobj->im_pramin->start;
  223. else
  224. gpuobj->pinst = ~0;
  225. gpuobj->cinst = 0xdeadbeef;
  226. }
  227. if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
  228. int i;
  229. for (i = 0; i < gpuobj->size; i += 4)
  230. nv_wo32(gpuobj, i, 0);
  231. engine->instmem.flush(dev);
  232. }
  233. *gpuobj_ret = gpuobj;
  234. return 0;
  235. }
  236. int
  237. nouveau_gpuobj_init(struct drm_device *dev)
  238. {
  239. struct drm_nouveau_private *dev_priv = dev->dev_private;
  240. NV_DEBUG(dev, "\n");
  241. INIT_LIST_HEAD(&dev_priv->gpuobj_list);
  242. INIT_LIST_HEAD(&dev_priv->classes);
  243. spin_lock_init(&dev_priv->ramin_lock);
  244. dev_priv->ramin_base = ~0;
  245. return 0;
  246. }
  247. void
  248. nouveau_gpuobj_takedown(struct drm_device *dev)
  249. {
  250. struct drm_nouveau_private *dev_priv = dev->dev_private;
  251. struct nouveau_gpuobj_method *om, *tm;
  252. struct nouveau_gpuobj_class *oc, *tc;
  253. NV_DEBUG(dev, "\n");
  254. list_for_each_entry_safe(oc, tc, &dev_priv->classes, head) {
  255. list_for_each_entry_safe(om, tm, &oc->methods, head) {
  256. list_del(&om->head);
  257. kfree(om);
  258. }
  259. list_del(&oc->head);
  260. kfree(oc);
  261. }
  262. BUG_ON(!list_empty(&dev_priv->gpuobj_list));
  263. }
  264. static void
  265. nouveau_gpuobj_del(struct kref *ref)
  266. {
  267. struct nouveau_gpuobj *gpuobj =
  268. container_of(ref, struct nouveau_gpuobj, refcount);
  269. struct drm_device *dev = gpuobj->dev;
  270. struct drm_nouveau_private *dev_priv = dev->dev_private;
  271. struct nouveau_engine *engine = &dev_priv->engine;
  272. int i;
  273. NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
  274. if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) {
  275. for (i = 0; i < gpuobj->size; i += 4)
  276. nv_wo32(gpuobj, i, 0);
  277. engine->instmem.flush(dev);
  278. }
  279. if (gpuobj->dtor)
  280. gpuobj->dtor(dev, gpuobj);
  281. if (gpuobj->im_backing)
  282. engine->instmem.clear(dev, gpuobj);
  283. spin_lock(&dev_priv->ramin_lock);
  284. if (gpuobj->im_pramin)
  285. drm_mm_put_block(gpuobj->im_pramin);
  286. list_del(&gpuobj->list);
  287. spin_unlock(&dev_priv->ramin_lock);
  288. kfree(gpuobj);
  289. }
  290. void
  291. nouveau_gpuobj_ref(struct nouveau_gpuobj *ref, struct nouveau_gpuobj **ptr)
  292. {
  293. if (ref)
  294. kref_get(&ref->refcount);
  295. if (*ptr)
  296. kref_put(&(*ptr)->refcount, nouveau_gpuobj_del);
  297. *ptr = ref;
  298. }
  299. int
  300. nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst,
  301. u32 size, u32 flags, struct nouveau_gpuobj **pgpuobj)
  302. {
  303. struct drm_nouveau_private *dev_priv = dev->dev_private;
  304. struct nouveau_gpuobj *gpuobj = NULL;
  305. int i;
  306. NV_DEBUG(dev,
  307. "pinst=0x%08x vinst=0x%010llx size=0x%08x flags=0x%08x\n",
  308. pinst, vinst, size, flags);
  309. gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
  310. if (!gpuobj)
  311. return -ENOMEM;
  312. NV_DEBUG(dev, "gpuobj %p\n", gpuobj);
  313. gpuobj->dev = dev;
  314. gpuobj->flags = flags;
  315. kref_init(&gpuobj->refcount);
  316. gpuobj->size = size;
  317. gpuobj->pinst = pinst;
  318. gpuobj->cinst = 0xdeadbeef;
  319. gpuobj->vinst = vinst;
  320. if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) {
  321. for (i = 0; i < gpuobj->size; i += 4)
  322. nv_wo32(gpuobj, i, 0);
  323. dev_priv->engine.instmem.flush(dev);
  324. }
  325. spin_lock(&dev_priv->ramin_lock);
  326. list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
  327. spin_unlock(&dev_priv->ramin_lock);
  328. *pgpuobj = gpuobj;
  329. return 0;
  330. }
  331. static uint32_t
  332. nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class)
  333. {
  334. struct drm_nouveau_private *dev_priv = dev->dev_private;
  335. /*XXX: dodgy hack for now */
  336. if (dev_priv->card_type >= NV_50)
  337. return 24;
  338. if (dev_priv->card_type >= NV_40)
  339. return 32;
  340. return 16;
  341. }
  342. /*
  343. DMA objects are used to reference a piece of memory in the
  344. framebuffer, PCI or AGP address space. Each object is 16 bytes big
  345. and looks as follows:
  346. entry[0]
  347. 11:0 class (seems like I can always use 0 here)
  348. 12 page table present?
  349. 13 page entry linear?
  350. 15:14 access: 0 rw, 1 ro, 2 wo
  351. 17:16 target: 0 NV memory, 1 NV memory tiled, 2 PCI, 3 AGP
  352. 31:20 dma adjust (bits 0-11 of the address)
  353. entry[1]
  354. dma limit (size of transfer)
  355. entry[X]
  356. 1 0 readonly, 1 readwrite
  357. 31:12 dma frame address of the page (bits 12-31 of the address)
  358. entry[N]
  359. page table terminator, same value as the first pte, as does nvidia
  360. rivatv uses 0xffffffff
  361. Non linear page tables need a list of frame addresses afterwards,
  362. the rivatv project has some info on this.
  363. The method below creates a DMA object in instance RAM and returns a handle
  364. to it that can be used to set up context objects.
  365. */
  366. int
  367. nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class,
  368. uint64_t offset, uint64_t size, int access,
  369. int target, struct nouveau_gpuobj **gpuobj)
  370. {
  371. struct drm_device *dev = chan->dev;
  372. struct drm_nouveau_private *dev_priv = dev->dev_private;
  373. struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
  374. int ret;
  375. NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n",
  376. chan->id, class, offset, size);
  377. NV_DEBUG(dev, "access=%d target=%d\n", access, target);
  378. switch (target) {
  379. case NV_DMA_TARGET_AGP:
  380. offset += dev_priv->gart_info.aper_base;
  381. break;
  382. default:
  383. break;
  384. }
  385. ret = nouveau_gpuobj_new(dev, chan,
  386. nouveau_gpuobj_class_instmem_size(dev, class),
  387. 16, NVOBJ_FLAG_ZERO_ALLOC |
  388. NVOBJ_FLAG_ZERO_FREE, gpuobj);
  389. if (ret) {
  390. NV_ERROR(dev, "Error creating gpuobj: %d\n", ret);
  391. return ret;
  392. }
  393. if (dev_priv->card_type < NV_50) {
  394. uint32_t frame, adjust, pte_flags = 0;
  395. if (access != NV_DMA_ACCESS_RO)
  396. pte_flags |= (1<<1);
  397. adjust = offset & 0x00000fff;
  398. frame = offset & ~0x00000fff;
  399. nv_wo32(*gpuobj, 0, ((1<<12) | (1<<13) | (adjust << 20) |
  400. (access << 14) | (target << 16) |
  401. class));
  402. nv_wo32(*gpuobj, 4, size - 1);
  403. nv_wo32(*gpuobj, 8, frame | pte_flags);
  404. nv_wo32(*gpuobj, 12, frame | pte_flags);
  405. } else {
  406. uint64_t limit = offset + size - 1;
  407. uint32_t flags0, flags5;
  408. if (target == NV_DMA_TARGET_VIDMEM) {
  409. flags0 = 0x00190000;
  410. flags5 = 0x00010000;
  411. } else {
  412. flags0 = 0x7fc00000;
  413. flags5 = 0x00080000;
  414. }
  415. nv_wo32(*gpuobj, 0, flags0 | class);
  416. nv_wo32(*gpuobj, 4, lower_32_bits(limit));
  417. nv_wo32(*gpuobj, 8, lower_32_bits(offset));
  418. nv_wo32(*gpuobj, 12, ((upper_32_bits(limit) & 0xff) << 24) |
  419. (upper_32_bits(offset) & 0xff));
  420. nv_wo32(*gpuobj, 20, flags5);
  421. }
  422. instmem->flush(dev);
  423. (*gpuobj)->engine = NVOBJ_ENGINE_SW;
  424. (*gpuobj)->class = class;
  425. return 0;
  426. }
  427. int
  428. nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan,
  429. uint64_t offset, uint64_t size, int access,
  430. struct nouveau_gpuobj **gpuobj,
  431. uint32_t *o_ret)
  432. {
  433. struct drm_device *dev = chan->dev;
  434. struct drm_nouveau_private *dev_priv = dev->dev_private;
  435. int ret;
  436. if (dev_priv->gart_info.type == NOUVEAU_GART_AGP ||
  437. (dev_priv->card_type >= NV_50 &&
  438. dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) {
  439. ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
  440. offset + dev_priv->vm_gart_base,
  441. size, access, NV_DMA_TARGET_AGP,
  442. gpuobj);
  443. if (o_ret)
  444. *o_ret = 0;
  445. } else
  446. if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) {
  447. nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, gpuobj);
  448. if (offset & ~0xffffffffULL) {
  449. NV_ERROR(dev, "obj offset exceeds 32-bits\n");
  450. return -EINVAL;
  451. }
  452. if (o_ret)
  453. *o_ret = (uint32_t)offset;
  454. ret = (*gpuobj != NULL) ? 0 : -EINVAL;
  455. } else {
  456. NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
  457. return -EINVAL;
  458. }
  459. return ret;
  460. }
  461. /* Context objects in the instance RAM have the following structure.
  462. * On NV40 they are 32 byte long, on NV30 and smaller 16 bytes.
  463. NV4 - NV30:
  464. entry[0]
  465. 11:0 class
  466. 12 chroma key enable
  467. 13 user clip enable
  468. 14 swizzle enable
  469. 17:15 patch config:
  470. scrcopy_and, rop_and, blend_and, scrcopy, srccopy_pre, blend_pre
  471. 18 synchronize enable
  472. 19 endian: 1 big, 0 little
  473. 21:20 dither mode
  474. 23 single step enable
  475. 24 patch status: 0 invalid, 1 valid
  476. 25 context_surface 0: 1 valid
  477. 26 context surface 1: 1 valid
  478. 27 context pattern: 1 valid
  479. 28 context rop: 1 valid
  480. 29,30 context beta, beta4
  481. entry[1]
  482. 7:0 mono format
  483. 15:8 color format
  484. 31:16 notify instance address
  485. entry[2]
  486. 15:0 dma 0 instance address
  487. 31:16 dma 1 instance address
  488. entry[3]
  489. dma method traps
  490. NV40:
  491. No idea what the exact format is. Here's what can be deducted:
  492. entry[0]:
  493. 11:0 class (maybe uses more bits here?)
  494. 17 user clip enable
  495. 21:19 patch config
  496. 25 patch status valid ?
  497. entry[1]:
  498. 15:0 DMA notifier (maybe 20:0)
  499. entry[2]:
  500. 15:0 DMA 0 instance (maybe 20:0)
  501. 24 big endian
  502. entry[3]:
  503. 15:0 DMA 1 instance (maybe 20:0)
  504. entry[4]:
  505. entry[5]:
  506. set to 0?
  507. */
  508. static int
  509. nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
  510. struct nouveau_gpuobj **gpuobj_ret)
  511. {
  512. struct drm_nouveau_private *dev_priv;
  513. struct nouveau_gpuobj *gpuobj;
  514. if (!chan || !gpuobj_ret || *gpuobj_ret != NULL)
  515. return -EINVAL;
  516. dev_priv = chan->dev->dev_private;
  517. gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
  518. if (!gpuobj)
  519. return -ENOMEM;
  520. gpuobj->dev = chan->dev;
  521. gpuobj->engine = NVOBJ_ENGINE_SW;
  522. gpuobj->class = class;
  523. kref_init(&gpuobj->refcount);
  524. gpuobj->cinst = 0x40;
  525. spin_lock(&dev_priv->ramin_lock);
  526. list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
  527. spin_unlock(&dev_priv->ramin_lock);
  528. *gpuobj_ret = gpuobj;
  529. return 0;
  530. }
  531. int
  532. nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
  533. struct nouveau_gpuobj **gpuobj)
  534. {
  535. struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
  536. struct drm_device *dev = chan->dev;
  537. struct nouveau_gpuobj_class *oc;
  538. int ret;
  539. NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);
  540. list_for_each_entry(oc, &dev_priv->classes, head) {
  541. if (oc->id == class)
  542. goto found;
  543. }
  544. NV_ERROR(dev, "illegal object class: 0x%x\n", class);
  545. return -EINVAL;
  546. found:
  547. if (oc->engine == NVOBJ_ENGINE_SW)
  548. return nouveau_gpuobj_sw_new(chan, class, gpuobj);
  549. switch (oc->engine) {
  550. case NVOBJ_ENGINE_GR:
  551. if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) {
  552. struct nouveau_pgraph_engine *pgraph =
  553. &dev_priv->engine.graph;
  554. ret = pgraph->create_context(chan);
  555. if (ret)
  556. return ret;
  557. }
  558. break;
  559. case NVOBJ_ENGINE_CRYPT:
  560. if (!chan->crypt_ctx) {
  561. struct nouveau_crypt_engine *pcrypt =
  562. &dev_priv->engine.crypt;
  563. ret = pcrypt->create_context(chan);
  564. if (ret)
  565. return ret;
  566. }
  567. break;
  568. }
  569. ret = nouveau_gpuobj_new(dev, chan,
  570. nouveau_gpuobj_class_instmem_size(dev, class),
  571. 16,
  572. NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
  573. gpuobj);
  574. if (ret) {
  575. NV_ERROR(dev, "error creating gpuobj: %d\n", ret);
  576. return ret;
  577. }
  578. if (dev_priv->card_type >= NV_50) {
  579. nv_wo32(*gpuobj, 0, class);
  580. nv_wo32(*gpuobj, 20, 0x00010000);
  581. } else {
  582. switch (class) {
  583. case NV_CLASS_NULL:
  584. nv_wo32(*gpuobj, 0, 0x00001030);
  585. nv_wo32(*gpuobj, 4, 0xFFFFFFFF);
  586. break;
  587. default:
  588. if (dev_priv->card_type >= NV_40) {
  589. nv_wo32(*gpuobj, 0, class);
  590. #ifdef __BIG_ENDIAN
  591. nv_wo32(*gpuobj, 8, 0x01000000);
  592. #endif
  593. } else {
  594. #ifdef __BIG_ENDIAN
  595. nv_wo32(*gpuobj, 0, class | 0x00080000);
  596. #else
  597. nv_wo32(*gpuobj, 0, class);
  598. #endif
  599. }
  600. }
  601. }
  602. dev_priv->engine.instmem.flush(dev);
  603. (*gpuobj)->engine = oc->engine;
  604. (*gpuobj)->class = oc->id;
  605. return 0;
  606. }
  607. static int
  608. nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan)
  609. {
  610. struct drm_device *dev = chan->dev;
  611. struct drm_nouveau_private *dev_priv = dev->dev_private;
  612. uint32_t size;
  613. uint32_t base;
  614. int ret;
  615. NV_DEBUG(dev, "ch%d\n", chan->id);
  616. /* Base amount for object storage (4KiB enough?) */
  617. size = 0x2000;
  618. base = 0;
  619. /* PGRAPH context */
  620. size += dev_priv->engine.graph.grctx_size;
  621. if (dev_priv->card_type == NV_50) {
  622. /* Various fixed table thingos */
  623. size += 0x1400; /* mostly unknown stuff */
  624. size += 0x4000; /* vm pd */
  625. base = 0x6000;
  626. /* RAMHT, not sure about setting size yet, 32KiB to be safe */
  627. size += 0x8000;
  628. /* RAMFC */
  629. size += 0x1000;
  630. }
  631. ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin);
  632. if (ret) {
  633. NV_ERROR(dev, "Error allocating channel PRAMIN: %d\n", ret);
  634. return ret;
  635. }
  636. ret = drm_mm_init(&chan->ramin_heap, base, size);
  637. if (ret) {
  638. NV_ERROR(dev, "Error creating PRAMIN heap: %d\n", ret);
  639. nouveau_gpuobj_ref(NULL, &chan->ramin);
  640. return ret;
  641. }
  642. return 0;
  643. }
  644. int
  645. nouveau_gpuobj_channel_init(struct nouveau_channel *chan,
  646. uint32_t vram_h, uint32_t tt_h)
  647. {
  648. struct drm_device *dev = chan->dev;
  649. struct drm_nouveau_private *dev_priv = dev->dev_private;
  650. struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem;
  651. struct nouveau_gpuobj *vram = NULL, *tt = NULL;
  652. int ret, i;
  653. NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h);
  654. /* Allocate a chunk of memory for per-channel object storage */
  655. ret = nouveau_gpuobj_channel_init_pramin(chan);
  656. if (ret) {
  657. NV_ERROR(dev, "init pramin\n");
  658. return ret;
  659. }
  660. /* NV50 VM
  661. * - Allocate per-channel page-directory
  662. * - Map GART and VRAM into the channel's address space at the
  663. * locations determined during init.
  664. */
  665. if (dev_priv->card_type >= NV_50) {
  666. u32 pgd_offs = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200;
  667. u64 vm_vinst = chan->ramin->vinst + pgd_offs;
  668. u32 vm_pinst = chan->ramin->pinst;
  669. u32 pde;
  670. if (vm_pinst != ~0)
  671. vm_pinst += pgd_offs;
  672. ret = nouveau_gpuobj_new_fake(dev, vm_pinst, vm_vinst, 0x4000,
  673. 0, &chan->vm_pd);
  674. if (ret)
  675. return ret;
  676. for (i = 0; i < 0x4000; i += 8) {
  677. nv_wo32(chan->vm_pd, i + 0, 0x00000000);
  678. nv_wo32(chan->vm_pd, i + 4, 0xdeadcafe);
  679. }
  680. nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma,
  681. &chan->vm_gart_pt);
  682. pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 8;
  683. nv_wo32(chan->vm_pd, pde + 0, chan->vm_gart_pt->vinst | 3);
  684. nv_wo32(chan->vm_pd, pde + 4, 0x00000000);
  685. pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 8;
  686. for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) {
  687. nouveau_gpuobj_ref(dev_priv->vm_vram_pt[i],
  688. &chan->vm_vram_pt[i]);
  689. nv_wo32(chan->vm_pd, pde + 0,
  690. chan->vm_vram_pt[i]->vinst | 0x61);
  691. nv_wo32(chan->vm_pd, pde + 4, 0x00000000);
  692. pde += 8;
  693. }
  694. instmem->flush(dev);
  695. }
  696. /* RAMHT */
  697. if (dev_priv->card_type < NV_50) {
  698. nouveau_ramht_ref(dev_priv->ramht, &chan->ramht, NULL);
  699. } else {
  700. struct nouveau_gpuobj *ramht = NULL;
  701. ret = nouveau_gpuobj_new(dev, chan, 0x8000, 16,
  702. NVOBJ_FLAG_ZERO_ALLOC, &ramht);
  703. if (ret)
  704. return ret;
  705. ret = nouveau_ramht_new(dev, ramht, &chan->ramht);
  706. nouveau_gpuobj_ref(NULL, &ramht);
  707. if (ret)
  708. return ret;
  709. }
  710. /* VRAM ctxdma */
  711. if (dev_priv->card_type >= NV_50) {
  712. ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
  713. 0, dev_priv->vm_end,
  714. NV_DMA_ACCESS_RW,
  715. NV_DMA_TARGET_AGP, &vram);
  716. if (ret) {
  717. NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
  718. return ret;
  719. }
  720. } else {
  721. ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
  722. 0, dev_priv->fb_available_size,
  723. NV_DMA_ACCESS_RW,
  724. NV_DMA_TARGET_VIDMEM, &vram);
  725. if (ret) {
  726. NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
  727. return ret;
  728. }
  729. }
  730. ret = nouveau_ramht_insert(chan, vram_h, vram);
  731. nouveau_gpuobj_ref(NULL, &vram);
  732. if (ret) {
  733. NV_ERROR(dev, "Error adding VRAM ctxdma to RAMHT: %d\n", ret);
  734. return ret;
  735. }
  736. /* TT memory ctxdma */
  737. if (dev_priv->card_type >= NV_50) {
  738. ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY,
  739. 0, dev_priv->vm_end,
  740. NV_DMA_ACCESS_RW,
  741. NV_DMA_TARGET_AGP, &tt);
  742. if (ret) {
  743. NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret);
  744. return ret;
  745. }
  746. } else
  747. if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) {
  748. ret = nouveau_gpuobj_gart_dma_new(chan, 0,
  749. dev_priv->gart_info.aper_size,
  750. NV_DMA_ACCESS_RW, &tt, NULL);
  751. } else {
  752. NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type);
  753. ret = -EINVAL;
  754. }
  755. if (ret) {
  756. NV_ERROR(dev, "Error creating TT ctxdma: %d\n", ret);
  757. return ret;
  758. }
  759. ret = nouveau_ramht_insert(chan, tt_h, tt);
  760. nouveau_gpuobj_ref(NULL, &tt);
  761. if (ret) {
  762. NV_ERROR(dev, "Error adding TT ctxdma to RAMHT: %d\n", ret);
  763. return ret;
  764. }
  765. return 0;
  766. }
  767. void
  768. nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan)
  769. {
  770. struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
  771. struct drm_device *dev = chan->dev;
  772. int i;
  773. NV_DEBUG(dev, "ch%d\n", chan->id);
  774. if (!chan->ramht)
  775. return;
  776. nouveau_ramht_ref(NULL, &chan->ramht, chan);
  777. nouveau_gpuobj_ref(NULL, &chan->vm_pd);
  778. nouveau_gpuobj_ref(NULL, &chan->vm_gart_pt);
  779. for (i = 0; i < dev_priv->vm_vram_pt_nr; i++)
  780. nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]);
  781. if (chan->ramin_heap.free_stack.next)
  782. drm_mm_takedown(&chan->ramin_heap);
  783. nouveau_gpuobj_ref(NULL, &chan->ramin);
  784. }
  785. int
  786. nouveau_gpuobj_suspend(struct drm_device *dev)
  787. {
  788. struct drm_nouveau_private *dev_priv = dev->dev_private;
  789. struct nouveau_gpuobj *gpuobj;
  790. int i;
  791. list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
  792. if (gpuobj->cinst != 0xdeadbeef)
  793. continue;
  794. gpuobj->suspend = vmalloc(gpuobj->size);
  795. if (!gpuobj->suspend) {
  796. nouveau_gpuobj_resume(dev);
  797. return -ENOMEM;
  798. }
  799. for (i = 0; i < gpuobj->size; i += 4)
  800. gpuobj->suspend[i/4] = nv_ro32(gpuobj, i);
  801. }
  802. return 0;
  803. }
  804. void
  805. nouveau_gpuobj_resume(struct drm_device *dev)
  806. {
  807. struct drm_nouveau_private *dev_priv = dev->dev_private;
  808. struct nouveau_gpuobj *gpuobj;
  809. int i;
  810. list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) {
  811. if (!gpuobj->suspend)
  812. continue;
  813. for (i = 0; i < gpuobj->size; i += 4)
  814. nv_wo32(gpuobj, i, gpuobj->suspend[i/4]);
  815. vfree(gpuobj->suspend);
  816. gpuobj->suspend = NULL;
  817. }
  818. dev_priv->engine.instmem.flush(dev);
  819. }
  820. int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data,
  821. struct drm_file *file_priv)
  822. {
  823. struct drm_nouveau_grobj_alloc *init = data;
  824. struct nouveau_gpuobj *gr = NULL;
  825. struct nouveau_channel *chan;
  826. int ret;
  827. if (init->handle == ~0)
  828. return -EINVAL;
  829. chan = nouveau_channel_get(dev, file_priv, init->channel);
  830. if (IS_ERR(chan))
  831. return PTR_ERR(chan);
  832. if (nouveau_ramht_find(chan, init->handle)) {
  833. ret = -EEXIST;
  834. goto out;
  835. }
  836. ret = nouveau_gpuobj_gr_new(chan, init->class, &gr);
  837. if (ret) {
  838. NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n",
  839. ret, init->channel, init->handle);
  840. goto out;
  841. }
  842. ret = nouveau_ramht_insert(chan, init->handle, gr);
  843. nouveau_gpuobj_ref(NULL, &gr);
  844. if (ret) {
  845. NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n",
  846. ret, init->channel, init->handle);
  847. }
  848. out:
  849. nouveau_channel_put(&chan);
  850. return ret;
  851. }
  852. int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data,
  853. struct drm_file *file_priv)
  854. {
  855. struct drm_nouveau_gpuobj_free *objfree = data;
  856. struct nouveau_channel *chan;
  857. int ret;
  858. chan = nouveau_channel_get(dev, file_priv, objfree->channel);
  859. if (IS_ERR(chan))
  860. return PTR_ERR(chan);
  861. ret = nouveau_ramht_remove(chan, objfree->handle);
  862. nouveau_channel_put(&chan);
  863. return ret;
  864. }
  865. u32
  866. nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset)
  867. {
  868. struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
  869. struct drm_device *dev = gpuobj->dev;
  870. if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
  871. u64 ptr = gpuobj->vinst + offset;
  872. u32 base = ptr >> 16;
  873. u32 val;
  874. spin_lock(&dev_priv->ramin_lock);
  875. if (dev_priv->ramin_base != base) {
  876. dev_priv->ramin_base = base;
  877. nv_wr32(dev, 0x001700, dev_priv->ramin_base);
  878. }
  879. val = nv_rd32(dev, 0x700000 + (ptr & 0xffff));
  880. spin_unlock(&dev_priv->ramin_lock);
  881. return val;
  882. }
  883. return nv_ri32(dev, gpuobj->pinst + offset);
  884. }
  885. void
  886. nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val)
  887. {
  888. struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private;
  889. struct drm_device *dev = gpuobj->dev;
  890. if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) {
  891. u64 ptr = gpuobj->vinst + offset;
  892. u32 base = ptr >> 16;
  893. spin_lock(&dev_priv->ramin_lock);
  894. if (dev_priv->ramin_base != base) {
  895. dev_priv->ramin_base = base;
  896. nv_wr32(dev, 0x001700, dev_priv->ramin_base);
  897. }
  898. nv_wr32(dev, 0x700000 + (ptr & 0xffff), val);
  899. spin_unlock(&dev_priv->ramin_lock);
  900. return;
  901. }
  902. nv_wi32(dev, gpuobj->pinst + offset, val);
  903. }