aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-09 14:10:25 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-08-09 15:28:06 -0400
commit410f3ec63570bea8efe00826a2b83ceb353553b1 (patch)
tree0a91f07fe4e2507573d0ffcf02ad58318a43d245 /drivers/gpu
parent867920f8c920bcaa5a6fa5ebad4596669b82ba80 (diff)
drm/nv50/kms: don't assume same class versions for all channels
One of the next commits will remove some of the class IDs, leaving only the ones used by NVIDIA which, presumably, mark where functionality changes actually happened. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c214
1 files changed, 166 insertions, 48 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 4f50add8e6dd..2d9a02c4b87e 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -68,19 +68,17 @@ struct nv50_chan {
68}; 68};
69 69
70static int 70static int
71nv50_chan_create(struct nvif_object *disp, u32 bclass, u8 head, 71nv50_chan_create(struct nvif_object *disp, const u32 *oclass, u8 head,
72 void *data, u32 size, struct nv50_chan *chan) 72 void *data, u32 size, struct nv50_chan *chan)
73{ 73{
74 const u32 oclass = EVO_CHAN_OCLASS(bclass, disp); 74 while (oclass[0]) {
75 const u32 handle = EVO_CHAN_HANDLE(bclass, head); 75 int ret = nvif_object_init(disp, NULL, (oclass[0] << 16) | head,
76 int ret; 76 oclass[0], data, size,
77 77 &chan->user);
78 ret = nvif_object_init(disp, NULL, handle, oclass, data, size, 78 if (oclass++, ret == 0)
79 &chan->user); 79 return ret;
80 if (ret) 80 }
81 return ret; 81 return -ENOSYS;
82
83 return 0;
84} 82}
85 83
86static void 84static void
@@ -104,10 +102,72 @@ nv50_pioc_destroy(struct nv50_pioc *pioc)
104} 102}
105 103
106static int 104static int
107nv50_pioc_create(struct nvif_object *disp, u32 bclass, u8 head, 105nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head,
108 void *data, u32 size, struct nv50_pioc *pioc) 106 void *data, u32 size, struct nv50_pioc *pioc)
109{ 107{
110 return nv50_chan_create(disp, bclass, head, data, size, &pioc->base); 108 return nv50_chan_create(disp, oclass, head, data, size, &pioc->base);
109}
110
111/******************************************************************************
112 * Cursor Immediate
113 *****************************************************************************/
114
115struct nv50_curs {
116 struct nv50_pioc base;
117};
118
119static int
120nv50_curs_create(struct nvif_object *disp, int head, struct nv50_curs *curs)
121{
122 struct nv50_display_curs_class args = {
123 .head = head,
124 };
125 static const u32 oclass[] = {
126 GM107_DISP_CURS_CLASS,
127 NVF0_DISP_CURS_CLASS,
128 NVE0_DISP_CURS_CLASS,
129 NVD0_DISP_CURS_CLASS,
130 NVA3_DISP_CURS_CLASS,
131 NV94_DISP_CURS_CLASS,
132 NVA0_DISP_CURS_CLASS,
133 NV84_DISP_CURS_CLASS,
134 NV50_DISP_CURS_CLASS,
135 0
136 };
137
138 return nv50_pioc_create(disp, oclass, head, &args, sizeof(args),
139 &curs->base);
140}
141
142/******************************************************************************
143 * Overlay Immediate
144 *****************************************************************************/
145
146struct nv50_oimm {
147 struct nv50_pioc base;
148};
149
150static int
151nv50_oimm_create(struct nvif_object *disp, int head, struct nv50_oimm *oimm)
152{
153 struct nv50_display_oimm_class args = {
154 .head = head,
155 };
156 static const u32 oclass[] = {
157 GM107_DISP_OIMM_CLASS,
158 NVF0_DISP_OIMM_CLASS,
159 NVE0_DISP_OIMM_CLASS,
160 NVD0_DISP_OIMM_CLASS,
161 NVA3_DISP_OIMM_CLASS,
162 NV94_DISP_OIMM_CLASS,
163 NVA0_DISP_OIMM_CLASS,
164 NV84_DISP_OIMM_CLASS,
165 NV50_DISP_OIMM_CLASS,
166 0
167 };
168
169 return nv50_pioc_create(disp, oclass, head, &args, sizeof(args),
170 &oimm->base);
111} 171}
112 172
113/****************************************************************************** 173/******************************************************************************
@@ -143,7 +203,7 @@ nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp)
143} 203}
144 204
145static int 205static int
146nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head, 206nv50_dmac_create(struct nvif_object *disp, const u32 *oclass, u8 head,
147 void *data, u32 size, u64 syncbuf, 207 void *data, u32 size, u64 syncbuf,
148 struct nv50_dmac *dmac) 208 struct nv50_dmac *dmac)
149{ 209{
@@ -170,7 +230,7 @@ nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head,
170 if (ret) 230 if (ret)
171 return ret; 231 return ret;
172 232
173 ret = nv50_chan_create(disp, bclass, head, data, size, &dmac->base); 233 ret = nv50_chan_create(disp, oclass, head, data, size, &dmac->base);
174 nvif_object_fini(&pushbuf); 234 nvif_object_fini(&pushbuf);
175 if (ret) 235 if (ret)
176 return ret; 236 return ret;
@@ -202,13 +262,40 @@ nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head,
202 return ret; 262 return ret;
203} 263}
204 264
265/******************************************************************************
266 * Core
267 *****************************************************************************/
268
205struct nv50_mast { 269struct nv50_mast {
206 struct nv50_dmac base; 270 struct nv50_dmac base;
207}; 271};
208 272
209struct nv50_curs { 273static int
210 struct nv50_pioc base; 274nv50_core_create(struct nvif_object *disp, u64 syncbuf, struct nv50_mast *core)
211}; 275{
276 struct nv50_display_mast_class args = {
277 .pushbuf = EVO_PUSH_HANDLE(MAST, 0),
278 };
279 static const u32 oclass[] = {
280 GM107_DISP_MAST_CLASS,
281 NVF0_DISP_MAST_CLASS,
282 NVE0_DISP_MAST_CLASS,
283 NVD0_DISP_MAST_CLASS,
284 NVA3_DISP_MAST_CLASS,
285 NV94_DISP_MAST_CLASS,
286 NVA0_DISP_MAST_CLASS,
287 NV84_DISP_MAST_CLASS,
288 NV50_DISP_MAST_CLASS,
289 0
290 };
291
292 return nv50_dmac_create(disp, oclass, 0, &args, sizeof(args), syncbuf,
293 &core->base);
294}
295
296/******************************************************************************
297 * Base
298 *****************************************************************************/
212 299
213struct nv50_sync { 300struct nv50_sync {
214 struct nv50_dmac base; 301 struct nv50_dmac base;
@@ -216,13 +303,63 @@ struct nv50_sync {
216 u32 data; 303 u32 data;
217}; 304};
218 305
306static int
307nv50_base_create(struct nvif_object *disp, int head, u64 syncbuf,
308 struct nv50_sync *base)
309{
310 struct nv50_display_sync_class args = {
311 .pushbuf = EVO_PUSH_HANDLE(SYNC, head),
312 .head = head,
313 };
314 static const u32 oclass[] = {
315 GM107_DISP_SYNC_CLASS,
316 NVF0_DISP_SYNC_CLASS,
317 NVE0_DISP_SYNC_CLASS,
318 NVD0_DISP_SYNC_CLASS,
319 NVA3_DISP_SYNC_CLASS,
320 NV94_DISP_SYNC_CLASS,
321 NVA0_DISP_SYNC_CLASS,
322 NV84_DISP_SYNC_CLASS,
323 NV50_DISP_SYNC_CLASS,
324 0
325 };
326
327 return nv50_dmac_create(disp, oclass, head, &args, sizeof(args),
328 syncbuf, &base->base);
329}
330
331/******************************************************************************
332 * Overlay
333 *****************************************************************************/
334
219struct nv50_ovly { 335struct nv50_ovly {
220 struct nv50_dmac base; 336 struct nv50_dmac base;
221}; 337};
222 338
223struct nv50_oimm { 339static int
224 struct nv50_pioc base; 340nv50_ovly_create(struct nvif_object *disp, int head, u64 syncbuf,
225}; 341 struct nv50_ovly *ovly)
342{
343 struct nv50_display_ovly_class args = {
344 .pushbuf = EVO_PUSH_HANDLE(OVLY, head),
345 .head = head,
346 };
347 static const u32 oclass[] = {
348 GM107_DISP_OVLY_CLASS,
349 NVF0_DISP_OVLY_CLASS,
350 NVE0_DISP_OVLY_CLASS,
351 NVD0_DISP_OVLY_CLASS,
352 NVA3_DISP_OVLY_CLASS,
353 NV94_DISP_OVLY_CLASS,
354 NVA0_DISP_OVLY_CLASS,
355 NV84_DISP_OVLY_CLASS,
356 NV50_DISP_OVLY_CLASS,
357 0
358 };
359
360 return nv50_dmac_create(disp, oclass, head, &args, sizeof(args),
361 syncbuf, &ovly->base);
362}
226 363
227struct nv50_head { 364struct nv50_head {
228 struct nouveau_crtc base; 365 struct nouveau_crtc base;
@@ -1276,11 +1413,7 @@ nv50_crtc_create(struct drm_device *dev, int index)
1276 nv50_crtc_lut_load(crtc); 1413 nv50_crtc_lut_load(crtc);
1277 1414
1278 /* allocate cursor resources */ 1415 /* allocate cursor resources */
1279 ret = nv50_pioc_create(disp->disp, NV50_DISP_CURS_CLASS, index, 1416 ret = nv50_curs_create(disp->disp, index, &head->curs);
1280 &(struct nv50_display_curs_class) {
1281 .head = index,
1282 }, sizeof(struct nv50_display_curs_class),
1283 &head->curs.base);
1284 if (ret) 1417 if (ret)
1285 goto out; 1418 goto out;
1286 1419
@@ -1301,12 +1434,8 @@ nv50_crtc_create(struct drm_device *dev, int index)
1301 goto out; 1434 goto out;
1302 1435
1303 /* allocate page flip / sync resources */ 1436 /* allocate page flip / sync resources */
1304 ret = nv50_dmac_create(disp->disp, NV50_DISP_SYNC_CLASS, index, 1437 ret = nv50_base_create(disp->disp, index, disp->sync->bo.offset,
1305 &(struct nv50_display_sync_class) { 1438 &head->sync);
1306 .pushbuf = EVO_PUSH_HANDLE(SYNC, index),
1307 .head = index,
1308 }, sizeof(struct nv50_display_sync_class),
1309 disp->sync->bo.offset, &head->sync.base);
1310 if (ret) 1439 if (ret)
1311 goto out; 1440 goto out;
1312 1441
@@ -1314,20 +1443,12 @@ nv50_crtc_create(struct drm_device *dev, int index)
1314 head->sync.data = 0x00000000; 1443 head->sync.data = 0x00000000;
1315 1444
1316 /* allocate overlay resources */ 1445 /* allocate overlay resources */
1317 ret = nv50_pioc_create(disp->disp, NV50_DISP_OIMM_CLASS, index, 1446 ret = nv50_oimm_create(disp->disp, index, &head->oimm);
1318 &(struct nv50_display_oimm_class) {
1319 .head = index,
1320 }, sizeof(struct nv50_display_oimm_class),
1321 &head->oimm.base);
1322 if (ret) 1447 if (ret)
1323 goto out; 1448 goto out;
1324 1449
1325 ret = nv50_dmac_create(disp->disp, NV50_DISP_OVLY_CLASS, index, 1450 ret = nv50_ovly_create(disp->disp, index, disp->sync->bo.offset,
1326 &(struct nv50_display_ovly_class) { 1451 &head->ovly);
1327 .pushbuf = EVO_PUSH_HANDLE(OVLY, index),
1328 .head = index,
1329 }, sizeof(struct nv50_display_ovly_class),
1330 disp->sync->bo.offset, &head->ovly.base);
1331 if (ret) 1452 if (ret)
1332 goto out; 1453 goto out;
1333 1454
@@ -2288,11 +2409,8 @@ nv50_display_create(struct drm_device *dev)
2288 goto out; 2409 goto out;
2289 2410
2290 /* allocate master evo channel */ 2411 /* allocate master evo channel */
2291 ret = nv50_dmac_create(disp->disp, NV50_DISP_MAST_CLASS, 0, 2412 ret = nv50_core_create(disp->disp, disp->sync->bo.offset,
2292 &(struct nv50_display_mast_class) { 2413 &disp->mast);
2293 .pushbuf = EVO_PUSH_HANDLE(MAST, 0),
2294 }, sizeof(struct nv50_display_mast_class),
2295 disp->sync->bo.offset, &disp->mast.base);
2296 if (ret) 2414 if (ret)
2297 goto out; 2415 goto out;
2298 2416