2 * Copyright 2007 Nouveau Project
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 #include "nouveau_drmif.h"
28 #include "nouveau_dma.h"
31 nouveau_channel_alloc(struct nouveau_device
*dev
, uint32_t fb_ctxdma
,
32 uint32_t tt_ctxdma
, struct nouveau_channel
**chan
)
34 struct nouveau_device_priv
*nvdev
= nouveau_device(dev
);
35 struct nouveau_channel_priv
*nvchan
;
38 if (!nvdev
|| !chan
|| *chan
)
41 nvchan
= calloc(1, sizeof(struct nouveau_channel_priv
));
44 nvchan
->base
.device
= dev
;
46 nvchan
->drm
.fb_ctxdma_handle
= fb_ctxdma
;
47 nvchan
->drm
.tt_ctxdma_handle
= tt_ctxdma
;
48 ret
= drmCommandWriteRead(nvdev
->fd
, DRM_NOUVEAU_CHANNEL_ALLOC
,
49 &nvchan
->drm
, sizeof(nvchan
->drm
));
55 nvchan
->base
.id
= nvchan
->drm
.channel
;
56 if (nouveau_grobj_ref(&nvchan
->base
, nvchan
->drm
.fb_ctxdma_handle
,
57 &nvchan
->base
.vram
) ||
58 nouveau_grobj_ref(&nvchan
->base
, nvchan
->drm
.tt_ctxdma_handle
,
59 &nvchan
->base
.gart
)) {
60 nouveau_channel_free((void *)&nvchan
);
64 ret
= drmMap(nvdev
->fd
, nvchan
->drm
.ctrl
, nvchan
->drm
.ctrl_size
,
65 (void*)&nvchan
->user
);
67 nouveau_channel_free((void *)&nvchan
);
70 nvchan
->put
= &nvchan
->user
[0x40/4];
71 nvchan
->get
= &nvchan
->user
[0x44/4];
72 nvchan
->ref_cnt
= &nvchan
->user
[0x48/4];
74 ret
= drmMap(nvdev
->fd
, nvchan
->drm
.notifier
, nvchan
->drm
.notifier_size
,
75 (drmAddressPtr
)&nvchan
->notifier_block
);
77 nouveau_channel_free((void *)&nvchan
);
81 ret
= drmMap(nvdev
->fd
, nvchan
->drm
.cmdbuf
, nvchan
->drm
.cmdbuf_size
,
82 (void*)&nvchan
->pushbuf
);
84 nouveau_channel_free((void *)&nvchan
);
88 nouveau_dma_channel_init(&nvchan
->base
);
89 nouveau_pushbuf_init(&nvchan
->base
);
91 *chan
= &nvchan
->base
;
96 nouveau_channel_free(struct nouveau_channel
**chan
)
98 struct nouveau_channel_priv
*nvchan
;
99 struct nouveau_device_priv
*nvdev
;
100 struct drm_nouveau_channel_free cf
;
104 nvchan
= nouveau_channel(*chan
);
106 nvdev
= nouveau_device(nvchan
->base
.device
);
108 FIRE_RING_CH(&nvchan
->base
);
110 nouveau_grobj_free(&nvchan
->base
.vram
);
111 nouveau_grobj_free(&nvchan
->base
.gart
);
113 cf
.channel
= nvchan
->drm
.channel
;
114 drmCommandWrite(nvdev
->fd
, DRM_NOUVEAU_CHANNEL_FREE
, &cf
, sizeof(cf
));