aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_evo.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-02-06 22:29:23 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-02-24 15:45:11 -0500
commitcdccc70eff1eaf3627a716374f9ebc115fc4621c (patch)
tree744a5a9e35c5749326d3bfb85336afceb24c2b4d /drivers/gpu/drm/nouveau/nv50_evo.c
parent45c4e0aae96c6354bf5131a282a74fe38d032de3 (diff)
drm/nv50-nvc0: initialise display sync channels
Also imports a couple of helper functions that'll be used to implement page flipping in the following commits.. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_evo.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_evo.c88
1 files changed, 84 insertions, 4 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c
index b70208e981fb..18fbf27376c1 100644
--- a/drivers/gpu/drm/nouveau/nv50_evo.c
+++ b/drivers/gpu/drm/nouveau/nv50_evo.c
@@ -220,7 +220,15 @@ static void
220nv50_evo_destroy(struct drm_device *dev) 220nv50_evo_destroy(struct drm_device *dev)
221{ 221{
222 struct nv50_display *disp = nv50_display(dev); 222 struct nv50_display *disp = nv50_display(dev);
223 223 int i;
224
225 for (i = 0; i < 2; i++) {
226 if (disp->crtc[i].sem.bo) {
227 nouveau_bo_unmap(disp->crtc[i].sem.bo);
228 nouveau_bo_ref(NULL, &disp->crtc[i].sem.bo);
229 }
230 nv50_evo_channel_del(&disp->crtc[i].sync);
231 }
224 nouveau_gpuobj_ref(NULL, &disp->ntfy); 232 nouveau_gpuobj_ref(NULL, &disp->ntfy);
225 nv50_evo_channel_del(&disp->master); 233 nv50_evo_channel_del(&disp->master);
226} 234}
@@ -232,7 +240,7 @@ nv50_evo_create(struct drm_device *dev)
232 struct nv50_display *disp = nv50_display(dev); 240 struct nv50_display *disp = nv50_display(dev);
233 struct nouveau_gpuobj *ramht = NULL; 241 struct nouveau_gpuobj *ramht = NULL;
234 struct nouveau_channel *evo; 242 struct nouveau_channel *evo;
235 int ret; 243 int ret, i, j;
236 244
237 /* create primary evo channel, the one we use for modesetting 245 /* create primary evo channel, the one we use for modesetting
238 * purporses 246 * purporses
@@ -311,6 +319,61 @@ nv50_evo_create(struct drm_device *dev)
311 if (ret) 319 if (ret)
312 goto err; 320 goto err;
313 321
322 /* create "display sync" channels and other structures we need
323 * to implement page flipping
324 */
325 for (i = 0; i < 2; i++) {
326 struct nv50_display_crtc *dispc = &disp->crtc[i];
327 u64 offset;
328
329 ret = nv50_evo_channel_new(dev, 1 + i, &dispc->sync);
330 if (ret)
331 goto err;
332
333 ret = nouveau_bo_new(dev, NULL, 4096, 0x1000, TTM_PL_FLAG_VRAM,
334 0, 0x0000, false, true, &dispc->sem.bo);
335 if (!ret) {
336 offset = dispc->sem.bo->bo.mem.start << PAGE_SHIFT;
337
338 ret = nouveau_bo_pin(dispc->sem.bo, TTM_PL_FLAG_VRAM);
339 if (!ret)
340 ret = nouveau_bo_map(dispc->sem.bo);
341 if (ret)
342 nouveau_bo_ref(NULL, &dispc->sem.bo);
343 }
344
345 if (ret)
346 goto err;
347
348 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoSync, 0x0000,
349 offset, 4096, NULL);
350 if (ret)
351 goto err;
352
353 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoVRAM_LP, 0x80000000,
354 0, dev_priv->vram_size, NULL);
355 if (ret)
356 goto err;
357
358 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB32, 0x80000000 |
359 (dev_priv->chipset < 0xc0 ?
360 0x7a00 : 0xfe00),
361 0, dev_priv->vram_size, NULL);
362 if (ret)
363 goto err;
364
365 ret = nv50_evo_dmaobj_new(dispc->sync, NvEvoFB16, 0x80000000 |
366 (dev_priv->chipset < 0xc0 ?
367 0x7000 : 0xfe00),
368 0, dev_priv->vram_size, NULL);
369 if (ret)
370 goto err;
371
372 for (j = 0; j < 4096; j += 4)
373 nouveau_bo_wr32(dispc->sem.bo, j / 4, 0x74b1e000);
374 dispc->sem.offset = 0;
375 }
376
314 return 0; 377 return 0;
315 378
316err: 379err:
@@ -322,7 +385,7 @@ int
322nv50_evo_init(struct drm_device *dev) 385nv50_evo_init(struct drm_device *dev)
323{ 386{
324 struct nv50_display *disp = nv50_display(dev); 387 struct nv50_display *disp = nv50_display(dev);
325 int ret; 388 int ret, i;
326 389
327 if (!disp->master) { 390 if (!disp->master) {
328 ret = nv50_evo_create(dev); 391 ret = nv50_evo_create(dev);
@@ -330,15 +393,32 @@ nv50_evo_init(struct drm_device *dev)
330 return ret; 393 return ret;
331 } 394 }
332 395
333 return nv50_evo_channel_init(disp->master); 396 ret = nv50_evo_channel_init(disp->master);
397 if (ret)
398 return ret;
399
400 for (i = 0; i < 2; i++) {
401 ret = nv50_evo_channel_init(disp->crtc[i].sync);
402 if (ret)
403 return ret;
404 }
405
406 return 0;
334} 407}
335 408
336void 409void
337nv50_evo_fini(struct drm_device *dev) 410nv50_evo_fini(struct drm_device *dev)
338{ 411{
339 struct nv50_display *disp = nv50_display(dev); 412 struct nv50_display *disp = nv50_display(dev);
413 int i;
414
415 for (i = 0; i < 2; i++) {
416 if (disp->crtc[i].sync)
417 nv50_evo_channel_fini(disp->crtc[i].sync);
418 }
340 419
341 if (disp->master) 420 if (disp->master)
342 nv50_evo_channel_fini(disp->master); 421 nv50_evo_channel_fini(disp->master);
422
343 nv50_evo_destroy(dev); 423 nv50_evo_destroy(dev);
344} 424}