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
*userdev
, uint32_t fb_ctxdma
,
32 uint32_t tt_ctxdma
, struct nouveau_channel
**userchan
)
34 struct nouveau_device_priv
*nv
= nouveau_device(userdev
);
35 struct nouveau_channel_priv
*chan
;
38 if (!nv
|| !userchan
|| *userchan
)
41 chan
= calloc(1, sizeof(*chan
));
44 chan
->base
.device
= userdev
;
46 chan
->drm
.fb_ctxdma_handle
= fb_ctxdma
;
47 chan
->drm
.tt_ctxdma_handle
= tt_ctxdma
;
48 ret
= drmCommandWriteRead(nv
->fd
, DRM_NOUVEAU_CHANNEL_ALLOC
,
49 &chan
->drm
, sizeof(chan
->drm
));
55 chan
->base
.id
= chan
->drm
.channel
;
56 if (nouveau_grobj_ref(&chan
->base
, chan
->drm
.fb_ctxdma_handle
,
58 nouveau_grobj_ref(&chan
->base
, chan
->drm
.tt_ctxdma_handle
,
60 nouveau_channel_free((void *)&chan
);
64 ret
= drmMap(nv
->fd
, chan
->drm
.ctrl
, chan
->drm
.ctrl_size
,
67 nouveau_channel_free((void *)&chan
);
70 chan
->put
= &chan
->user
[0x40/4];
71 chan
->get
= &chan
->user
[0x44/4];
72 chan
->ref_cnt
= &chan
->user
[0x48/4];
74 ret
= drmMap(nv
->fd
, chan
->drm
.notifier
, chan
->drm
.notifier_size
,
75 (drmAddressPtr
)&chan
->notifier_block
);
77 nouveau_channel_free((void *)&chan
);
81 ret
= drmMap(nv
->fd
, chan
->drm
.cmdbuf
, chan
->drm
.cmdbuf_size
,
82 (void*)&chan
->pushbuf
);
84 nouveau_channel_free((void *)&chan
);
88 nouveau_dma_channel_init(&chan
->base
);
89 nouveau_pushbuf_init(&chan
->base
);
91 *userchan
= &chan
->base
;
96 nouveau_channel_free(struct nouveau_channel
**userchan
)
98 struct nouveau_channel_priv
*chan
;
102 chan
= nouveau_channel(*userchan
);
105 struct nouveau_device_priv
*nv
;
106 struct drm_nouveau_channel_free cf
;
108 nv
= nouveau_device((*userchan
)->device
);
111 FIRE_RING_CH(&chan
->base
);
113 nouveau_grobj_free(&chan
->base
.vram
);
114 nouveau_grobj_free(&chan
->base
.gart
);
116 cf
.channel
= chan
->drm
.channel
;
117 drmCommandWrite(nv
->fd
, DRM_NOUVEAU_CHANNEL_FREE
,