nouveau_copy.c revision c2e4ac43
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include "nouveau_copy.h"
26
27void
28nouveau_copy_fini(ScreenPtr pScreen)
29{
30	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
31	NVPtr pNv = NVPTR(pScrn);
32	nouveau_object_del(&pNv->NvCopy);
33	nouveau_pushbuf_del(&pNv->ce_pushbuf);
34	nouveau_object_del(&pNv->ce_channel);
35}
36
37Bool
38nouveau_copy_init(ScreenPtr pScreen)
39{
40	static const struct {
41		CARD32 oclass;
42		int engine;
43		Bool (*init)(NVPtr);
44	} methods[] = {
45		{ 0xa0b5, 0, nouveau_copya0b5_init },
46		{ 0x90b8, 5, nouveau_copy90b5_init },
47		{ 0x90b5, 4, nouveau_copy90b5_init },
48		{ 0x85b5, 0, nouveau_copy85b5_init },
49		{}
50	}, *method = methods;
51	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
52	NVPtr pNv = NVPTR(pScrn);
53	int ret;
54
55	if (pNv->AccelMethod == NONE) {
56		xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
57			   "[COPY] acceleration disabled\n");
58		return FALSE;
59	}
60
61	switch (pNv->Architecture) {
62	case NV_TESLA:
63		if (pNv->dev->chipset < 0xa3 ||
64		    pNv->dev->chipset == 0xaa ||
65		    pNv->dev->chipset == 0xac)
66			return FALSE;
67
68		ret = nouveau_object_new(&pNv->dev->object, 0,
69					 NOUVEAU_FIFO_CHANNEL_CLASS,
70					 &(struct nv04_fifo) {
71						.vram = NvDmaFB,
72						.gart = NvDmaTT,
73					 }, sizeof(struct nv04_fifo),
74					 &pNv->ce_channel);
75		break;
76	case NV_FERMI:
77		ret = nouveau_object_new(&pNv->dev->object, 0,
78					 NOUVEAU_FIFO_CHANNEL_CLASS,
79					 &(struct nvc0_fifo) {
80					 }, sizeof(struct nvc0_fifo),
81					 &pNv->ce_channel);
82		break;
83	case NV_KEPLER:
84		ret = nouveau_object_new(&pNv->dev->object, 0,
85					 NOUVEAU_FIFO_CHANNEL_CLASS,
86					 &(struct nve0_fifo) {
87						.engine = NVE0_FIFO_ENGINE_CE0 |
88							  NVE0_FIFO_ENGINE_CE1,
89					 }, sizeof(struct nve0_fifo),
90					 &pNv->ce_channel);
91		break;
92	default:
93		return FALSE;
94	}
95
96	if (ret) {
97		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
98			   "[COPY] error allocating channel: %d\n", ret);
99		return FALSE;
100	}
101
102	ret = nouveau_pushbuf_new(pNv->client, pNv->ce_channel, 4,
103				  32 * 1024, true, &pNv->ce_pushbuf);
104	if (ret) {
105		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
106			   "[COPY] error allocating pushbuf: %d\n", ret);
107		nouveau_copy_fini(pScreen);
108		return FALSE;
109	}
110
111	while (method->init) {
112		ret = nouveau_object_new(pNv->ce_channel,
113					 method->engine << 16 | method->oclass,
114					 method->oclass, NULL, 0,
115					 &pNv->NvCopy);
116		if (ret == 0) {
117			if (!method->init(pNv)) {
118				xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
119					   "[COPY] failed to initialise.\n");
120				nouveau_copy_fini(pScreen);
121				return FALSE;
122			}
123			break;
124		}
125		method++;
126	}
127
128	if (ret) {
129		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
130			   "[COPY] failed to allocate class.\n");
131		nouveau_copy_fini(pScreen);
132		return FALSE;
133	}
134
135	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[COPY] async initialised.\n");
136	return TRUE;
137}
138