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 ret
= nouveau_grobj_alloc(&nvchan
->base
, 0x00000000, 0x0030,
89 &nvchan
->base
.nullobj
);
91 nouveau_channel_free((void *)&nvchan
);
95 nouveau_dma_channel_init(&nvchan
->base
);
96 nouveau_pushbuf_init(&nvchan
->base
);
98 *chan
= &nvchan
->base
;
103 nouveau_channel_free(struct nouveau_channel
**chan
)
105 struct nouveau_channel_priv
*nvchan
;
106 struct nouveau_device_priv
*nvdev
;
107 struct drm_nouveau_channel_free cf
;
111 nvchan
= nouveau_channel(*chan
);
113 nvdev
= nouveau_device(nvchan
->base
.device
);
115 FIRE_RING_CH(&nvchan
->base
);
117 nouveau_grobj_free(&nvchan
->base
.vram
);
118 nouveau_grobj_free(&nvchan
->base
.gart
);
119 nouveau_grobj_free(&nvchan
->base
.nullobj
);
121 cf
.channel
= nvchan
->drm
.channel
;
122 drmCommandWrite(nvdev
->fd
, DRM_NOUVEAU_CHANNEL_FREE
, &cf
, sizeof(cf
));