1 /*
2  * Copyright 2012 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
23  */
24 #include <engine/ce.h>
25 #include <engine/fifo.h>
26 
27 #include <nvif/class.h>
28 
29 static void
30 gk104_ce_intr(struct nvkm_subdev *subdev)
31 {
32 	struct nvkm_device *device = subdev->device;
33 	const int idx = nv_subidx(subdev) - NVDEV_ENGINE_CE0;
34 	u32 stat = nvkm_rd32(device, 0x104908 + (idx * 0x1000));
35 
36 	if (stat) {
37 		nvkm_warn(subdev, "intr %08x\n", stat);
38 		nvkm_wr32(device, 0x104908 + (idx * 0x1000), stat);
39 	}
40 }
41 
42 static const struct nvkm_engine_func
43 gk104_ce = {
44 	.sclass = {
45 		{ -1, -1, KEPLER_DMA_COPY_A },
46 		{}
47 	}
48 };
49 
50 static int
51 gk104_ce0_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
52 	       struct nvkm_oclass *oclass, void *data, u32 size,
53 	       struct nvkm_object **pobject)
54 {
55 	struct nvkm_engine *ce;
56 	int ret;
57 
58 	ret = nvkm_engine_create(parent, engine, oclass, true,
59 				 "PCE0", "ce0", &ce);
60 	*pobject = nv_object(ce);
61 	if (ret)
62 		return ret;
63 
64 	ce->func = &gk104_ce;
65 	nv_subdev(ce)->unit = 0x00000040;
66 	nv_subdev(ce)->intr = gk104_ce_intr;
67 	return 0;
68 }
69 
70 static int
71 gk104_ce1_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
72 	       struct nvkm_oclass *oclass, void *data, u32 size,
73 	       struct nvkm_object **pobject)
74 {
75 	struct nvkm_engine *ce;
76 	int ret;
77 
78 	ret = nvkm_engine_create(parent, engine, oclass, true,
79 				 "PCE1", "ce1", &ce);
80 	*pobject = nv_object(ce);
81 	if (ret)
82 		return ret;
83 
84 	ce->func = &gk104_ce;
85 	nv_subdev(ce)->unit = 0x00000080;
86 	nv_subdev(ce)->intr = gk104_ce_intr;
87 	return 0;
88 }
89 
90 static int
91 gk104_ce2_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
92 	       struct nvkm_oclass *oclass, void *data, u32 size,
93 	       struct nvkm_object **pobject)
94 {
95 	struct nvkm_engine *ce;
96 	int ret;
97 
98 	ret = nvkm_engine_create(parent, engine, oclass, true,
99 				 "PCE2", "ce2", &ce);
100 	*pobject = nv_object(ce);
101 	if (ret)
102 		return ret;
103 
104 	ce->func = &gk104_ce;
105 	nv_subdev(ce)->unit = 0x00200000;
106 	nv_subdev(ce)->intr = gk104_ce_intr;
107 	return 0;
108 }
109 
110 struct nvkm_oclass
111 gk104_ce0_oclass = {
112 	.handle = NV_ENGINE(CE0, 0xe0),
113 	.ofuncs = &(struct nvkm_ofuncs) {
114 		.ctor = gk104_ce0_ctor,
115 		.dtor = _nvkm_engine_dtor,
116 		.init = _nvkm_engine_init,
117 		.fini = _nvkm_engine_fini,
118 	},
119 };
120 
121 struct nvkm_oclass
122 gk104_ce1_oclass = {
123 	.handle = NV_ENGINE(CE1, 0xe0),
124 	.ofuncs = &(struct nvkm_ofuncs) {
125 		.ctor = gk104_ce1_ctor,
126 		.dtor = _nvkm_engine_dtor,
127 		.init = _nvkm_engine_init,
128 		.fini = _nvkm_engine_fini,
129 	},
130 };
131 
132 struct nvkm_oclass
133 gk104_ce2_oclass = {
134 	.handle = NV_ENGINE(CE2, 0xe0),
135 	.ofuncs = &(struct nvkm_ofuncs) {
136 		.ctor = gk104_ce2_ctor,
137 		.dtor = _nvkm_engine_dtor,
138 		.init = _nvkm_engine_init,
139 		.fini = _nvkm_engine_fini,
140 	},
141 };
142