drm/nouveau/fifo: implement nvif event source
[linux-2.6-block.git] / drivers / gpu / drm / nouveau / nv50_display.c
CommitLineData
56d237d2 1/*
26f6d88b
BS
2 * Copyright 2011 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
51beb428 25#include <linux/dma-mapping.h>
83fc083c 26
760285e7
DH
27#include <drm/drmP.h>
28#include <drm/drm_crtc_helper.h>
4874322e 29#include <drm/drm_dp_helper.h>
26f6d88b 30
fdb751ef
BS
31#include <nvif/class.h>
32
77145f1c
BS
33#include "nouveau_drm.h"
34#include "nouveau_dma.h"
35#include "nouveau_gem.h"
26f6d88b
BS
36#include "nouveau_connector.h"
37#include "nouveau_encoder.h"
38#include "nouveau_crtc.h"
f589be88 39#include "nouveau_fence.h"
3a89cd02 40#include "nv50_display.h"
26f6d88b 41
8a46438a
BS
42#define EVO_DMA_NR 9
43
bdb8c212 44#define EVO_MASTER (0x00)
a63a97eb 45#define EVO_FLIP(c) (0x01 + (c))
8a46438a
BS
46#define EVO_OVLY(c) (0x05 + (c))
47#define EVO_OIMM(c) (0x09 + (c))
bdb8c212
BS
48#define EVO_CURS(c) (0x0d + (c))
49
816af2f2
BS
50/* offsets in shared sync bo of various structures */
51#define EVO_SYNC(c, o) ((c) * 0x0100 + (o))
9f9bdaaf
BS
52#define EVO_MAST_NTFY EVO_SYNC( 0, 0x00)
53#define EVO_FLIP_SEM0(c) EVO_SYNC((c) + 1, 0x00)
54#define EVO_FLIP_SEM1(c) EVO_SYNC((c) + 1, 0x10)
816af2f2 55
b5a794b0
BS
56#define EVO_CORE_HANDLE (0xd1500000)
57#define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i))
0ad72863 58#define EVO_CHAN_OCLASS(t,c) (((c)->oclass & 0xff00) | ((t) & 0x00ff))
b5a794b0
BS
59#define EVO_PUSH_HANDLE(t,i) (0xd15b0000 | (i) | \
60 (((NV50_DISP_##t##_CLASS) & 0x00ff) << 8))
61
62/******************************************************************************
63 * EVO channel
64 *****************************************************************************/
65
e225f446 66struct nv50_chan {
0ad72863 67 struct nvif_object user;
b5a794b0
BS
68};
69
70static int
0ad72863 71nv50_chan_create(struct nvif_object *disp, u32 bclass, u8 head,
e225f446 72 void *data, u32 size, struct nv50_chan *chan)
b5a794b0 73{
0ad72863 74 const u32 oclass = EVO_CHAN_OCLASS(bclass, disp);
b5a794b0
BS
75 const u32 handle = EVO_CHAN_HANDLE(bclass, head);
76 int ret;
77
0ad72863
BS
78 ret = nvif_object_init(disp, NULL, handle, oclass, data, size,
79 &chan->user);
b5a794b0
BS
80 if (ret)
81 return ret;
82
b5a794b0
BS
83 return 0;
84}
85
86static void
0ad72863 87nv50_chan_destroy(struct nv50_chan *chan)
b5a794b0 88{
0ad72863 89 nvif_object_fini(&chan->user);
b5a794b0
BS
90}
91
92/******************************************************************************
93 * PIO EVO channel
94 *****************************************************************************/
95
e225f446
BS
96struct nv50_pioc {
97 struct nv50_chan base;
b5a794b0
BS
98};
99
100static void
0ad72863 101nv50_pioc_destroy(struct nv50_pioc *pioc)
b5a794b0 102{
0ad72863 103 nv50_chan_destroy(&pioc->base);
b5a794b0
BS
104}
105
106static int
0ad72863 107nv50_pioc_create(struct nvif_object *disp, u32 bclass, u8 head,
e225f446 108 void *data, u32 size, struct nv50_pioc *pioc)
b5a794b0 109{
0ad72863 110 return nv50_chan_create(disp, bclass, head, data, size, &pioc->base);
b5a794b0
BS
111}
112
113/******************************************************************************
114 * DMA EVO channel
115 *****************************************************************************/
116
e225f446
BS
117struct nv50_dmac {
118 struct nv50_chan base;
3376ee37
BS
119 dma_addr_t handle;
120 u32 *ptr;
59ad1465 121
0ad72863
BS
122 struct nvif_object sync;
123 struct nvif_object vram;
124
59ad1465
DV
125 /* Protects against concurrent pushbuf access to this channel, lock is
126 * grabbed by evo_wait (if the pushbuf reservation is successful) and
127 * dropped again by evo_kick. */
128 struct mutex lock;
b5a794b0
BS
129};
130
131static void
0ad72863 132nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp)
b5a794b0 133{
0ad72863
BS
134 nvif_object_fini(&dmac->vram);
135 nvif_object_fini(&dmac->sync);
136
137 nv50_chan_destroy(&dmac->base);
138
b5a794b0 139 if (dmac->ptr) {
0ad72863 140 struct pci_dev *pdev = nvkm_device(nvif_device(disp))->pdev;
b5a794b0
BS
141 pci_free_consistent(pdev, PAGE_SIZE, dmac->ptr, dmac->handle);
142 }
b5a794b0
BS
143}
144
47057302 145static int
0ad72863 146nv50_dmac_create(struct nvif_object *disp, u32 bclass, u8 head,
47057302 147 void *data, u32 size, u64 syncbuf,
e225f446 148 struct nv50_dmac *dmac)
47057302 149{
0ad72863
BS
150 struct nouveau_fb *pfb = nvkm_fb(nvif_device(disp));
151 struct nvif_object pushbuf;
152 u32 handle = *(u32 *)data;
47057302
BS
153 int ret;
154
59ad1465
DV
155 mutex_init(&dmac->lock);
156
0ad72863
BS
157 dmac->ptr = pci_alloc_consistent(nvkm_device(nvif_device(disp))->pdev,
158 PAGE_SIZE, &dmac->handle);
47057302
BS
159 if (!dmac->ptr)
160 return -ENOMEM;
161
0ad72863 162 ret = nvif_object_init(nvif_object(nvif_device(disp)), NULL, handle,
4acfd707
BS
163 NV_DMA_FROM_MEMORY,
164 &(struct nv_dma_v0) {
165 .target = NV_DMA_V0_TARGET_PCI_US,
166 .access = NV_DMA_V0_ACCESS_RD,
47057302
BS
167 .start = dmac->handle + 0x0000,
168 .limit = dmac->handle + 0x0fff,
4acfd707 169 }, sizeof(struct nv_dma_v0), &pushbuf);
b5a794b0 170 if (ret)
47057302 171 return ret;
b5a794b0 172
0ad72863
BS
173 ret = nv50_chan_create(disp, bclass, head, data, size, &dmac->base);
174 nvif_object_fini(&pushbuf);
47057302
BS
175 if (ret)
176 return ret;
177
f45f55c4 178 ret = nvif_object_init(&dmac->base.user, NULL, 0xf0000000,
4acfd707
BS
179 NV_DMA_IN_MEMORY,
180 &(struct nv_dma_v0) {
181 .target = NV_DMA_V0_TARGET_VRAM,
182 .access = NV_DMA_V0_ACCESS_RDWR,
47057302
BS
183 .start = syncbuf + 0x0000,
184 .limit = syncbuf + 0x0fff,
4acfd707 185 }, sizeof(struct nv_dma_v0),
0ad72863 186 &dmac->sync);
47057302
BS
187 if (ret)
188 return ret;
189
f45f55c4 190 ret = nvif_object_init(&dmac->base.user, NULL, 0xf0000001,
4acfd707
BS
191 NV_DMA_IN_MEMORY,
192 &(struct nv_dma_v0) {
193 .target = NV_DMA_V0_TARGET_VRAM,
194 .access = NV_DMA_V0_ACCESS_RDWR,
b5a794b0 195 .start = 0,
dceef5d8 196 .limit = pfb->ram->size - 1,
4acfd707 197 }, sizeof(struct nv_dma_v0),
0ad72863 198 &dmac->vram);
b5a794b0 199 if (ret)
47057302
BS
200 return ret;
201
b5a794b0
BS
202 return ret;
203}
204
e225f446
BS
205struct nv50_mast {
206 struct nv50_dmac base;
b5a794b0
BS
207};
208
e225f446
BS
209struct nv50_curs {
210 struct nv50_pioc base;
b5a794b0
BS
211};
212
e225f446
BS
213struct nv50_sync {
214 struct nv50_dmac base;
9f9bdaaf
BS
215 u32 addr;
216 u32 data;
3376ee37
BS
217};
218
e225f446
BS
219struct nv50_ovly {
220 struct nv50_dmac base;
b5a794b0 221};
f20ce962 222
e225f446
BS
223struct nv50_oimm {
224 struct nv50_pioc base;
26f6d88b
BS
225};
226
e225f446 227struct nv50_head {
dd0e3d53 228 struct nouveau_crtc base;
8dda53fc 229 struct nouveau_bo *image;
e225f446
BS
230 struct nv50_curs curs;
231 struct nv50_sync sync;
232 struct nv50_ovly ovly;
233 struct nv50_oimm oimm;
b5a794b0
BS
234};
235
e225f446
BS
236#define nv50_head(c) ((struct nv50_head *)nouveau_crtc(c))
237#define nv50_curs(c) (&nv50_head(c)->curs)
238#define nv50_sync(c) (&nv50_head(c)->sync)
239#define nv50_ovly(c) (&nv50_head(c)->ovly)
240#define nv50_oimm(c) (&nv50_head(c)->oimm)
241#define nv50_chan(c) (&(c)->base.base)
0ad72863
BS
242#define nv50_vers(c) nv50_chan(c)->user.oclass
243
244struct nv50_fbdma {
245 struct list_head head;
246 struct nvif_object core;
247 struct nvif_object base[4];
248};
b5a794b0 249
e225f446 250struct nv50_disp {
0ad72863 251 struct nvif_object *disp;
e225f446 252 struct nv50_mast mast;
b5a794b0 253
8a423647 254 struct list_head fbdma;
b5a794b0
BS
255
256 struct nouveau_bo *sync;
dd0e3d53
BS
257};
258
e225f446
BS
259static struct nv50_disp *
260nv50_disp(struct drm_device *dev)
26f6d88b 261{
77145f1c 262 return nouveau_display(dev)->priv;
26f6d88b
BS
263}
264
e225f446 265#define nv50_mast(d) (&nv50_disp(d)->mast)
b5a794b0 266
bdb8c212 267static struct drm_crtc *
e225f446 268nv50_display_crtc_get(struct drm_encoder *encoder)
bdb8c212
BS
269{
270 return nouveau_encoder(encoder)->crtc;
271}
272
273/******************************************************************************
274 * EVO channel helpers
275 *****************************************************************************/
51beb428 276static u32 *
b5a794b0 277evo_wait(void *evoc, int nr)
51beb428 278{
e225f446 279 struct nv50_dmac *dmac = evoc;
0ad72863 280 u32 put = nvif_rd32(&dmac->base.user, 0x0000) / 4;
51beb428 281
59ad1465 282 mutex_lock(&dmac->lock);
de8268c5 283 if (put + nr >= (PAGE_SIZE / 4) - 8) {
b5a794b0 284 dmac->ptr[put] = 0x20000000;
51beb428 285
0ad72863
BS
286 nvif_wr32(&dmac->base.user, 0x0000, 0x00000000);
287 if (!nvkm_wait(&dmac->base.user, 0x0004, ~0, 0x00000000)) {
59ad1465 288 mutex_unlock(&dmac->lock);
0ad72863 289 nv_error(nvkm_object(&dmac->base.user), "channel stalled\n");
51beb428
BS
290 return NULL;
291 }
292
293 put = 0;
294 }
295
b5a794b0 296 return dmac->ptr + put;
51beb428
BS
297}
298
299static void
b5a794b0 300evo_kick(u32 *push, void *evoc)
51beb428 301{
e225f446 302 struct nv50_dmac *dmac = evoc;
0ad72863 303 nvif_wr32(&dmac->base.user, 0x0000, (push - dmac->ptr) << 2);
59ad1465 304 mutex_unlock(&dmac->lock);
51beb428
BS
305}
306
307#define evo_mthd(p,m,s) *((p)++) = (((s) << 18) | (m))
308#define evo_data(p,d) *((p)++) = (d)
309
3376ee37
BS
310static bool
311evo_sync_wait(void *data)
312{
5cc027f6
BS
313 if (nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000)
314 return true;
315 usleep_range(1, 2);
316 return false;
3376ee37
BS
317}
318
319static int
b5a794b0 320evo_sync(struct drm_device *dev)
3376ee37 321{
967e7bde 322 struct nvif_device *device = &nouveau_drm(dev)->device;
e225f446
BS
323 struct nv50_disp *disp = nv50_disp(dev);
324 struct nv50_mast *mast = nv50_mast(dev);
b5a794b0 325 u32 *push = evo_wait(mast, 8);
3376ee37 326 if (push) {
816af2f2 327 nouveau_bo_wr32(disp->sync, EVO_MAST_NTFY, 0x00000000);
3376ee37 328 evo_mthd(push, 0x0084, 1);
816af2f2 329 evo_data(push, 0x80000000 | EVO_MAST_NTFY);
3376ee37
BS
330 evo_mthd(push, 0x0080, 2);
331 evo_data(push, 0x00000000);
332 evo_data(push, 0x00000000);
b5a794b0 333 evo_kick(push, mast);
967e7bde 334 if (nv_wait_cb(nvkm_device(device), evo_sync_wait, disp->sync))
3376ee37
BS
335 return 0;
336 }
337
338 return -EBUSY;
339}
340
341/******************************************************************************
a63a97eb 342 * Page flipping channel
3376ee37
BS
343 *****************************************************************************/
344struct nouveau_bo *
e225f446 345nv50_display_crtc_sema(struct drm_device *dev, int crtc)
3376ee37 346{
e225f446 347 return nv50_disp(dev)->sync;
3376ee37
BS
348}
349
9f9bdaaf
BS
350struct nv50_display_flip {
351 struct nv50_disp *disp;
352 struct nv50_sync *chan;
353};
354
355static bool
356nv50_display_flip_wait(void *data)
357{
358 struct nv50_display_flip *flip = data;
359 if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) ==
b1ea3e6e 360 flip->chan->data)
9f9bdaaf
BS
361 return true;
362 usleep_range(1, 2);
363 return false;
364}
365
3376ee37 366void
e225f446 367nv50_display_flip_stop(struct drm_crtc *crtc)
3376ee37 368{
967e7bde 369 struct nvif_device *device = &nouveau_drm(crtc->dev)->device;
9f9bdaaf
BS
370 struct nv50_display_flip flip = {
371 .disp = nv50_disp(crtc->dev),
372 .chan = nv50_sync(crtc),
373 };
3376ee37
BS
374 u32 *push;
375
9f9bdaaf 376 push = evo_wait(flip.chan, 8);
3376ee37
BS
377 if (push) {
378 evo_mthd(push, 0x0084, 1);
379 evo_data(push, 0x00000000);
380 evo_mthd(push, 0x0094, 1);
381 evo_data(push, 0x00000000);
382 evo_mthd(push, 0x00c0, 1);
383 evo_data(push, 0x00000000);
384 evo_mthd(push, 0x0080, 1);
385 evo_data(push, 0x00000000);
9f9bdaaf 386 evo_kick(push, flip.chan);
3376ee37 387 }
9f9bdaaf 388
967e7bde 389 nv_wait_cb(nvkm_device(device), nv50_display_flip_wait, &flip);
3376ee37
BS
390}
391
392int
e225f446 393nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb,
3376ee37
BS
394 struct nouveau_channel *chan, u32 swap_interval)
395{
396 struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
3376ee37 397 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
8dda53fc 398 struct nv50_head *head = nv50_head(crtc);
e225f446 399 struct nv50_sync *sync = nv50_sync(crtc);
3376ee37 400 u32 *push;
8dda53fc 401 int ret;
3376ee37
BS
402
403 swap_interval <<= 4;
404 if (swap_interval == 0)
405 swap_interval |= 0x100;
f60b6e7a
BS
406 if (chan == NULL)
407 evo_sync(crtc->dev);
3376ee37 408
b5a794b0 409 push = evo_wait(sync, 128);
3376ee37
BS
410 if (unlikely(push == NULL))
411 return -EBUSY;
412
bbf8906b 413 if (chan && chan->object->oclass < G82_CHANNEL_GPFIFO) {
9f9bdaaf
BS
414 ret = RING_SPACE(chan, 8);
415 if (ret)
416 return ret;
417
418 BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2);
8dda53fc 419 OUT_RING (chan, NvEvoSema0 + nv_crtc->index);
9f9bdaaf
BS
420 OUT_RING (chan, sync->addr ^ 0x10);
421 BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1);
422 OUT_RING (chan, sync->data + 1);
423 BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2);
424 OUT_RING (chan, sync->addr);
425 OUT_RING (chan, sync->data);
426 } else
bbf8906b 427 if (chan && chan->object->oclass < FERMI_CHANNEL_GPFIFO) {
8dda53fc 428 u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr;
9f9bdaaf
BS
429 ret = RING_SPACE(chan, 12);
430 if (ret)
431 return ret;
432
433 BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1);
0ad72863 434 OUT_RING (chan, chan->vram.handle);
9f9bdaaf
BS
435 BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
436 OUT_RING (chan, upper_32_bits(addr ^ 0x10));
437 OUT_RING (chan, lower_32_bits(addr ^ 0x10));
438 OUT_RING (chan, sync->data + 1);
439 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG);
440 BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
441 OUT_RING (chan, upper_32_bits(addr));
442 OUT_RING (chan, lower_32_bits(addr));
443 OUT_RING (chan, sync->data);
444 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL);
445 } else
446 if (chan) {
8dda53fc 447 u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr;
9f9bdaaf
BS
448 ret = RING_SPACE(chan, 10);
449 if (ret)
450 return ret;
451
452 BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
453 OUT_RING (chan, upper_32_bits(addr ^ 0x10));
454 OUT_RING (chan, lower_32_bits(addr ^ 0x10));
455 OUT_RING (chan, sync->data + 1);
456 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG |
457 NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
458 BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4);
459 OUT_RING (chan, upper_32_bits(addr));
460 OUT_RING (chan, lower_32_bits(addr));
461 OUT_RING (chan, sync->data);
462 OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL |
463 NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD);
464 }
35bcf5d5 465
9f9bdaaf
BS
466 if (chan) {
467 sync->addr ^= 0x10;
468 sync->data++;
3376ee37 469 FIRE_RING (chan);
3376ee37
BS
470 }
471
472 /* queue the flip */
473 evo_mthd(push, 0x0100, 1);
474 evo_data(push, 0xfffe0000);
475 evo_mthd(push, 0x0084, 1);
476 evo_data(push, swap_interval);
477 if (!(swap_interval & 0x00000100)) {
478 evo_mthd(push, 0x00e0, 1);
479 evo_data(push, 0x40000000);
480 }
481 evo_mthd(push, 0x0088, 4);
9f9bdaaf
BS
482 evo_data(push, sync->addr);
483 evo_data(push, sync->data++);
484 evo_data(push, sync->data);
f45f55c4 485 evo_data(push, sync->base.sync.handle);
3376ee37
BS
486 evo_mthd(push, 0x00a0, 2);
487 evo_data(push, 0x00000000);
488 evo_data(push, 0x00000000);
489 evo_mthd(push, 0x00c0, 1);
8a423647 490 evo_data(push, nv_fb->r_handle);
3376ee37
BS
491 evo_mthd(push, 0x0110, 2);
492 evo_data(push, 0x00000000);
493 evo_data(push, 0x00000000);
e225f446 494 if (nv50_vers(sync) < NVD0_DISP_SYNC_CLASS) {
ed5085a5
BS
495 evo_mthd(push, 0x0800, 5);
496 evo_data(push, nv_fb->nvbo->bo.offset >> 8);
497 evo_data(push, 0);
498 evo_data(push, (fb->height << 16) | fb->width);
499 evo_data(push, nv_fb->r_pitch);
500 evo_data(push, nv_fb->r_format);
501 } else {
502 evo_mthd(push, 0x0400, 5);
503 evo_data(push, nv_fb->nvbo->bo.offset >> 8);
504 evo_data(push, 0);
505 evo_data(push, (fb->height << 16) | fb->width);
506 evo_data(push, nv_fb->r_pitch);
507 evo_data(push, nv_fb->r_format);
508 }
3376ee37
BS
509 evo_mthd(push, 0x0080, 1);
510 evo_data(push, 0x00000000);
b5a794b0 511 evo_kick(push, sync);
8dda53fc
BS
512
513 nouveau_bo_ref(nv_fb->nvbo, &head->image);
3376ee37
BS
514 return 0;
515}
516
438d99e3
BS
517/******************************************************************************
518 * CRTC
519 *****************************************************************************/
520static int
e225f446 521nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update)
438d99e3 522{
e225f446 523 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
de691855
BS
524 struct nouveau_connector *nv_connector;
525 struct drm_connector *connector;
526 u32 *push, mode = 0x00;
438d99e3 527
488ff207 528 nv_connector = nouveau_crtc_connector_get(nv_crtc);
de691855
BS
529 connector = &nv_connector->base;
530 if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) {
f4510a27 531 if (nv_crtc->base.primary->fb->depth > connector->display_info.bpc * 3)
de691855
BS
532 mode = DITHERING_MODE_DYNAMIC2X2;
533 } else {
534 mode = nv_connector->dithering_mode;
535 }
536
537 if (nv_connector->dithering_depth == DITHERING_DEPTH_AUTO) {
538 if (connector->display_info.bpc >= 8)
539 mode |= DITHERING_DEPTH_8BPC;
540 } else {
541 mode |= nv_connector->dithering_depth;
438d99e3
BS
542 }
543
de8268c5 544 push = evo_wait(mast, 4);
438d99e3 545 if (push) {
e225f446 546 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5
BS
547 evo_mthd(push, 0x08a0 + (nv_crtc->index * 0x0400), 1);
548 evo_data(push, mode);
549 } else
e225f446 550 if (nv50_vers(mast) < NVE0_DISP_MAST_CLASS) {
de8268c5
BS
551 evo_mthd(push, 0x0490 + (nv_crtc->index * 0x0300), 1);
552 evo_data(push, mode);
553 } else {
554 evo_mthd(push, 0x04a0 + (nv_crtc->index * 0x0300), 1);
555 evo_data(push, mode);
556 }
557
438d99e3
BS
558 if (update) {
559 evo_mthd(push, 0x0080, 1);
560 evo_data(push, 0x00000000);
561 }
de8268c5 562 evo_kick(push, mast);
438d99e3
BS
563 }
564
565 return 0;
566}
567
568static int
e225f446 569nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
438d99e3 570{
e225f446 571 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
92854622 572 struct drm_display_mode *omode, *umode = &nv_crtc->base.mode;
3376ee37 573 struct drm_crtc *crtc = &nv_crtc->base;
f3fdc52d 574 struct nouveau_connector *nv_connector;
92854622
BS
575 int mode = DRM_MODE_SCALE_NONE;
576 u32 oX, oY, *push;
f3fdc52d 577
92854622
BS
578 /* start off at the resolution we programmed the crtc for, this
579 * effectively handles NONE/FULL scaling
580 */
f3fdc52d 581 nv_connector = nouveau_crtc_connector_get(nv_crtc);
92854622
BS
582 if (nv_connector && nv_connector->native_mode)
583 mode = nv_connector->scaling_mode;
584
585 if (mode != DRM_MODE_SCALE_NONE)
586 omode = nv_connector->native_mode;
587 else
588 omode = umode;
589
590 oX = omode->hdisplay;
591 oY = omode->vdisplay;
592 if (omode->flags & DRM_MODE_FLAG_DBLSCAN)
593 oY *= 2;
594
595 /* add overscan compensation if necessary, will keep the aspect
596 * ratio the same as the backend mode unless overridden by the
597 * user setting both hborder and vborder properties.
598 */
599 if (nv_connector && ( nv_connector->underscan == UNDERSCAN_ON ||
600 (nv_connector->underscan == UNDERSCAN_AUTO &&
601 nv_connector->edid &&
602 drm_detect_hdmi_monitor(nv_connector->edid)))) {
603 u32 bX = nv_connector->underscan_hborder;
604 u32 bY = nv_connector->underscan_vborder;
605 u32 aspect = (oY << 19) / oX;
606
607 if (bX) {
608 oX -= (bX * 2);
609 if (bY) oY -= (bY * 2);
610 else oY = ((oX * aspect) + (aspect / 2)) >> 19;
611 } else {
612 oX -= (oX >> 4) + 32;
613 if (bY) oY -= (bY * 2);
614 else oY = ((oX * aspect) + (aspect / 2)) >> 19;
615 }
616 }
617
618 /* handle CENTER/ASPECT scaling, taking into account the areas
619 * removed already for overscan compensation
620 */
621 switch (mode) {
622 case DRM_MODE_SCALE_CENTER:
623 oX = min((u32)umode->hdisplay, oX);
624 oY = min((u32)umode->vdisplay, oY);
625 /* fall-through */
626 case DRM_MODE_SCALE_ASPECT:
627 if (oY < oX) {
628 u32 aspect = (umode->hdisplay << 19) / umode->vdisplay;
629 oX = ((oY * aspect) + (aspect / 2)) >> 19;
630 } else {
631 u32 aspect = (umode->vdisplay << 19) / umode->hdisplay;
632 oY = ((oX * aspect) + (aspect / 2)) >> 19;
f3fdc52d 633 }
92854622
BS
634 break;
635 default:
636 break;
f3fdc52d 637 }
438d99e3 638
de8268c5 639 push = evo_wait(mast, 8);
438d99e3 640 if (push) {
e225f446 641 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5
BS
642 /*XXX: SCALE_CTRL_ACTIVE??? */
643 evo_mthd(push, 0x08d8 + (nv_crtc->index * 0x400), 2);
644 evo_data(push, (oY << 16) | oX);
645 evo_data(push, (oY << 16) | oX);
646 evo_mthd(push, 0x08a4 + (nv_crtc->index * 0x400), 1);
647 evo_data(push, 0x00000000);
648 evo_mthd(push, 0x08c8 + (nv_crtc->index * 0x400), 1);
649 evo_data(push, umode->vdisplay << 16 | umode->hdisplay);
650 } else {
651 evo_mthd(push, 0x04c0 + (nv_crtc->index * 0x300), 3);
652 evo_data(push, (oY << 16) | oX);
653 evo_data(push, (oY << 16) | oX);
654 evo_data(push, (oY << 16) | oX);
655 evo_mthd(push, 0x0494 + (nv_crtc->index * 0x300), 1);
656 evo_data(push, 0x00000000);
657 evo_mthd(push, 0x04b8 + (nv_crtc->index * 0x300), 1);
658 evo_data(push, umode->vdisplay << 16 | umode->hdisplay);
659 }
660
661 evo_kick(push, mast);
662
438d99e3 663 if (update) {
e225f446 664 nv50_display_flip_stop(crtc);
f4510a27
MR
665 nv50_display_flip_next(crtc, crtc->primary->fb,
666 NULL, 1);
438d99e3 667 }
438d99e3
BS
668 }
669
670 return 0;
671}
672
f9887d09 673static int
e225f446 674nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update)
f9887d09 675{
e225f446 676 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
f9887d09
BS
677 u32 *push, hue, vib;
678 int adj;
679
680 adj = (nv_crtc->color_vibrance > 0) ? 50 : 0;
681 vib = ((nv_crtc->color_vibrance * 2047 + adj) / 100) & 0xfff;
682 hue = ((nv_crtc->vibrant_hue * 2047) / 100) & 0xfff;
683
684 push = evo_wait(mast, 16);
685 if (push) {
e225f446 686 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
f9887d09
BS
687 evo_mthd(push, 0x08a8 + (nv_crtc->index * 0x400), 1);
688 evo_data(push, (hue << 20) | (vib << 8));
689 } else {
690 evo_mthd(push, 0x0498 + (nv_crtc->index * 0x300), 1);
691 evo_data(push, (hue << 20) | (vib << 8));
692 }
693
694 if (update) {
695 evo_mthd(push, 0x0080, 1);
696 evo_data(push, 0x00000000);
697 }
698 evo_kick(push, mast);
699 }
700
701 return 0;
702}
703
438d99e3 704static int
e225f446 705nv50_crtc_set_image(struct nouveau_crtc *nv_crtc, struct drm_framebuffer *fb,
438d99e3
BS
706 int x, int y, bool update)
707{
708 struct nouveau_framebuffer *nvfb = nouveau_framebuffer(fb);
e225f446 709 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
438d99e3
BS
710 u32 *push;
711
de8268c5 712 push = evo_wait(mast, 16);
438d99e3 713 if (push) {
e225f446 714 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5
BS
715 evo_mthd(push, 0x0860 + (nv_crtc->index * 0x400), 1);
716 evo_data(push, nvfb->nvbo->bo.offset >> 8);
717 evo_mthd(push, 0x0868 + (nv_crtc->index * 0x400), 3);
718 evo_data(push, (fb->height << 16) | fb->width);
719 evo_data(push, nvfb->r_pitch);
720 evo_data(push, nvfb->r_format);
721 evo_mthd(push, 0x08c0 + (nv_crtc->index * 0x400), 1);
722 evo_data(push, (y << 16) | x);
e225f446 723 if (nv50_vers(mast) > NV50_DISP_MAST_CLASS) {
de8268c5 724 evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1);
8a423647 725 evo_data(push, nvfb->r_handle);
de8268c5
BS
726 }
727 } else {
728 evo_mthd(push, 0x0460 + (nv_crtc->index * 0x300), 1);
729 evo_data(push, nvfb->nvbo->bo.offset >> 8);
730 evo_mthd(push, 0x0468 + (nv_crtc->index * 0x300), 4);
731 evo_data(push, (fb->height << 16) | fb->width);
732 evo_data(push, nvfb->r_pitch);
733 evo_data(push, nvfb->r_format);
8a423647 734 evo_data(push, nvfb->r_handle);
de8268c5
BS
735 evo_mthd(push, 0x04b0 + (nv_crtc->index * 0x300), 1);
736 evo_data(push, (y << 16) | x);
737 }
738
a46232ee
BS
739 if (update) {
740 evo_mthd(push, 0x0080, 1);
741 evo_data(push, 0x00000000);
742 }
de8268c5 743 evo_kick(push, mast);
438d99e3
BS
744 }
745
8a423647 746 nv_crtc->fb.handle = nvfb->r_handle;
438d99e3
BS
747 return 0;
748}
749
750static void
e225f446 751nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc)
438d99e3 752{
e225f446 753 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
de8268c5 754 u32 *push = evo_wait(mast, 16);
438d99e3 755 if (push) {
e225f446 756 if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) {
de8268c5
BS
757 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
758 evo_data(push, 0x85000000);
759 evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
760 } else
e225f446 761 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5
BS
762 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2);
763 evo_data(push, 0x85000000);
764 evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
765 evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1);
f45f55c4 766 evo_data(push, mast->base.vram.handle);
de8268c5 767 } else {
438d99e3
BS
768 evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2);
769 evo_data(push, 0x85000000);
770 evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
771 evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
f45f55c4 772 evo_data(push, mast->base.vram.handle);
de8268c5
BS
773 }
774 evo_kick(push, mast);
775 }
776}
777
778static void
e225f446 779nv50_crtc_cursor_hide(struct nouveau_crtc *nv_crtc)
de8268c5 780{
e225f446 781 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
de8268c5
BS
782 u32 *push = evo_wait(mast, 16);
783 if (push) {
e225f446 784 if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) {
de8268c5
BS
785 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 1);
786 evo_data(push, 0x05000000);
787 } else
e225f446 788 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5
BS
789 evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 1);
790 evo_data(push, 0x05000000);
791 evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1);
792 evo_data(push, 0x00000000);
438d99e3
BS
793 } else {
794 evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 1);
795 evo_data(push, 0x05000000);
796 evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
797 evo_data(push, 0x00000000);
798 }
de8268c5
BS
799 evo_kick(push, mast);
800 }
801}
438d99e3 802
de8268c5 803static void
e225f446 804nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update)
de8268c5 805{
e225f446 806 struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev);
de8268c5
BS
807
808 if (show)
e225f446 809 nv50_crtc_cursor_show(nv_crtc);
de8268c5 810 else
e225f446 811 nv50_crtc_cursor_hide(nv_crtc);
de8268c5
BS
812
813 if (update) {
814 u32 *push = evo_wait(mast, 2);
815 if (push) {
438d99e3
BS
816 evo_mthd(push, 0x0080, 1);
817 evo_data(push, 0x00000000);
de8268c5 818 evo_kick(push, mast);
438d99e3 819 }
438d99e3
BS
820 }
821}
822
823static void
e225f446 824nv50_crtc_dpms(struct drm_crtc *crtc, int mode)
438d99e3
BS
825{
826}
827
828static void
e225f446 829nv50_crtc_prepare(struct drm_crtc *crtc)
438d99e3
BS
830{
831 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
e225f446 832 struct nv50_mast *mast = nv50_mast(crtc->dev);
438d99e3
BS
833 u32 *push;
834
e225f446 835 nv50_display_flip_stop(crtc);
3376ee37 836
56d237d2 837 push = evo_wait(mast, 6);
438d99e3 838 if (push) {
e225f446 839 if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) {
de8268c5
BS
840 evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1);
841 evo_data(push, 0x00000000);
842 evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 1);
843 evo_data(push, 0x40000000);
844 } else
e225f446 845 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5
BS
846 evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1);
847 evo_data(push, 0x00000000);
848 evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 1);
849 evo_data(push, 0x40000000);
850 evo_mthd(push, 0x085c + (nv_crtc->index * 0x400), 1);
851 evo_data(push, 0x00000000);
852 } else {
853 evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1);
854 evo_data(push, 0x00000000);
855 evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 1);
856 evo_data(push, 0x03000000);
857 evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1);
858 evo_data(push, 0x00000000);
859 }
860
861 evo_kick(push, mast);
438d99e3
BS
862 }
863
e225f446 864 nv50_crtc_cursor_show_hide(nv_crtc, false, false);
438d99e3
BS
865}
866
867static void
e225f446 868nv50_crtc_commit(struct drm_crtc *crtc)
438d99e3
BS
869{
870 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
e225f446 871 struct nv50_mast *mast = nv50_mast(crtc->dev);
438d99e3
BS
872 u32 *push;
873
de8268c5 874 push = evo_wait(mast, 32);
438d99e3 875 if (push) {
e225f446 876 if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) {
de8268c5 877 evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1);
8a423647 878 evo_data(push, nv_crtc->fb.handle);
de8268c5
BS
879 evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 2);
880 evo_data(push, 0xc0000000);
881 evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8);
882 } else
e225f446 883 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5 884 evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1);
8a423647 885 evo_data(push, nv_crtc->fb.handle);
de8268c5
BS
886 evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 2);
887 evo_data(push, 0xc0000000);
888 evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8);
889 evo_mthd(push, 0x085c + (nv_crtc->index * 0x400), 1);
f45f55c4 890 evo_data(push, mast->base.vram.handle);
de8268c5
BS
891 } else {
892 evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1);
8a423647 893 evo_data(push, nv_crtc->fb.handle);
de8268c5
BS
894 evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 4);
895 evo_data(push, 0x83000000);
896 evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8);
897 evo_data(push, 0x00000000);
898 evo_data(push, 0x00000000);
899 evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1);
f45f55c4 900 evo_data(push, mast->base.vram.handle);
de8268c5
BS
901 evo_mthd(push, 0x0430 + (nv_crtc->index * 0x300), 1);
902 evo_data(push, 0xffffff00);
903 }
904
905 evo_kick(push, mast);
438d99e3
BS
906 }
907
e225f446 908 nv50_crtc_cursor_show_hide(nv_crtc, nv_crtc->cursor.visible, true);
f4510a27 909 nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1);
438d99e3
BS
910}
911
912static bool
e225f446 913nv50_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode,
438d99e3
BS
914 struct drm_display_mode *adjusted_mode)
915{
eb2e9686 916 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
438d99e3
BS
917 return true;
918}
919
920static int
e225f446 921nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
438d99e3 922{
f4510a27 923 struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb);
8dda53fc 924 struct nv50_head *head = nv50_head(crtc);
438d99e3
BS
925 int ret;
926
927 ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM);
8dda53fc
BS
928 if (ret == 0) {
929 if (head->image)
930 nouveau_bo_unpin(head->image);
931 nouveau_bo_ref(nvfb->nvbo, &head->image);
438d99e3
BS
932 }
933
8dda53fc 934 return ret;
438d99e3
BS
935}
936
937static int
e225f446 938nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
438d99e3
BS
939 struct drm_display_mode *mode, int x, int y,
940 struct drm_framebuffer *old_fb)
941{
e225f446 942 struct nv50_mast *mast = nv50_mast(crtc->dev);
438d99e3
BS
943 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
944 struct nouveau_connector *nv_connector;
2d1d898b
BS
945 u32 ilace = (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 1;
946 u32 vscan = (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 2 : 1;
947 u32 hactive, hsynce, hbackp, hfrontp, hblanke, hblanks;
948 u32 vactive, vsynce, vbackp, vfrontp, vblanke, vblanks;
949 u32 vblan2e = 0, vblan2s = 1;
3488c57b 950 u32 *push;
438d99e3
BS
951 int ret;
952
2d1d898b
BS
953 hactive = mode->htotal;
954 hsynce = mode->hsync_end - mode->hsync_start - 1;
955 hbackp = mode->htotal - mode->hsync_end;
956 hblanke = hsynce + hbackp;
957 hfrontp = mode->hsync_start - mode->hdisplay;
958 hblanks = mode->htotal - hfrontp - 1;
959
960 vactive = mode->vtotal * vscan / ilace;
961 vsynce = ((mode->vsync_end - mode->vsync_start) * vscan / ilace) - 1;
962 vbackp = (mode->vtotal - mode->vsync_end) * vscan / ilace;
963 vblanke = vsynce + vbackp;
964 vfrontp = (mode->vsync_start - mode->vdisplay) * vscan / ilace;
965 vblanks = vactive - vfrontp - 1;
966 if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
967 vblan2e = vactive + vsynce + vbackp;
968 vblan2s = vblan2e + (mode->vdisplay * vscan / ilace);
969 vactive = (vactive * 2) + 1;
2d1d898b
BS
970 }
971
e225f446 972 ret = nv50_crtc_swap_fbs(crtc, old_fb);
438d99e3
BS
973 if (ret)
974 return ret;
975
de8268c5 976 push = evo_wait(mast, 64);
438d99e3 977 if (push) {
e225f446 978 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
de8268c5
BS
979 evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2);
980 evo_data(push, 0x00800000 | mode->clock);
981 evo_data(push, (ilace == 2) ? 2 : 0);
982 evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6);
983 evo_data(push, 0x00000000);
984 evo_data(push, (vactive << 16) | hactive);
985 evo_data(push, ( vsynce << 16) | hsynce);
986 evo_data(push, (vblanke << 16) | hblanke);
987 evo_data(push, (vblanks << 16) | hblanks);
988 evo_data(push, (vblan2e << 16) | vblan2s);
989 evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1);
990 evo_data(push, 0x00000000);
991 evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2);
992 evo_data(push, 0x00000311);
993 evo_data(push, 0x00000100);
994 } else {
995 evo_mthd(push, 0x0410 + (nv_crtc->index * 0x300), 6);
996 evo_data(push, 0x00000000);
997 evo_data(push, (vactive << 16) | hactive);
998 evo_data(push, ( vsynce << 16) | hsynce);
999 evo_data(push, (vblanke << 16) | hblanke);
1000 evo_data(push, (vblanks << 16) | hblanks);
1001 evo_data(push, (vblan2e << 16) | vblan2s);
1002 evo_mthd(push, 0x042c + (nv_crtc->index * 0x300), 1);
1003 evo_data(push, 0x00000000); /* ??? */
1004 evo_mthd(push, 0x0450 + (nv_crtc->index * 0x300), 3);
1005 evo_data(push, mode->clock * 1000);
1006 evo_data(push, 0x00200000); /* ??? */
1007 evo_data(push, mode->clock * 1000);
1008 evo_mthd(push, 0x04d0 + (nv_crtc->index * 0x300), 2);
1009 evo_data(push, 0x00000311);
1010 evo_data(push, 0x00000100);
1011 }
1012
1013 evo_kick(push, mast);
438d99e3
BS
1014 }
1015
1016 nv_connector = nouveau_crtc_connector_get(nv_crtc);
e225f446
BS
1017 nv50_crtc_set_dither(nv_crtc, false);
1018 nv50_crtc_set_scale(nv_crtc, false);
1019 nv50_crtc_set_color_vibrance(nv_crtc, false);
f4510a27 1020 nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false);
438d99e3
BS
1021 return 0;
1022}
1023
1024static int
e225f446 1025nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
438d99e3
BS
1026 struct drm_framebuffer *old_fb)
1027{
77145f1c 1028 struct nouveau_drm *drm = nouveau_drm(crtc->dev);
438d99e3
BS
1029 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
1030 int ret;
1031
f4510a27 1032 if (!crtc->primary->fb) {
77145f1c 1033 NV_DEBUG(drm, "No FB bound\n");
84e2ad8b
BS
1034 return 0;
1035 }
1036
e225f446 1037 ret = nv50_crtc_swap_fbs(crtc, old_fb);
438d99e3
BS
1038 if (ret)
1039 return ret;
1040
e225f446 1041 nv50_display_flip_stop(crtc);
f4510a27
MR
1042 nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, true);
1043 nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1);
438d99e3
BS
1044 return 0;
1045}
1046
1047static int
e225f446 1048nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
438d99e3
BS
1049 struct drm_framebuffer *fb, int x, int y,
1050 enum mode_set_atomic state)
1051{
1052 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
e225f446
BS
1053 nv50_display_flip_stop(crtc);
1054 nv50_crtc_set_image(nv_crtc, fb, x, y, true);
438d99e3
BS
1055 return 0;
1056}
1057
1058static void
e225f446 1059nv50_crtc_lut_load(struct drm_crtc *crtc)
438d99e3 1060{
e225f446 1061 struct nv50_disp *disp = nv50_disp(crtc->dev);
438d99e3
BS
1062 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
1063 void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
1064 int i;
1065
1066 for (i = 0; i < 256; i++) {
de8268c5
BS
1067 u16 r = nv_crtc->lut.r[i] >> 2;
1068 u16 g = nv_crtc->lut.g[i] >> 2;
1069 u16 b = nv_crtc->lut.b[i] >> 2;
1070
0ad72863 1071 if (disp->disp->oclass < NVD0_DISP_CLASS) {
de8268c5
BS
1072 writew(r + 0x0000, lut + (i * 0x08) + 0);
1073 writew(g + 0x0000, lut + (i * 0x08) + 2);
1074 writew(b + 0x0000, lut + (i * 0x08) + 4);
1075 } else {
1076 writew(r + 0x6000, lut + (i * 0x20) + 0);
1077 writew(g + 0x6000, lut + (i * 0x20) + 2);
1078 writew(b + 0x6000, lut + (i * 0x20) + 4);
1079 }
438d99e3
BS
1080 }
1081}
1082
8dda53fc
BS
1083static void
1084nv50_crtc_disable(struct drm_crtc *crtc)
1085{
1086 struct nv50_head *head = nv50_head(crtc);
efa366fd 1087 evo_sync(crtc->dev);
8dda53fc
BS
1088 if (head->image)
1089 nouveau_bo_unpin(head->image);
1090 nouveau_bo_ref(NULL, &head->image);
1091}
1092
438d99e3 1093static int
e225f446 1094nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
438d99e3
BS
1095 uint32_t handle, uint32_t width, uint32_t height)
1096{
1097 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
1098 struct drm_device *dev = crtc->dev;
1099 struct drm_gem_object *gem;
1100 struct nouveau_bo *nvbo;
1101 bool visible = (handle != 0);
1102 int i, ret = 0;
1103
1104 if (visible) {
1105 if (width != 64 || height != 64)
1106 return -EINVAL;
1107
1108 gem = drm_gem_object_lookup(dev, file_priv, handle);
1109 if (unlikely(!gem))
1110 return -ENOENT;
1111 nvbo = nouveau_gem_object(gem);
1112
1113 ret = nouveau_bo_map(nvbo);
1114 if (ret == 0) {
1115 for (i = 0; i < 64 * 64; i++) {
1116 u32 v = nouveau_bo_rd32(nvbo, i);
1117 nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, v);
1118 }
1119 nouveau_bo_unmap(nvbo);
1120 }
1121
1122 drm_gem_object_unreference_unlocked(gem);
1123 }
1124
1125 if (visible != nv_crtc->cursor.visible) {
e225f446 1126 nv50_crtc_cursor_show_hide(nv_crtc, visible, true);
438d99e3
BS
1127 nv_crtc->cursor.visible = visible;
1128 }
1129
1130 return ret;
1131}
1132
1133static int
e225f446 1134nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
438d99e3 1135{
e225f446
BS
1136 struct nv50_curs *curs = nv50_curs(crtc);
1137 struct nv50_chan *chan = nv50_chan(curs);
0ad72863
BS
1138 nvif_wr32(&chan->user, 0x0084, (y << 16) | (x & 0xffff));
1139 nvif_wr32(&chan->user, 0x0080, 0x00000000);
438d99e3
BS
1140 return 0;
1141}
1142
1143static void
e225f446 1144nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
438d99e3
BS
1145 uint32_t start, uint32_t size)
1146{
1147 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
bdefc8cb 1148 u32 end = min_t(u32, start + size, 256);
438d99e3
BS
1149 u32 i;
1150
1151 for (i = start; i < end; i++) {
1152 nv_crtc->lut.r[i] = r[i];
1153 nv_crtc->lut.g[i] = g[i];
1154 nv_crtc->lut.b[i] = b[i];
1155 }
1156
e225f446 1157 nv50_crtc_lut_load(crtc);
438d99e3
BS
1158}
1159
1160static void
e225f446 1161nv50_crtc_destroy(struct drm_crtc *crtc)
438d99e3
BS
1162{
1163 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
e225f446
BS
1164 struct nv50_disp *disp = nv50_disp(crtc->dev);
1165 struct nv50_head *head = nv50_head(crtc);
0ad72863 1166 struct nv50_fbdma *fbdma;
8dda53fc 1167
0ad72863
BS
1168 list_for_each_entry(fbdma, &disp->fbdma, head) {
1169 nvif_object_fini(&fbdma->base[nv_crtc->index]);
1170 }
1171
1172 nv50_dmac_destroy(&head->ovly.base, disp->disp);
1173 nv50_pioc_destroy(&head->oimm.base);
1174 nv50_dmac_destroy(&head->sync.base, disp->disp);
1175 nv50_pioc_destroy(&head->curs.base);
8dda53fc
BS
1176
1177 /*XXX: this shouldn't be necessary, but the core doesn't call
1178 * disconnect() during the cleanup paths
1179 */
1180 if (head->image)
1181 nouveau_bo_unpin(head->image);
1182 nouveau_bo_ref(NULL, &head->image);
1183
438d99e3 1184 nouveau_bo_unmap(nv_crtc->cursor.nvbo);
04c8c210
MS
1185 if (nv_crtc->cursor.nvbo)
1186 nouveau_bo_unpin(nv_crtc->cursor.nvbo);
438d99e3 1187 nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
8dda53fc 1188
438d99e3 1189 nouveau_bo_unmap(nv_crtc->lut.nvbo);
04c8c210
MS
1190 if (nv_crtc->lut.nvbo)
1191 nouveau_bo_unpin(nv_crtc->lut.nvbo);
438d99e3 1192 nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
8dda53fc 1193
438d99e3
BS
1194 drm_crtc_cleanup(crtc);
1195 kfree(crtc);
1196}
1197
e225f446
BS
1198static const struct drm_crtc_helper_funcs nv50_crtc_hfunc = {
1199 .dpms = nv50_crtc_dpms,
1200 .prepare = nv50_crtc_prepare,
1201 .commit = nv50_crtc_commit,
1202 .mode_fixup = nv50_crtc_mode_fixup,
1203 .mode_set = nv50_crtc_mode_set,
1204 .mode_set_base = nv50_crtc_mode_set_base,
1205 .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic,
1206 .load_lut = nv50_crtc_lut_load,
8dda53fc 1207 .disable = nv50_crtc_disable,
438d99e3
BS
1208};
1209
e225f446
BS
1210static const struct drm_crtc_funcs nv50_crtc_func = {
1211 .cursor_set = nv50_crtc_cursor_set,
1212 .cursor_move = nv50_crtc_cursor_move,
1213 .gamma_set = nv50_crtc_gamma_set,
5addcf0a 1214 .set_config = nouveau_crtc_set_config,
e225f446 1215 .destroy = nv50_crtc_destroy,
3376ee37 1216 .page_flip = nouveau_crtc_page_flip,
438d99e3
BS
1217};
1218
c20ab3e1 1219static void
e225f446 1220nv50_cursor_set_pos(struct nouveau_crtc *nv_crtc, int x, int y)
c20ab3e1
BS
1221{
1222}
1223
1224static void
e225f446 1225nv50_cursor_set_offset(struct nouveau_crtc *nv_crtc, uint32_t offset)
c20ab3e1
BS
1226{
1227}
1228
438d99e3 1229static int
0ad72863 1230nv50_crtc_create(struct drm_device *dev, int index)
438d99e3 1231{
e225f446
BS
1232 struct nv50_disp *disp = nv50_disp(dev);
1233 struct nv50_head *head;
438d99e3
BS
1234 struct drm_crtc *crtc;
1235 int ret, i;
1236
dd0e3d53
BS
1237 head = kzalloc(sizeof(*head), GFP_KERNEL);
1238 if (!head)
438d99e3
BS
1239 return -ENOMEM;
1240
dd0e3d53 1241 head->base.index = index;
e225f446
BS
1242 head->base.set_dither = nv50_crtc_set_dither;
1243 head->base.set_scale = nv50_crtc_set_scale;
1244 head->base.set_color_vibrance = nv50_crtc_set_color_vibrance;
f9887d09
BS
1245 head->base.color_vibrance = 50;
1246 head->base.vibrant_hue = 0;
e225f446
BS
1247 head->base.cursor.set_offset = nv50_cursor_set_offset;
1248 head->base.cursor.set_pos = nv50_cursor_set_pos;
438d99e3 1249 for (i = 0; i < 256; i++) {
dd0e3d53
BS
1250 head->base.lut.r[i] = i << 8;
1251 head->base.lut.g[i] = i << 8;
1252 head->base.lut.b[i] = i << 8;
438d99e3
BS
1253 }
1254
dd0e3d53 1255 crtc = &head->base.base;
e225f446
BS
1256 drm_crtc_init(dev, crtc, &nv50_crtc_func);
1257 drm_crtc_helper_add(crtc, &nv50_crtc_hfunc);
438d99e3
BS
1258 drm_mode_crtc_set_gamma_size(crtc, 256);
1259
b5a794b0
BS
1260 ret = nouveau_bo_new(dev, 8192, 0x100, TTM_PL_FLAG_VRAM,
1261 0, 0x0000, NULL, &head->base.lut.nvbo);
1262 if (!ret) {
1263 ret = nouveau_bo_pin(head->base.lut.nvbo, TTM_PL_FLAG_VRAM);
04c8c210 1264 if (!ret) {
b5a794b0 1265 ret = nouveau_bo_map(head->base.lut.nvbo);
04c8c210
MS
1266 if (ret)
1267 nouveau_bo_unpin(head->base.lut.nvbo);
1268 }
b5a794b0
BS
1269 if (ret)
1270 nouveau_bo_ref(NULL, &head->base.lut.nvbo);
1271 }
1272
1273 if (ret)
1274 goto out;
1275
e225f446 1276 nv50_crtc_lut_load(crtc);
b5a794b0
BS
1277
1278 /* allocate cursor resources */
0ad72863 1279 ret = nv50_pioc_create(disp->disp, NV50_DISP_CURS_CLASS, index,
b5a794b0
BS
1280 &(struct nv50_display_curs_class) {
1281 .head = index,
1282 }, sizeof(struct nv50_display_curs_class),
1283 &head->curs.base);
1284 if (ret)
1285 goto out;
1286
438d99e3 1287 ret = nouveau_bo_new(dev, 64 * 64 * 4, 0x100, TTM_PL_FLAG_VRAM,
dd0e3d53 1288 0, 0x0000, NULL, &head->base.cursor.nvbo);
438d99e3 1289 if (!ret) {
dd0e3d53 1290 ret = nouveau_bo_pin(head->base.cursor.nvbo, TTM_PL_FLAG_VRAM);
04c8c210 1291 if (!ret) {
dd0e3d53 1292 ret = nouveau_bo_map(head->base.cursor.nvbo);
04c8c210
MS
1293 if (ret)
1294 nouveau_bo_unpin(head->base.lut.nvbo);
1295 }
438d99e3 1296 if (ret)
dd0e3d53 1297 nouveau_bo_ref(NULL, &head->base.cursor.nvbo);
438d99e3
BS
1298 }
1299
1300 if (ret)
1301 goto out;
1302
b5a794b0 1303 /* allocate page flip / sync resources */
0ad72863 1304 ret = nv50_dmac_create(disp->disp, NV50_DISP_SYNC_CLASS, index,
b5a794b0
BS
1305 &(struct nv50_display_sync_class) {
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)
1311 goto out;
1312
9f9bdaaf
BS
1313 head->sync.addr = EVO_FLIP_SEM0(index);
1314 head->sync.data = 0x00000000;
438d99e3 1315
b5a794b0 1316 /* allocate overlay resources */
0ad72863 1317 ret = nv50_pioc_create(disp->disp, NV50_DISP_OIMM_CLASS, index,
b5a794b0
BS
1318 &(struct nv50_display_oimm_class) {
1319 .head = index,
1320 }, sizeof(struct nv50_display_oimm_class),
1321 &head->oimm.base);
438d99e3
BS
1322 if (ret)
1323 goto out;
1324
0ad72863 1325 ret = nv50_dmac_create(disp->disp, NV50_DISP_OVLY_CLASS, index,
b5a794b0
BS
1326 &(struct nv50_display_ovly_class) {
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)
1332 goto out;
438d99e3
BS
1333
1334out:
1335 if (ret)
e225f446 1336 nv50_crtc_destroy(crtc);
438d99e3
BS
1337 return ret;
1338}
1339
26f6d88b
BS
1340/******************************************************************************
1341 * DAC
1342 *****************************************************************************/
8eaa9669 1343static void
e225f446 1344nv50_dac_dpms(struct drm_encoder *encoder, int mode)
8eaa9669
BS
1345{
1346 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
e225f446 1347 struct nv50_disp *disp = nv50_disp(encoder->dev);
8eaa9669
BS
1348 int or = nv_encoder->or;
1349 u32 dpms_ctrl;
1350
35b21d39 1351 dpms_ctrl = 0x00000000;
8eaa9669
BS
1352 if (mode == DRM_MODE_DPMS_STANDBY || mode == DRM_MODE_DPMS_OFF)
1353 dpms_ctrl |= 0x00000001;
1354 if (mode == DRM_MODE_DPMS_SUSPEND || mode == DRM_MODE_DPMS_OFF)
1355 dpms_ctrl |= 0x00000004;
1356
0ad72863 1357 nvif_exec(disp->disp, NV50_DISP_DAC_PWR + or, &dpms_ctrl, sizeof(dpms_ctrl));
8eaa9669
BS
1358}
1359
1360static bool
e225f446 1361nv50_dac_mode_fixup(struct drm_encoder *encoder,
e811f5ae 1362 const struct drm_display_mode *mode,
8eaa9669
BS
1363 struct drm_display_mode *adjusted_mode)
1364{
1365 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1366 struct nouveau_connector *nv_connector;
1367
1368 nv_connector = nouveau_encoder_connector_get(nv_encoder);
1369 if (nv_connector && nv_connector->native_mode) {
1370 if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
1371 int id = adjusted_mode->base.id;
1372 *adjusted_mode = *nv_connector->native_mode;
1373 adjusted_mode->base.id = id;
1374 }
1375 }
1376
1377 return true;
1378}
1379
8eaa9669 1380static void
e225f446 1381nv50_dac_commit(struct drm_encoder *encoder)
8eaa9669
BS
1382{
1383}
1384
1385static void
e225f446 1386nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
8eaa9669
BS
1387 struct drm_display_mode *adjusted_mode)
1388{
e225f446 1389 struct nv50_mast *mast = nv50_mast(encoder->dev);
8eaa9669
BS
1390 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1391 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
97b19b5c 1392 u32 *push;
8eaa9669 1393
e225f446 1394 nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON);
8eaa9669 1395
97b19b5c 1396 push = evo_wait(mast, 8);
8eaa9669 1397 if (push) {
e225f446 1398 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
97b19b5c
BS
1399 u32 syncs = 0x00000000;
1400
1401 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1402 syncs |= 0x00000001;
1403 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1404 syncs |= 0x00000002;
1405
1406 evo_mthd(push, 0x0400 + (nv_encoder->or * 0x080), 2);
1407 evo_data(push, 1 << nv_crtc->index);
1408 evo_data(push, syncs);
1409 } else {
1410 u32 magic = 0x31ec6000 | (nv_crtc->index << 25);
1411 u32 syncs = 0x00000001;
1412
1413 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1414 syncs |= 0x00000008;
1415 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1416 syncs |= 0x00000010;
1417
1418 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1419 magic |= 0x00000001;
1420
1421 evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2);
1422 evo_data(push, syncs);
1423 evo_data(push, magic);
1424 evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1);
1425 evo_data(push, 1 << nv_crtc->index);
1426 }
1427
1428 evo_kick(push, mast);
8eaa9669
BS
1429 }
1430
1431 nv_encoder->crtc = encoder->crtc;
1432}
1433
1434static void
e225f446 1435nv50_dac_disconnect(struct drm_encoder *encoder)
8eaa9669
BS
1436{
1437 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
e225f446 1438 struct nv50_mast *mast = nv50_mast(encoder->dev);
97b19b5c 1439 const int or = nv_encoder->or;
8eaa9669
BS
1440 u32 *push;
1441
1442 if (nv_encoder->crtc) {
e225f446 1443 nv50_crtc_prepare(nv_encoder->crtc);
8eaa9669 1444
97b19b5c 1445 push = evo_wait(mast, 4);
8eaa9669 1446 if (push) {
e225f446 1447 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
97b19b5c
BS
1448 evo_mthd(push, 0x0400 + (or * 0x080), 1);
1449 evo_data(push, 0x00000000);
1450 } else {
1451 evo_mthd(push, 0x0180 + (or * 0x020), 1);
1452 evo_data(push, 0x00000000);
1453 }
97b19b5c 1454 evo_kick(push, mast);
8eaa9669 1455 }
8eaa9669 1456 }
97b19b5c
BS
1457
1458 nv_encoder->crtc = NULL;
8eaa9669
BS
1459}
1460
b6d8e7ec 1461static enum drm_connector_status
e225f446 1462nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
b6d8e7ec 1463{
e225f446 1464 struct nv50_disp *disp = nv50_disp(encoder->dev);
35b21d39 1465 int ret, or = nouveau_encoder(encoder)->or;
d40ee48a
BS
1466 u32 load = nouveau_drm(encoder->dev)->vbios.dactestval;
1467 if (load == 0)
1468 load = 340;
b681993f 1469
0ad72863 1470 ret = nvif_exec(disp->disp, NV50_DISP_DAC_LOAD + or, &load, sizeof(load));
4b31ebcf 1471 if (ret || !load)
35b21d39 1472 return connector_status_disconnected;
b681993f 1473
35b21d39 1474 return connector_status_connected;
b6d8e7ec
BS
1475}
1476
8eaa9669 1477static void
e225f446 1478nv50_dac_destroy(struct drm_encoder *encoder)
8eaa9669
BS
1479{
1480 drm_encoder_cleanup(encoder);
1481 kfree(encoder);
1482}
1483
e225f446
BS
1484static const struct drm_encoder_helper_funcs nv50_dac_hfunc = {
1485 .dpms = nv50_dac_dpms,
1486 .mode_fixup = nv50_dac_mode_fixup,
1487 .prepare = nv50_dac_disconnect,
1488 .commit = nv50_dac_commit,
1489 .mode_set = nv50_dac_mode_set,
1490 .disable = nv50_dac_disconnect,
1491 .get_crtc = nv50_display_crtc_get,
1492 .detect = nv50_dac_detect
8eaa9669
BS
1493};
1494
e225f446
BS
1495static const struct drm_encoder_funcs nv50_dac_func = {
1496 .destroy = nv50_dac_destroy,
8eaa9669
BS
1497};
1498
1499static int
e225f446 1500nv50_dac_create(struct drm_connector *connector, struct dcb_output *dcbe)
8eaa9669 1501{
5ed50209 1502 struct nouveau_drm *drm = nouveau_drm(connector->dev);
967e7bde 1503 struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
8eaa9669
BS
1504 struct nouveau_encoder *nv_encoder;
1505 struct drm_encoder *encoder;
5ed50209 1506 int type = DRM_MODE_ENCODER_DAC;
8eaa9669
BS
1507
1508 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
1509 if (!nv_encoder)
1510 return -ENOMEM;
1511 nv_encoder->dcb = dcbe;
1512 nv_encoder->or = ffs(dcbe->or) - 1;
5ed50209 1513 nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index);
8eaa9669
BS
1514
1515 encoder = to_drm_encoder(nv_encoder);
1516 encoder->possible_crtcs = dcbe->heads;
1517 encoder->possible_clones = 0;
5ed50209 1518 drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type);
e225f446 1519 drm_encoder_helper_add(encoder, &nv50_dac_hfunc);
8eaa9669
BS
1520
1521 drm_mode_connector_attach_encoder(connector, encoder);
1522 return 0;
1523}
26f6d88b 1524
78951d22
BS
1525/******************************************************************************
1526 * Audio
1527 *****************************************************************************/
1528static void
e225f446 1529nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode)
78951d22
BS
1530{
1531 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1532 struct nouveau_connector *nv_connector;
e225f446 1533 struct nv50_disp *disp = nv50_disp(encoder->dev);
78951d22
BS
1534
1535 nv_connector = nouveau_encoder_connector_get(nv_encoder);
1536 if (!drm_detect_monitor_audio(nv_connector->edid))
1537 return;
1538
78951d22 1539 drm_edid_to_eld(&nv_connector->base, nv_connector->edid);
78951d22 1540
0ad72863
BS
1541 nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or,
1542 nv_connector->base.eld,
1543 nv_connector->base.eld[2] * 4);
78951d22
BS
1544}
1545
1546static void
e225f446 1547nv50_audio_disconnect(struct drm_encoder *encoder)
78951d22
BS
1548{
1549 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
e225f446 1550 struct nv50_disp *disp = nv50_disp(encoder->dev);
78951d22 1551
0ad72863 1552 nvif_exec(disp->disp, NVA3_DISP_SOR_HDA_ELD + nv_encoder->or, NULL, 0);
78951d22
BS
1553}
1554
1555/******************************************************************************
1556 * HDMI
1557 *****************************************************************************/
1558static void
e225f446 1559nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode)
78951d22 1560{
64d9cc04
BS
1561 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1562 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
1563 struct nouveau_connector *nv_connector;
e225f446 1564 struct nv50_disp *disp = nv50_disp(encoder->dev);
1c30cd09 1565 const u32 moff = (nv_crtc->index << 3) | nv_encoder->or;
64d9cc04
BS
1566 u32 rekey = 56; /* binary driver, and tegra constant */
1567 u32 max_ac_packet;
0ad72863 1568 u32 data;
64d9cc04
BS
1569
1570 nv_connector = nouveau_encoder_connector_get(nv_encoder);
1571 if (!drm_detect_hdmi_monitor(nv_connector->edid))
1572 return;
1573
1574 max_ac_packet = mode->htotal - mode->hdisplay;
1575 max_ac_packet -= rekey;
1576 max_ac_packet -= 18; /* constant from tegra */
1577 max_ac_packet /= 32;
1578
0ad72863
BS
1579 data = NV84_DISP_SOR_HDMI_PWR_STATE_ON | (max_ac_packet << 16) | rekey;
1580 nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data));
091e40cd 1581
e225f446 1582 nv50_audio_mode_set(encoder, mode);
78951d22
BS
1583}
1584
1585static void
e84a35a8 1586nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc)
78951d22 1587{
64d9cc04 1588 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
e225f446 1589 struct nv50_disp *disp = nv50_disp(encoder->dev);
1c30cd09 1590 const u32 moff = (nv_crtc->index << 3) | nv_encoder->or;
0ad72863 1591 u32 data = 0;
64d9cc04 1592
e225f446 1593 nv50_audio_disconnect(encoder);
64d9cc04 1594
0ad72863 1595 nvif_exec(disp->disp, NV84_DISP_SOR_HDMI_PWR + moff, &data, sizeof(data));
78951d22
BS
1596}
1597
26f6d88b
BS
1598/******************************************************************************
1599 * SOR
1600 *****************************************************************************/
83fc083c 1601static void
e225f446 1602nv50_sor_dpms(struct drm_encoder *encoder, int mode)
83fc083c
BS
1603{
1604 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1605 struct drm_device *dev = encoder->dev;
e225f446 1606 struct nv50_disp *disp = nv50_disp(dev);
83fc083c 1607 struct drm_encoder *partner;
0ad72863 1608 u32 mthd, data;
83fc083c
BS
1609
1610 nv_encoder->last_dpms = mode;
1611
1612 list_for_each_entry(partner, &dev->mode_config.encoder_list, head) {
1613 struct nouveau_encoder *nv_partner = nouveau_encoder(partner);
1614
1615 if (partner->encoder_type != DRM_MODE_ENCODER_TMDS)
1616 continue;
1617
1618 if (nv_partner != nv_encoder &&
26cfa813 1619 nv_partner->dcb->or == nv_encoder->dcb->or) {
83fc083c
BS
1620 if (nv_partner->last_dpms == DRM_MODE_DPMS_ON)
1621 return;
1622 break;
1623 }
1624 }
1625
276e526c
BS
1626 mthd = (ffs(nv_encoder->dcb->heads) - 1) << 3;
1627 mthd |= (ffs(nv_encoder->dcb->sorconf.link) - 1) << 2;
4874322e
BS
1628 mthd |= nv_encoder->or;
1629
1630 if (nv_encoder->dcb->type == DCB_OUTPUT_DP) {
0ad72863
BS
1631 data = 1;
1632 nvif_exec(disp->disp, NV50_DISP_SOR_PWR | mthd, &data, sizeof(data));
4874322e
BS
1633 mthd |= NV94_DISP_SOR_DP_PWR;
1634 } else {
1635 mthd |= NV50_DISP_SOR_PWR;
1636 }
1637
0ad72863
BS
1638 data = (mode == DRM_MODE_DPMS_ON);
1639 nvif_exec(disp->disp, mthd, &data, sizeof(data));
83fc083c
BS
1640}
1641
1642static bool
e225f446 1643nv50_sor_mode_fixup(struct drm_encoder *encoder,
e811f5ae 1644 const struct drm_display_mode *mode,
83fc083c
BS
1645 struct drm_display_mode *adjusted_mode)
1646{
1647 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1648 struct nouveau_connector *nv_connector;
1649
1650 nv_connector = nouveau_encoder_connector_get(nv_encoder);
1651 if (nv_connector && nv_connector->native_mode) {
1652 if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
1653 int id = adjusted_mode->base.id;
1654 *adjusted_mode = *nv_connector->native_mode;
1655 adjusted_mode->base.id = id;
1656 }
1657 }
1658
1659 return true;
1660}
1661
4cbb0f8d 1662static void
e84a35a8 1663nv50_sor_ctrl(struct nouveau_encoder *nv_encoder, u32 mask, u32 data)
4cbb0f8d 1664{
e84a35a8
BS
1665 struct nv50_mast *mast = nv50_mast(nv_encoder->base.base.dev);
1666 u32 temp = (nv_encoder->ctrl & ~mask) | (data & mask), *push;
1667 if (temp != nv_encoder->ctrl && (push = evo_wait(mast, 2))) {
1668 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
1669 evo_mthd(push, 0x0600 + (nv_encoder->or * 0x40), 1);
1670 evo_data(push, (nv_encoder->ctrl = temp));
1671 } else {
1672 evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1);
1673 evo_data(push, (nv_encoder->ctrl = temp));
4cbb0f8d 1674 }
e84a35a8 1675 evo_kick(push, mast);
4cbb0f8d 1676 }
e84a35a8
BS
1677}
1678
1679static void
1680nv50_sor_disconnect(struct drm_encoder *encoder)
1681{
1682 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1683 struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc);
419e8dc0
BS
1684
1685 nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
1686 nv_encoder->crtc = NULL;
e84a35a8
BS
1687
1688 if (nv_crtc) {
1689 nv50_crtc_prepare(&nv_crtc->base);
1690 nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0);
1691 nv50_hdmi_disconnect(&nv_encoder->base.base, nv_crtc);
1692 }
4cbb0f8d
BS
1693}
1694
83fc083c 1695static void
e225f446 1696nv50_sor_commit(struct drm_encoder *encoder)
83fc083c
BS
1697{
1698}
1699
1700static void
e225f446 1701nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
3b6d83d1 1702 struct drm_display_mode *mode)
83fc083c 1703{
e225f446
BS
1704 struct nv50_disp *disp = nv50_disp(encoder->dev);
1705 struct nv50_mast *mast = nv50_mast(encoder->dev);
78951d22 1706 struct drm_device *dev = encoder->dev;
77145f1c 1707 struct nouveau_drm *drm = nouveau_drm(dev);
83fc083c
BS
1708 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1709 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
3b6d83d1 1710 struct nouveau_connector *nv_connector;
77145f1c 1711 struct nvbios *bios = &drm->vbios;
e84a35a8 1712 u32 lvds = 0, mask, ctrl;
419e8dc0
BS
1713 u8 owner = 1 << nv_crtc->index;
1714 u8 proto = 0xf;
1715 u8 depth = 0x0;
83fc083c 1716
3b6d83d1 1717 nv_connector = nouveau_encoder_connector_get(nv_encoder);
e84a35a8
BS
1718 nv_encoder->crtc = encoder->crtc;
1719
3b6d83d1 1720 switch (nv_encoder->dcb->type) {
cb75d97e 1721 case DCB_OUTPUT_TMDS:
3b6d83d1
BS
1722 if (nv_encoder->dcb->sorconf.link & 1) {
1723 if (mode->clock < 165000)
419e8dc0 1724 proto = 0x1;
3b6d83d1 1725 else
419e8dc0 1726 proto = 0x5;
3b6d83d1 1727 } else {
419e8dc0 1728 proto = 0x2;
3b6d83d1
BS
1729 }
1730
e84a35a8 1731 nv50_hdmi_mode_set(&nv_encoder->base.base, mode);
3b6d83d1 1732 break;
cb75d97e 1733 case DCB_OUTPUT_LVDS:
419e8dc0
BS
1734 proto = 0x0;
1735
3b6d83d1
BS
1736 if (bios->fp_no_ddc) {
1737 if (bios->fp.dual_link)
419e8dc0 1738 lvds |= 0x0100;
3b6d83d1 1739 if (bios->fp.if_is_24bit)
419e8dc0 1740 lvds |= 0x0200;
3b6d83d1 1741 } else {
befb51e9 1742 if (nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) {
3b6d83d1 1743 if (((u8 *)nv_connector->edid)[121] == 2)
419e8dc0 1744 lvds |= 0x0100;
3b6d83d1
BS
1745 } else
1746 if (mode->clock >= bios->fp.duallink_transition_clk) {
419e8dc0 1747 lvds |= 0x0100;
3b6d83d1 1748 }
83fc083c 1749
419e8dc0 1750 if (lvds & 0x0100) {
3b6d83d1 1751 if (bios->fp.strapless_is_24bit & 2)
419e8dc0 1752 lvds |= 0x0200;
3b6d83d1
BS
1753 } else {
1754 if (bios->fp.strapless_is_24bit & 1)
419e8dc0 1755 lvds |= 0x0200;
3b6d83d1
BS
1756 }
1757
1758 if (nv_connector->base.display_info.bpc == 8)
419e8dc0 1759 lvds |= 0x0200;
3b6d83d1 1760 }
4a230fa6 1761
0ad72863 1762 nvif_exec(disp->disp, NV50_DISP_SOR_LVDS_SCRIPT + nv_encoder->or, &lvds, sizeof(lvds));
3b6d83d1 1763 break;
cb75d97e 1764 case DCB_OUTPUT_DP:
3488c57b 1765 if (nv_connector->base.display_info.bpc == 6) {
6e83fda2 1766 nv_encoder->dp.datarate = mode->clock * 18 / 8;
419e8dc0 1767 depth = 0x2;
bf2c886a
BS
1768 } else
1769 if (nv_connector->base.display_info.bpc == 8) {
6e83fda2 1770 nv_encoder->dp.datarate = mode->clock * 24 / 8;
419e8dc0 1771 depth = 0x5;
bf2c886a
BS
1772 } else {
1773 nv_encoder->dp.datarate = mode->clock * 30 / 8;
1774 depth = 0x6;
3488c57b 1775 }
6e83fda2
BS
1776
1777 if (nv_encoder->dcb->sorconf.link & 1)
419e8dc0 1778 proto = 0x8;
6e83fda2 1779 else
419e8dc0 1780 proto = 0x9;
6e83fda2 1781 break;
3b6d83d1
BS
1782 default:
1783 BUG_ON(1);
1784 break;
1785 }
ff8ff503 1786
e84a35a8 1787 nv50_sor_dpms(&nv_encoder->base.base, DRM_MODE_DPMS_ON);
83fc083c 1788
e84a35a8
BS
1789 if (nv50_vers(mast) >= NVD0_DISP_CLASS) {
1790 u32 *push = evo_wait(mast, 3);
1791 if (push) {
419e8dc0
BS
1792 u32 magic = 0x31ec6000 | (nv_crtc->index << 25);
1793 u32 syncs = 0x00000001;
1794
1795 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1796 syncs |= 0x00000008;
1797 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1798 syncs |= 0x00000010;
1799
1800 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
1801 magic |= 0x00000001;
1802
1803 evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2);
1804 evo_data(push, syncs | (depth << 6));
1805 evo_data(push, magic);
e84a35a8 1806 evo_kick(push, mast);
419e8dc0
BS
1807 }
1808
e84a35a8
BS
1809 ctrl = proto << 8;
1810 mask = 0x00000f00;
1811 } else {
1812 ctrl = (depth << 16) | (proto << 8);
1813 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1814 ctrl |= 0x00001000;
1815 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1816 ctrl |= 0x00002000;
1817 mask = 0x000f3f00;
83fc083c
BS
1818 }
1819
e84a35a8 1820 nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner);
83fc083c
BS
1821}
1822
83fc083c 1823static void
e225f446 1824nv50_sor_destroy(struct drm_encoder *encoder)
83fc083c
BS
1825{
1826 drm_encoder_cleanup(encoder);
1827 kfree(encoder);
1828}
1829
e225f446
BS
1830static const struct drm_encoder_helper_funcs nv50_sor_hfunc = {
1831 .dpms = nv50_sor_dpms,
1832 .mode_fixup = nv50_sor_mode_fixup,
5a885f0b 1833 .prepare = nv50_sor_disconnect,
e225f446
BS
1834 .commit = nv50_sor_commit,
1835 .mode_set = nv50_sor_mode_set,
1836 .disable = nv50_sor_disconnect,
1837 .get_crtc = nv50_display_crtc_get,
83fc083c
BS
1838};
1839
e225f446
BS
1840static const struct drm_encoder_funcs nv50_sor_func = {
1841 .destroy = nv50_sor_destroy,
83fc083c
BS
1842};
1843
1844static int
e225f446 1845nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
83fc083c 1846{
5ed50209 1847 struct nouveau_drm *drm = nouveau_drm(connector->dev);
967e7bde 1848 struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
83fc083c
BS
1849 struct nouveau_encoder *nv_encoder;
1850 struct drm_encoder *encoder;
5ed50209
BS
1851 int type;
1852
1853 switch (dcbe->type) {
1854 case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break;
1855 case DCB_OUTPUT_TMDS:
1856 case DCB_OUTPUT_DP:
1857 default:
1858 type = DRM_MODE_ENCODER_TMDS;
1859 break;
1860 }
83fc083c
BS
1861
1862 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
1863 if (!nv_encoder)
1864 return -ENOMEM;
1865 nv_encoder->dcb = dcbe;
1866 nv_encoder->or = ffs(dcbe->or) - 1;
5ed50209 1867 nv_encoder->i2c = i2c->find(i2c, dcbe->i2c_index);
83fc083c
BS
1868 nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
1869
1870 encoder = to_drm_encoder(nv_encoder);
1871 encoder->possible_crtcs = dcbe->heads;
1872 encoder->possible_clones = 0;
5ed50209 1873 drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type);
e225f446 1874 drm_encoder_helper_add(encoder, &nv50_sor_hfunc);
83fc083c
BS
1875
1876 drm_mode_connector_attach_encoder(connector, encoder);
1877 return 0;
1878}
26f6d88b 1879
eb6313ad
BS
1880/******************************************************************************
1881 * PIOR
1882 *****************************************************************************/
1883
1884static void
1885nv50_pior_dpms(struct drm_encoder *encoder, int mode)
1886{
1887 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1888 struct nv50_disp *disp = nv50_disp(encoder->dev);
1889 u32 mthd = (nv_encoder->dcb->type << 12) | nv_encoder->or;
1890 u32 ctrl = (mode == DRM_MODE_DPMS_ON);
0ad72863 1891 nvif_exec(disp->disp, NV50_DISP_PIOR_PWR + mthd, &ctrl, sizeof(ctrl));
eb6313ad
BS
1892}
1893
1894static bool
1895nv50_pior_mode_fixup(struct drm_encoder *encoder,
1896 const struct drm_display_mode *mode,
1897 struct drm_display_mode *adjusted_mode)
1898{
1899 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1900 struct nouveau_connector *nv_connector;
1901
1902 nv_connector = nouveau_encoder_connector_get(nv_encoder);
1903 if (nv_connector && nv_connector->native_mode) {
1904 if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
1905 int id = adjusted_mode->base.id;
1906 *adjusted_mode = *nv_connector->native_mode;
1907 adjusted_mode->base.id = id;
1908 }
1909 }
1910
1911 adjusted_mode->clock *= 2;
1912 return true;
1913}
1914
1915static void
1916nv50_pior_commit(struct drm_encoder *encoder)
1917{
1918}
1919
1920static void
1921nv50_pior_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
1922 struct drm_display_mode *adjusted_mode)
1923{
1924 struct nv50_mast *mast = nv50_mast(encoder->dev);
1925 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1926 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
1927 struct nouveau_connector *nv_connector;
1928 u8 owner = 1 << nv_crtc->index;
1929 u8 proto, depth;
1930 u32 *push;
1931
1932 nv_connector = nouveau_encoder_connector_get(nv_encoder);
1933 switch (nv_connector->base.display_info.bpc) {
1934 case 10: depth = 0x6; break;
1935 case 8: depth = 0x5; break;
1936 case 6: depth = 0x2; break;
1937 default: depth = 0x0; break;
1938 }
1939
1940 switch (nv_encoder->dcb->type) {
1941 case DCB_OUTPUT_TMDS:
1942 case DCB_OUTPUT_DP:
1943 proto = 0x0;
1944 break;
1945 default:
1946 BUG_ON(1);
1947 break;
1948 }
1949
1950 nv50_pior_dpms(encoder, DRM_MODE_DPMS_ON);
1951
1952 push = evo_wait(mast, 8);
1953 if (push) {
1954 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
1955 u32 ctrl = (depth << 16) | (proto << 8) | owner;
1956 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1957 ctrl |= 0x00001000;
1958 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1959 ctrl |= 0x00002000;
1960 evo_mthd(push, 0x0700 + (nv_encoder->or * 0x040), 1);
1961 evo_data(push, ctrl);
1962 }
1963
1964 evo_kick(push, mast);
1965 }
1966
1967 nv_encoder->crtc = encoder->crtc;
1968}
1969
1970static void
1971nv50_pior_disconnect(struct drm_encoder *encoder)
1972{
1973 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
1974 struct nv50_mast *mast = nv50_mast(encoder->dev);
1975 const int or = nv_encoder->or;
1976 u32 *push;
1977
1978 if (nv_encoder->crtc) {
1979 nv50_crtc_prepare(nv_encoder->crtc);
1980
1981 push = evo_wait(mast, 4);
1982 if (push) {
1983 if (nv50_vers(mast) < NVD0_DISP_MAST_CLASS) {
1984 evo_mthd(push, 0x0700 + (or * 0x040), 1);
1985 evo_data(push, 0x00000000);
1986 }
eb6313ad
BS
1987 evo_kick(push, mast);
1988 }
1989 }
1990
1991 nv_encoder->crtc = NULL;
1992}
1993
1994static void
1995nv50_pior_destroy(struct drm_encoder *encoder)
1996{
1997 drm_encoder_cleanup(encoder);
1998 kfree(encoder);
1999}
2000
2001static const struct drm_encoder_helper_funcs nv50_pior_hfunc = {
2002 .dpms = nv50_pior_dpms,
2003 .mode_fixup = nv50_pior_mode_fixup,
2004 .prepare = nv50_pior_disconnect,
2005 .commit = nv50_pior_commit,
2006 .mode_set = nv50_pior_mode_set,
2007 .disable = nv50_pior_disconnect,
2008 .get_crtc = nv50_display_crtc_get,
2009};
2010
2011static const struct drm_encoder_funcs nv50_pior_func = {
2012 .destroy = nv50_pior_destroy,
2013};
2014
2015static int
2016nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
2017{
2018 struct nouveau_drm *drm = nouveau_drm(connector->dev);
967e7bde 2019 struct nouveau_i2c *i2c = nvkm_i2c(&drm->device);
eb6313ad
BS
2020 struct nouveau_i2c_port *ddc = NULL;
2021 struct nouveau_encoder *nv_encoder;
2022 struct drm_encoder *encoder;
2023 int type;
2024
2025 switch (dcbe->type) {
2026 case DCB_OUTPUT_TMDS:
2027 ddc = i2c->find_type(i2c, NV_I2C_TYPE_EXTDDC(dcbe->extdev));
2028 type = DRM_MODE_ENCODER_TMDS;
2029 break;
2030 case DCB_OUTPUT_DP:
2031 ddc = i2c->find_type(i2c, NV_I2C_TYPE_EXTAUX(dcbe->extdev));
2032 type = DRM_MODE_ENCODER_TMDS;
2033 break;
2034 default:
2035 return -ENODEV;
2036 }
2037
2038 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
2039 if (!nv_encoder)
2040 return -ENOMEM;
2041 nv_encoder->dcb = dcbe;
2042 nv_encoder->or = ffs(dcbe->or) - 1;
2043 nv_encoder->i2c = ddc;
2044
2045 encoder = to_drm_encoder(nv_encoder);
2046 encoder->possible_crtcs = dcbe->heads;
2047 encoder->possible_clones = 0;
2048 drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type);
2049 drm_encoder_helper_add(encoder, &nv50_pior_hfunc);
2050
2051 drm_mode_connector_attach_encoder(connector, encoder);
2052 return 0;
2053}
2054
ab0af559
BS
2055/******************************************************************************
2056 * Framebuffer
2057 *****************************************************************************/
2058
8a423647 2059static void
0ad72863 2060nv50_fbdma_fini(struct nv50_fbdma *fbdma)
8a423647 2061{
0ad72863
BS
2062 int i;
2063 for (i = 0; i < ARRAY_SIZE(fbdma->base); i++)
2064 nvif_object_fini(&fbdma->base[i]);
2065 nvif_object_fini(&fbdma->core);
8a423647
BS
2066 list_del(&fbdma->head);
2067 kfree(fbdma);
2068}
2069
2070static int
2071nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kind)
2072{
2073 struct nouveau_drm *drm = nouveau_drm(dev);
2074 struct nv50_disp *disp = nv50_disp(dev);
2075 struct nv50_mast *mast = nv50_mast(dev);
4acfd707
BS
2076 struct __attribute__ ((packed)) {
2077 struct nv_dma_v0 base;
2078 union {
2079 struct nv50_dma_v0 nv50;
2080 struct gf100_dma_v0 gf100;
2081 struct gf110_dma_v0 gf110;
2082 };
2083 } args = {};
8a423647
BS
2084 struct nv50_fbdma *fbdma;
2085 struct drm_crtc *crtc;
4acfd707 2086 u32 size = sizeof(args.base);
8a423647
BS
2087 int ret;
2088
2089 list_for_each_entry(fbdma, &disp->fbdma, head) {
0ad72863 2090 if (fbdma->core.handle == name)
8a423647
BS
2091 return 0;
2092 }
2093
2094 fbdma = kzalloc(sizeof(*fbdma), GFP_KERNEL);
2095 if (!fbdma)
2096 return -ENOMEM;
2097 list_add(&fbdma->head, &disp->fbdma);
8a423647 2098
4acfd707
BS
2099 args.base.target = NV_DMA_V0_TARGET_VRAM;
2100 args.base.access = NV_DMA_V0_ACCESS_RDWR;
2101 args.base.start = offset;
2102 args.base.limit = offset + length - 1;
8a423647 2103
967e7bde 2104 if (drm->device.info.chipset < 0x80) {
4acfd707
BS
2105 args.nv50.part = NV50_DMA_V0_PART_256;
2106 size += sizeof(args.nv50);
8a423647 2107 } else
967e7bde 2108 if (drm->device.info.chipset < 0xc0) {
4acfd707
BS
2109 args.nv50.part = NV50_DMA_V0_PART_256;
2110 args.nv50.kind = kind;
2111 size += sizeof(args.nv50);
8a423647 2112 } else
967e7bde 2113 if (drm->device.info.chipset < 0xd0) {
4acfd707
BS
2114 args.gf100.kind = kind;
2115 size += sizeof(args.gf100);
8a423647 2116 } else {
4acfd707
BS
2117 args.gf110.page = GF110_DMA_V0_PAGE_LP;
2118 args.gf110.kind = kind;
2119 size += sizeof(args.gf110);
8a423647
BS
2120 }
2121
2122 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
0ad72863
BS
2123 struct nv50_head *head = nv50_head(crtc);
2124 int ret = nvif_object_init(&head->sync.base.base.user, NULL,
4acfd707 2125 name, NV_DMA_IN_MEMORY, &args, size,
0ad72863 2126 &fbdma->base[head->base.index]);
8a423647 2127 if (ret) {
0ad72863 2128 nv50_fbdma_fini(fbdma);
8a423647
BS
2129 return ret;
2130 }
2131 }
2132
0ad72863 2133 ret = nvif_object_init(&mast->base.base.user, NULL, name,
4acfd707 2134 NV_DMA_IN_MEMORY, &args, size,
0ad72863 2135 &fbdma->core);
8a423647 2136 if (ret) {
0ad72863 2137 nv50_fbdma_fini(fbdma);
8a423647
BS
2138 return ret;
2139 }
2140
2141 return 0;
2142}
2143
ab0af559
BS
2144static void
2145nv50_fb_dtor(struct drm_framebuffer *fb)
2146{
2147}
2148
2149static int
2150nv50_fb_ctor(struct drm_framebuffer *fb)
2151{
2152 struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb);
2153 struct nouveau_drm *drm = nouveau_drm(fb->dev);
2154 struct nouveau_bo *nvbo = nv_fb->nvbo;
8a423647 2155 struct nv50_disp *disp = nv50_disp(fb->dev);
967e7bde 2156 struct nouveau_fb *pfb = nvkm_fb(&drm->device);
8a423647
BS
2157 u8 kind = nouveau_bo_tile_layout(nvbo) >> 8;
2158 u8 tile = nvbo->tile_mode;
ab0af559
BS
2159
2160 if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) {
2161 NV_ERROR(drm, "framebuffer requires contiguous bo\n");
2162 return -EINVAL;
2163 }
2164
967e7bde 2165 if (drm->device.info.chipset >= 0xc0)
8a423647
BS
2166 tile >>= 4; /* yep.. */
2167
ab0af559
BS
2168 switch (fb->depth) {
2169 case 8: nv_fb->r_format = 0x1e00; break;
2170 case 15: nv_fb->r_format = 0xe900; break;
2171 case 16: nv_fb->r_format = 0xe800; break;
2172 case 24:
2173 case 32: nv_fb->r_format = 0xcf00; break;
2174 case 30: nv_fb->r_format = 0xd100; break;
2175 default:
2176 NV_ERROR(drm, "unknown depth %d\n", fb->depth);
2177 return -EINVAL;
2178 }
2179
0ad72863 2180 if (disp->disp->oclass < NV84_DISP_CLASS) {
8a423647
BS
2181 nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) :
2182 (fb->pitches[0] | 0x00100000);
2183 nv_fb->r_format |= kind << 16;
2184 } else
0ad72863 2185 if (disp->disp->oclass < NVD0_DISP_CLASS) {
8a423647
BS
2186 nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) :
2187 (fb->pitches[0] | 0x00100000);
ab0af559 2188 } else {
8a423647
BS
2189 nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) :
2190 (fb->pitches[0] | 0x01000000);
ab0af559 2191 }
8a423647 2192 nv_fb->r_handle = 0xffff0000 | kind;
ab0af559 2193
8a423647 2194 return nv50_fbdma_init(fb->dev, nv_fb->r_handle, 0, pfb->ram->size, kind);
ab0af559
BS
2195}
2196
26f6d88b
BS
2197/******************************************************************************
2198 * Init
2199 *****************************************************************************/
ab0af559 2200
2a44e499 2201void
e225f446 2202nv50_display_fini(struct drm_device *dev)
26f6d88b 2203{
26f6d88b
BS
2204}
2205
2206int
e225f446 2207nv50_display_init(struct drm_device *dev)
26f6d88b 2208{
9f9bdaaf
BS
2209 struct nv50_disp *disp = nv50_disp(dev);
2210 struct drm_crtc *crtc;
2211 u32 *push;
2212
2213 push = evo_wait(nv50_mast(dev), 32);
2214 if (!push)
2215 return -EBUSY;
2216
2217 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2218 struct nv50_sync *sync = nv50_sync(crtc);
2219 nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data);
bdb8c212 2220 }
efd272a7 2221
9f9bdaaf 2222 evo_mthd(push, 0x0088, 1);
f45f55c4 2223 evo_data(push, nv50_mast(dev)->base.sync.handle);
9f9bdaaf
BS
2224 evo_kick(push, nv50_mast(dev));
2225 return 0;
26f6d88b
BS
2226}
2227
2228void
e225f446 2229nv50_display_destroy(struct drm_device *dev)
26f6d88b 2230{
e225f446 2231 struct nv50_disp *disp = nv50_disp(dev);
8a423647
BS
2232 struct nv50_fbdma *fbdma, *fbtmp;
2233
2234 list_for_each_entry_safe(fbdma, fbtmp, &disp->fbdma, head) {
0ad72863 2235 nv50_fbdma_fini(fbdma);
8a423647 2236 }
bdb8c212 2237
0ad72863 2238 nv50_dmac_destroy(&disp->mast.base, disp->disp);
26f6d88b 2239
816af2f2 2240 nouveau_bo_unmap(disp->sync);
04c8c210
MS
2241 if (disp->sync)
2242 nouveau_bo_unpin(disp->sync);
816af2f2 2243 nouveau_bo_ref(NULL, &disp->sync);
51beb428 2244
77145f1c 2245 nouveau_display(dev)->priv = NULL;
26f6d88b
BS
2246 kfree(disp);
2247}
2248
2249int
e225f446 2250nv50_display_create(struct drm_device *dev)
26f6d88b 2251{
967e7bde 2252 struct nvif_device *device = &nouveau_drm(dev)->device;
77145f1c 2253 struct nouveau_drm *drm = nouveau_drm(dev);
77145f1c 2254 struct dcb_table *dcb = &drm->vbios.dcb;
83fc083c 2255 struct drm_connector *connector, *tmp;
e225f446 2256 struct nv50_disp *disp;
cb75d97e 2257 struct dcb_output *dcbe;
7c5f6a87 2258 int crtcs, ret, i;
26f6d88b
BS
2259
2260 disp = kzalloc(sizeof(*disp), GFP_KERNEL);
2261 if (!disp)
2262 return -ENOMEM;
8a423647 2263 INIT_LIST_HEAD(&disp->fbdma);
77145f1c
BS
2264
2265 nouveau_display(dev)->priv = disp;
e225f446
BS
2266 nouveau_display(dev)->dtor = nv50_display_destroy;
2267 nouveau_display(dev)->init = nv50_display_init;
2268 nouveau_display(dev)->fini = nv50_display_fini;
ab0af559
BS
2269 nouveau_display(dev)->fb_ctor = nv50_fb_ctor;
2270 nouveau_display(dev)->fb_dtor = nv50_fb_dtor;
0ad72863 2271 disp->disp = &nouveau_display(dev)->disp;
26f6d88b 2272
b5a794b0
BS
2273 /* small shared memory area we use for notifiers and semaphores */
2274 ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
2275 0, 0x0000, NULL, &disp->sync);
2276 if (!ret) {
2277 ret = nouveau_bo_pin(disp->sync, TTM_PL_FLAG_VRAM);
04c8c210 2278 if (!ret) {
b5a794b0 2279 ret = nouveau_bo_map(disp->sync);
04c8c210
MS
2280 if (ret)
2281 nouveau_bo_unpin(disp->sync);
2282 }
b5a794b0
BS
2283 if (ret)
2284 nouveau_bo_ref(NULL, &disp->sync);
2285 }
2286
b5a794b0
BS
2287 if (ret)
2288 goto out;
2289
2290 /* allocate master evo channel */
0ad72863 2291 ret = nv50_dmac_create(disp->disp, NV50_DISP_MAST_CLASS, 0,
b5a794b0
BS
2292 &(struct nv50_display_mast_class) {
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)
2297 goto out;
2298
438d99e3 2299 /* create crtc objects to represent the hw heads */
0ad72863 2300 if (disp->disp->oclass >= NVD0_DISP_CLASS)
db2bec18 2301 crtcs = nvif_rd32(device, 0x022448);
63718a07
BS
2302 else
2303 crtcs = 2;
2304
7c5f6a87 2305 for (i = 0; i < crtcs; i++) {
0ad72863 2306 ret = nv50_crtc_create(dev, i);
438d99e3
BS
2307 if (ret)
2308 goto out;
2309 }
2310
83fc083c
BS
2311 /* create encoder/connector objects based on VBIOS DCB table */
2312 for (i = 0, dcbe = &dcb->entry[0]; i < dcb->entries; i++, dcbe++) {
2313 connector = nouveau_connector_create(dev, dcbe->connector);
2314 if (IS_ERR(connector))
2315 continue;
2316
eb6313ad
BS
2317 if (dcbe->location == DCB_LOC_ON_CHIP) {
2318 switch (dcbe->type) {
2319 case DCB_OUTPUT_TMDS:
2320 case DCB_OUTPUT_LVDS:
2321 case DCB_OUTPUT_DP:
2322 ret = nv50_sor_create(connector, dcbe);
2323 break;
2324 case DCB_OUTPUT_ANALOG:
2325 ret = nv50_dac_create(connector, dcbe);
2326 break;
2327 default:
2328 ret = -ENODEV;
2329 break;
2330 }
2331 } else {
2332 ret = nv50_pior_create(connector, dcbe);
83fc083c
BS
2333 }
2334
eb6313ad
BS
2335 if (ret) {
2336 NV_WARN(drm, "failed to create encoder %d/%d/%d: %d\n",
2337 dcbe->location, dcbe->type,
2338 ffs(dcbe->or) - 1, ret);
94f54f53 2339 ret = 0;
83fc083c
BS
2340 }
2341 }
2342
2343 /* cull any connectors we created that don't have an encoder */
2344 list_for_each_entry_safe(connector, tmp, &dev->mode_config.connector_list, head) {
2345 if (connector->encoder_ids[0])
2346 continue;
2347
77145f1c 2348 NV_WARN(drm, "%s has no encoders, removing\n",
8c6c361a 2349 connector->name);
83fc083c
BS
2350 connector->funcs->destroy(connector);
2351 }
2352
26f6d88b
BS
2353out:
2354 if (ret)
e225f446 2355 nv50_display_destroy(dev);
26f6d88b
BS
2356 return ret;
2357}