drm/nvd0/disp: some magic to make evo happeir
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / drivers / gpu / drm / nouveau / nvd0_display.c
CommitLineData
26f6d88b
BS
1/*
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
26f6d88b 27#include "drmP.h"
83fc083c 28#include "drm_crtc_helper.h"
26f6d88b
BS
29
30#include "nouveau_drv.h"
31#include "nouveau_connector.h"
32#include "nouveau_encoder.h"
33#include "nouveau_crtc.h"
438d99e3 34#include "nouveau_fb.h"
26f6d88b 35
efd272a7
BS
36#define MEM_SYNC 0xe0000001
37#define MEM_VRAM 0xe0010000
38
26f6d88b
BS
39struct nvd0_display {
40 struct nouveau_gpuobj *mem;
51beb428
BS
41 struct {
42 dma_addr_t handle;
43 u32 *ptr;
44 } evo[1];
26f6d88b
BS
45};
46
47static struct nvd0_display *
48nvd0_display(struct drm_device *dev)
49{
50 struct drm_nouveau_private *dev_priv = dev->dev_private;
51 return dev_priv->engine.display.priv;
52}
53
51beb428
BS
54static int
55evo_icmd(struct drm_device *dev, int id, u32 mthd, u32 data)
56{
57 int ret = 0;
58 nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000001);
59 nv_wr32(dev, 0x610704 + (id * 0x10), data);
60 nv_mask(dev, 0x610704 + (id * 0x10), 0x80000ffc, 0x80000000 | mthd);
61 if (!nv_wait(dev, 0x610704 + (id * 0x10), 0x80000000, 0x00000000))
62 ret = -EBUSY;
63 nv_mask(dev, 0x610700 + (id * 0x10), 0x00000001, 0x00000000);
64 return ret;
65}
66
67static u32 *
68evo_wait(struct drm_device *dev, int id, int nr)
69{
70 struct nvd0_display *disp = nvd0_display(dev);
71 u32 put = nv_rd32(dev, 0x640000 + (id * 0x1000)) / 4;
72
73 if (put + nr >= (PAGE_SIZE / 4)) {
74 disp->evo[id].ptr[put] = 0x20000000;
75
76 nv_wr32(dev, 0x640000 + (id * 0x1000), 0x00000000);
77 if (!nv_wait(dev, 0x640004 + (id * 0x1000), ~0, 0x00000000)) {
78 NV_ERROR(dev, "evo %d dma stalled\n", id);
79 return NULL;
80 }
81
82 put = 0;
83 }
84
85 return disp->evo[id].ptr + put;
86}
87
88static void
89evo_kick(u32 *push, struct drm_device *dev, int id)
90{
91 struct nvd0_display *disp = nvd0_display(dev);
92 nv_wr32(dev, 0x640000 + (id * 0x1000), (push - disp->evo[id].ptr) << 2);
93}
94
95#define evo_mthd(p,m,s) *((p)++) = (((s) << 18) | (m))
96#define evo_data(p,d) *((p)++) = (d)
97
83fc083c
BS
98static struct drm_crtc *
99nvd0_display_crtc_get(struct drm_encoder *encoder)
100{
101 return nouveau_encoder(encoder)->crtc;
102}
103
438d99e3
BS
104/******************************************************************************
105 * CRTC
106 *****************************************************************************/
107static int
108nvd0_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool on, bool update)
109{
110 struct drm_device *dev = nv_crtc->base.dev;
111 u32 *push, mode;
112
113 mode = 0x00000000;
114 if (on) {
115 /* 0x11: 6bpc dynamic 2x2
116 * 0x13: 8bpc dynamic 2x2
117 * 0x19: 6bpc static 2x2
118 * 0x1b: 8bpc static 2x2
119 * 0x21: 6bpc temporal
120 * 0x23: 8bpc temporal
121 */
122 mode = 0x00000011;
123 }
124
125 push = evo_wait(dev, 0, 4);
126 if (push) {
127 evo_mthd(push, 0x0490 + (nv_crtc->index * 0x300), 1);
128 evo_data(push, mode);
129 if (update) {
130 evo_mthd(push, 0x0080, 1);
131 evo_data(push, 0x00000000);
132 }
133 evo_kick(push, dev, 0);
134 }
135
136 return 0;
137}
138
139static int
140nvd0_crtc_set_scale(struct nouveau_crtc *nv_crtc, int type, bool update)
141{
142 struct drm_display_mode *mode = &nv_crtc->base.mode;
143 struct drm_device *dev = nv_crtc->base.dev;
144 u32 *push;
145
146 /*XXX: actually handle scaling */
147
148 push = evo_wait(dev, 0, 16);
149 if (push) {
150 evo_mthd(push, 0x04c0 + (nv_crtc->index * 0x300), 3);
151 evo_data(push, (mode->vdisplay << 16) | mode->hdisplay);
152 evo_data(push, (mode->vdisplay << 16) | mode->hdisplay);
153 evo_data(push, (mode->vdisplay << 16) | mode->hdisplay);
154 evo_mthd(push, 0x0494 + (nv_crtc->index * 0x300), 1);
155 evo_data(push, 0x00000000);
156 evo_mthd(push, 0x04b0 + (nv_crtc->index * 0x300), 1);
157 evo_data(push, 0x00000000);
158 evo_mthd(push, 0x04b8 + (nv_crtc->index * 0x300), 1);
159 evo_data(push, (mode->vdisplay << 16) | mode->hdisplay);
160 if (update) {
161 evo_mthd(push, 0x0080, 1);
162 evo_data(push, 0x00000000);
163 }
164 evo_kick(push, dev, 0);
165 }
166
167 return 0;
168}
169
170static int
171nvd0_crtc_set_image(struct nouveau_crtc *nv_crtc, struct drm_framebuffer *fb,
172 int x, int y, bool update)
173{
174 struct nouveau_framebuffer *nvfb = nouveau_framebuffer(fb);
175 u32 *push;
176
177 /*XXX*/
178 nv_crtc->fb.tile_flags = MEM_VRAM;
179
180 push = evo_wait(fb->dev, 0, 16);
181 if (push) {
182 evo_mthd(push, 0x0460 + (nv_crtc->index * 0x300), 1);
183 evo_data(push, nvfb->nvbo->bo.offset >> 8);
184 evo_mthd(push, 0x0468 + (nv_crtc->index * 0x300), 4);
185 evo_data(push, (fb->height << 16) | fb->width);
186 evo_data(push, nvfb->r_pitch);
187 evo_data(push, nvfb->r_format);
188 evo_data(push, nv_crtc->fb.tile_flags);
189 evo_kick(push, fb->dev, 0);
190 }
191
192 return 0;
193}
194
195static void
196nvd0_crtc_cursor_show(struct nouveau_crtc *nv_crtc, bool show, bool update)
197{
198 struct drm_device *dev = nv_crtc->base.dev;
199 u32 *push = evo_wait(dev, 0, 16);
200 if (push) {
201 if (show) {
202 evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2);
203 evo_data(push, 0x85000000);
204 evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8);
205 evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
206 evo_data(push, MEM_VRAM);
207 } else {
208 evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 1);
209 evo_data(push, 0x05000000);
210 evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1);
211 evo_data(push, 0x00000000);
212 }
213
214 if (update) {
215 evo_mthd(push, 0x0080, 1);
216 evo_data(push, 0x00000000);
217 }
218
219 evo_kick(push, dev, 0);
220 }
221}
222
223static void
224nvd0_crtc_dpms(struct drm_crtc *crtc, int mode)
225{
226}
227
228static void
229nvd0_crtc_prepare(struct drm_crtc *crtc)
230{
231 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
232 u32 *push;
233
234 push = evo_wait(crtc->dev, 0, 2);
235 if (push) {
236 evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1);
237 evo_data(push, 0x00000000);
238 evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 1);
239 evo_data(push, 0x03000000);
240 evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1);
241 evo_data(push, 0x00000000);
242 evo_kick(push, crtc->dev, 0);
243 }
244
245 nvd0_crtc_cursor_show(nv_crtc, false, false);
246}
247
248static void
249nvd0_crtc_commit(struct drm_crtc *crtc)
250{
251 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
252 u32 *push;
253
254 push = evo_wait(crtc->dev, 0, 32);
255 if (push) {
256 evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1);
257 evo_data(push, nv_crtc->fb.tile_flags);
258 evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 4);
259 evo_data(push, 0x83000000);
260 evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8);
261 evo_data(push, 0x00000000);
262 evo_data(push, 0x00000000);
263 evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1);
264 evo_data(push, MEM_VRAM);
265 evo_kick(push, crtc->dev, 0);
266 }
267
268 nvd0_crtc_cursor_show(nv_crtc, nv_crtc->cursor.visible, true);
269}
270
271static bool
272nvd0_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode,
273 struct drm_display_mode *adjusted_mode)
274{
275 return true;
276}
277
278static int
279nvd0_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb)
280{
281 struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->fb);
282 int ret;
283
284 ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM);
285 if (ret)
286 return ret;
287
288 if (old_fb) {
289 nvfb = nouveau_framebuffer(old_fb);
290 nouveau_bo_unpin(nvfb->nvbo);
291 }
292
293 return 0;
294}
295
296static int
297nvd0_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode,
298 struct drm_display_mode *mode, int x, int y,
299 struct drm_framebuffer *old_fb)
300{
301 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
302 struct nouveau_connector *nv_connector;
303 u32 htotal = mode->htotal;
304 u32 vtotal = mode->vtotal;
305 u32 hsyncw = mode->hsync_end - mode->hsync_start - 1;
306 u32 vsyncw = mode->vsync_end - mode->vsync_start - 1;
307 u32 hfrntp = mode->hsync_start - mode->hdisplay;
308 u32 vfrntp = mode->vsync_start - mode->vdisplay;
309 u32 hbackp = mode->htotal - mode->hsync_end;
310 u32 vbackp = mode->vtotal - mode->vsync_end;
311 u32 hss2be = hsyncw + hbackp;
312 u32 vss2be = vsyncw + vbackp;
313 u32 hss2de = htotal - hfrntp;
314 u32 vss2de = vtotal - vfrntp;
315 u32 hstart = 0;
316 u32 vstart = 0;
317 u32 *push;
318 int ret;
319
320 ret = nvd0_crtc_swap_fbs(crtc, old_fb);
321 if (ret)
322 return ret;
323
324 push = evo_wait(crtc->dev, 0, 64);
325 if (push) {
326 evo_mthd(push, 0x0410 + (nv_crtc->index * 0x300), 5);
327 evo_data(push, (vstart << 16) | hstart);
328 evo_data(push, (vtotal << 16) | htotal);
329 evo_data(push, (vsyncw << 16) | hsyncw);
330 evo_data(push, (vss2be << 16) | hss2be);
331 evo_data(push, (vss2de << 16) | hss2de);
332 evo_mthd(push, 0x042c + (nv_crtc->index * 0x300), 1);
333 evo_data(push, 0x00000000); /* ??? */
334 evo_mthd(push, 0x0450 + (nv_crtc->index * 0x300), 3);
335 evo_data(push, mode->clock * 1000);
336 evo_data(push, 0x00200000); /* ??? */
337 evo_data(push, mode->clock * 1000);
338 evo_mthd(push, 0x0408 + (nv_crtc->index * 0x300), 1);
339 evo_data(push, 0x31ec6000); /* ??? */
340 evo_kick(push, crtc->dev, 0);
341 }
342
343 nv_connector = nouveau_crtc_connector_get(nv_crtc);
344 nvd0_crtc_set_dither(nv_crtc, nv_connector->use_dithering, false);
345 nvd0_crtc_set_scale(nv_crtc, nv_connector->scaling_mode, false);
346 nvd0_crtc_set_image(nv_crtc, crtc->fb, x, y, false);
347 return 0;
348}
349
350static int
351nvd0_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
352 struct drm_framebuffer *old_fb)
353{
354 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
355 int ret;
356
357 ret = nvd0_crtc_swap_fbs(crtc, old_fb);
358 if (ret)
359 return ret;
360
361 nvd0_crtc_set_image(nv_crtc, crtc->fb, x, y, true);
362 return 0;
363}
364
365static int
366nvd0_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
367 struct drm_framebuffer *fb, int x, int y,
368 enum mode_set_atomic state)
369{
370 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
371 nvd0_crtc_set_image(nv_crtc, fb, x, y, true);
372 return 0;
373}
374
375static void
376nvd0_crtc_lut_load(struct drm_crtc *crtc)
377{
378 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
379 void __iomem *lut = nvbo_kmap_obj_iovirtual(nv_crtc->lut.nvbo);
380 int i;
381
382 for (i = 0; i < 256; i++) {
383 writew(nv_crtc->lut.r[i] >> 2, lut + 8*i + 0);
384 writew(nv_crtc->lut.g[i] >> 2, lut + 8*i + 2);
385 writew(nv_crtc->lut.b[i] >> 2, lut + 8*i + 4);
386 }
387}
388
389static int
390nvd0_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
391 uint32_t handle, uint32_t width, uint32_t height)
392{
393 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
394 struct drm_device *dev = crtc->dev;
395 struct drm_gem_object *gem;
396 struct nouveau_bo *nvbo;
397 bool visible = (handle != 0);
398 int i, ret = 0;
399
400 if (visible) {
401 if (width != 64 || height != 64)
402 return -EINVAL;
403
404 gem = drm_gem_object_lookup(dev, file_priv, handle);
405 if (unlikely(!gem))
406 return -ENOENT;
407 nvbo = nouveau_gem_object(gem);
408
409 ret = nouveau_bo_map(nvbo);
410 if (ret == 0) {
411 for (i = 0; i < 64 * 64; i++) {
412 u32 v = nouveau_bo_rd32(nvbo, i);
413 nouveau_bo_wr32(nv_crtc->cursor.nvbo, i, v);
414 }
415 nouveau_bo_unmap(nvbo);
416 }
417
418 drm_gem_object_unreference_unlocked(gem);
419 }
420
421 if (visible != nv_crtc->cursor.visible) {
422 nvd0_crtc_cursor_show(nv_crtc, visible, true);
423 nv_crtc->cursor.visible = visible;
424 }
425
426 return ret;
427}
428
429static int
430nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
431{
432 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
433 const u32 data = (y << 16) | x;
434
435 nv_wr32(crtc->dev, 0x64d084 + (nv_crtc->index * 0x1000), data);
436 nv_wr32(crtc->dev, 0x64d080 + (nv_crtc->index * 0x1000), 0x00000000);
437 return 0;
438}
439
440static void
441nvd0_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
442 uint32_t start, uint32_t size)
443{
444 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
445 u32 end = max(start + size, (u32)256);
446 u32 i;
447
448 for (i = start; i < end; i++) {
449 nv_crtc->lut.r[i] = r[i];
450 nv_crtc->lut.g[i] = g[i];
451 nv_crtc->lut.b[i] = b[i];
452 }
453
454 nvd0_crtc_lut_load(crtc);
455}
456
457static void
458nvd0_crtc_destroy(struct drm_crtc *crtc)
459{
460 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
461 nouveau_bo_unmap(nv_crtc->cursor.nvbo);
462 nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
463 nouveau_bo_unmap(nv_crtc->lut.nvbo);
464 nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
465 drm_crtc_cleanup(crtc);
466 kfree(crtc);
467}
468
469static const struct drm_crtc_helper_funcs nvd0_crtc_hfunc = {
470 .dpms = nvd0_crtc_dpms,
471 .prepare = nvd0_crtc_prepare,
472 .commit = nvd0_crtc_commit,
473 .mode_fixup = nvd0_crtc_mode_fixup,
474 .mode_set = nvd0_crtc_mode_set,
475 .mode_set_base = nvd0_crtc_mode_set_base,
476 .mode_set_base_atomic = nvd0_crtc_mode_set_base_atomic,
477 .load_lut = nvd0_crtc_lut_load,
478};
479
480static const struct drm_crtc_funcs nvd0_crtc_func = {
481 .cursor_set = nvd0_crtc_cursor_set,
482 .cursor_move = nvd0_crtc_cursor_move,
483 .gamma_set = nvd0_crtc_gamma_set,
484 .set_config = drm_crtc_helper_set_config,
485 .destroy = nvd0_crtc_destroy,
486};
487
488static int
489nvd0_crtc_create(struct drm_device *dev, int index)
490{
491 struct nouveau_crtc *nv_crtc;
492 struct drm_crtc *crtc;
493 int ret, i;
494
495 nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL);
496 if (!nv_crtc)
497 return -ENOMEM;
498
499 nv_crtc->index = index;
500 nv_crtc->set_dither = nvd0_crtc_set_dither;
501 nv_crtc->set_scale = nvd0_crtc_set_scale;
502 for (i = 0; i < 256; i++) {
503 nv_crtc->lut.r[i] = i << 8;
504 nv_crtc->lut.g[i] = i << 8;
505 nv_crtc->lut.b[i] = i << 8;
506 }
507
508 crtc = &nv_crtc->base;
509 drm_crtc_init(dev, crtc, &nvd0_crtc_func);
510 drm_crtc_helper_add(crtc, &nvd0_crtc_hfunc);
511 drm_mode_crtc_set_gamma_size(crtc, 256);
512
513 ret = nouveau_bo_new(dev, 64 * 64 * 4, 0x100, TTM_PL_FLAG_VRAM,
514 0, 0x0000, &nv_crtc->cursor.nvbo);
515 if (!ret) {
516 ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM);
517 if (!ret)
518 ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
519 if (ret)
520 nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
521 }
522
523 if (ret)
524 goto out;
525
526 ret = nouveau_bo_new(dev, 4096, 0x100, TTM_PL_FLAG_VRAM,
527 0, 0x0000, &nv_crtc->lut.nvbo);
528 if (!ret) {
529 ret = nouveau_bo_pin(nv_crtc->lut.nvbo, TTM_PL_FLAG_VRAM);
530 if (!ret)
531 ret = nouveau_bo_map(nv_crtc->lut.nvbo);
532 if (ret)
533 nouveau_bo_ref(NULL, &nv_crtc->lut.nvbo);
534 }
535
536 if (ret)
537 goto out;
538
539 nvd0_crtc_lut_load(crtc);
540
541out:
542 if (ret)
543 nvd0_crtc_destroy(crtc);
544 return ret;
545}
546
26f6d88b
BS
547/******************************************************************************
548 * DAC
549 *****************************************************************************/
550
551/******************************************************************************
552 * SOR
553 *****************************************************************************/
83fc083c
BS
554static void
555nvd0_sor_dpms(struct drm_encoder *encoder, int mode)
556{
557 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
558 struct drm_device *dev = encoder->dev;
559 struct drm_encoder *partner;
560 int or = nv_encoder->or;
561 u32 dpms_ctrl;
562
563 nv_encoder->last_dpms = mode;
564
565 list_for_each_entry(partner, &dev->mode_config.encoder_list, head) {
566 struct nouveau_encoder *nv_partner = nouveau_encoder(partner);
567
568 if (partner->encoder_type != DRM_MODE_ENCODER_TMDS)
569 continue;
570
571 if (nv_partner != nv_encoder &&
572 nv_partner->dcb->or == nv_encoder->or) {
573 if (nv_partner->last_dpms == DRM_MODE_DPMS_ON)
574 return;
575 break;
576 }
577 }
578
579 dpms_ctrl = (mode == DRM_MODE_DPMS_ON);
580 dpms_ctrl |= 0x80000000;
581
582 nv_wait(dev, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000);
583 nv_mask(dev, 0x61c004 + (or * 0x0800), 0x80000001, dpms_ctrl);
584 nv_wait(dev, 0x61c004 + (or * 0x0800), 0x80000000, 0x00000000);
585 nv_wait(dev, 0x61c030 + (or * 0x0800), 0x10000000, 0x00000000);
586}
587
588static bool
589nvd0_sor_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
590 struct drm_display_mode *adjusted_mode)
591{
592 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
593 struct nouveau_connector *nv_connector;
594
595 nv_connector = nouveau_encoder_connector_get(nv_encoder);
596 if (nv_connector && nv_connector->native_mode) {
597 if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) {
598 int id = adjusted_mode->base.id;
599 *adjusted_mode = *nv_connector->native_mode;
600 adjusted_mode->base.id = id;
601 }
602 }
603
604 return true;
605}
606
607static void
608nvd0_sor_prepare(struct drm_encoder *encoder)
609{
610}
611
612static void
613nvd0_sor_commit(struct drm_encoder *encoder)
614{
615}
616
617static void
618nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
619 struct drm_display_mode *adjusted_mode)
620{
621 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
622 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
623 u32 mode_ctrl = (1 << nv_crtc->index);
624 u32 *push;
625
626 if (nv_encoder->dcb->sorconf.link & 1) {
627 if (adjusted_mode->clock < 165000)
628 mode_ctrl |= 0x00000100;
629 else
630 mode_ctrl |= 0x00000500;
631 } else {
632 mode_ctrl |= 0x00000200;
633 }
634
635 nvd0_sor_dpms(encoder, DRM_MODE_DPMS_ON);
636
637 push = evo_wait(encoder->dev, 0, 2);
638 if (push) {
639 evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1);
640 evo_data(push, mode_ctrl);
438d99e3 641 evo_kick(push, encoder->dev, 0);
83fc083c
BS
642 }
643
644 nv_encoder->crtc = encoder->crtc;
645}
646
647static void
648nvd0_sor_disconnect(struct drm_encoder *encoder)
649{
650 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
651 struct drm_device *dev = encoder->dev;
438d99e3 652 u32 *push;
83fc083c
BS
653
654 if (nv_encoder->crtc) {
438d99e3
BS
655 nvd0_crtc_prepare(nv_encoder->crtc);
656
657 push = evo_wait(dev, 0, 4);
83fc083c
BS
658 if (push) {
659 evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1);
660 evo_data(push, 0x00000000);
661 evo_mthd(push, 0x0080, 1);
662 evo_data(push, 0x00000000);
663 evo_kick(push, dev, 0);
664 }
665
666 nv_encoder->crtc = NULL;
667 nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
668 }
669}
670
671static void
672nvd0_sor_destroy(struct drm_encoder *encoder)
673{
674 drm_encoder_cleanup(encoder);
675 kfree(encoder);
676}
677
678static const struct drm_encoder_helper_funcs nvd0_sor_hfunc = {
679 .dpms = nvd0_sor_dpms,
680 .mode_fixup = nvd0_sor_mode_fixup,
681 .prepare = nvd0_sor_prepare,
682 .commit = nvd0_sor_commit,
683 .mode_set = nvd0_sor_mode_set,
684 .disable = nvd0_sor_disconnect,
685 .get_crtc = nvd0_display_crtc_get,
686};
687
688static const struct drm_encoder_funcs nvd0_sor_func = {
689 .destroy = nvd0_sor_destroy,
690};
691
692static int
693nvd0_sor_create(struct drm_connector *connector, struct dcb_entry *dcbe)
694{
695 struct drm_device *dev = connector->dev;
696 struct nouveau_encoder *nv_encoder;
697 struct drm_encoder *encoder;
698
699 nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL);
700 if (!nv_encoder)
701 return -ENOMEM;
702 nv_encoder->dcb = dcbe;
703 nv_encoder->or = ffs(dcbe->or) - 1;
704 nv_encoder->last_dpms = DRM_MODE_DPMS_OFF;
705
706 encoder = to_drm_encoder(nv_encoder);
707 encoder->possible_crtcs = dcbe->heads;
708 encoder->possible_clones = 0;
709 drm_encoder_init(dev, encoder, &nvd0_sor_func, DRM_MODE_ENCODER_TMDS);
710 drm_encoder_helper_add(encoder, &nvd0_sor_hfunc);
711
712 drm_mode_connector_attach_encoder(connector, encoder);
713 return 0;
714}
26f6d88b
BS
715
716/******************************************************************************
717 * IRQ
718 *****************************************************************************/
270a5747
BS
719static void
720nvd0_display_unk1_handler(struct drm_device *dev)
721{
722 u32 unk0 = nv_rd32(dev, 0x6101d0);
723
724 NV_INFO(dev, "PDISP: unk1 0x%08x\n", unk0);
725
726 nv_wr32(dev, 0x6101d4, 0x00000000);
727 nv_wr32(dev, 0x6109d4, 0x00000000);
728 nv_wr32(dev, 0x6101d0, 0x80000000);
729}
730
731static void
732nvd0_display_unk2_handler(struct drm_device *dev)
733{
734 u32 unk0 = nv_rd32(dev, 0x6101d0);
735
736 NV_INFO(dev, "PDISP: unk2 0x%08x\n", unk0);
737
738 nv_wr32(dev, 0x6101d4, 0x00000000);
739 nv_wr32(dev, 0x6109d4, 0x00000000);
740 nv_wr32(dev, 0x6101d0, 0x80000000);
741}
742
743static void
744nvd0_display_unk4_handler(struct drm_device *dev)
745{
746 u32 unk0 = nv_rd32(dev, 0x6101d0);
747
748 NV_INFO(dev, "PDISP: unk4 0x%08x\n", unk0);
749
750 nv_wr32(dev, 0x6101d4, 0x00000000);
751 nv_wr32(dev, 0x6109d4, 0x00000000);
752 nv_wr32(dev, 0x6101d0, 0x80000000);
753}
754
4600522a
BS
755static void
756nvd0_display_intr(struct drm_device *dev)
757{
758 u32 intr = nv_rd32(dev, 0x610088);
759
760 if (intr & 0x00000002) {
761 u32 stat = nv_rd32(dev, 0x61009c);
762 int chid = ffs(stat) - 1;
763 if (chid >= 0) {
764 u32 mthd = nv_rd32(dev, 0x6101f0 + (chid * 12));
765 u32 data = nv_rd32(dev, 0x6101f4 + (chid * 12));
766 u32 unkn = nv_rd32(dev, 0x6101f8 + (chid * 12));
767
768 NV_INFO(dev, "EvoCh: chid %d mthd 0x%04x data 0x%08x "
769 "0x%08x 0x%08x\n",
770 chid, (mthd & 0x0000ffc), data, mthd, unkn);
771 nv_wr32(dev, 0x61009c, (1 << chid));
772 nv_wr32(dev, 0x6101f0 + (chid * 12), 0x90000000);
773 }
774
775 intr &= ~0x00000002;
776 }
777
270a5747
BS
778 if (intr & 0x00100000) {
779 u32 stat = nv_rd32(dev, 0x6100ac);
780
781 if (stat & 0x00000007) {
782 nv_wr32(dev, 0x6100ac, (stat & 0x00000007));
783
784 if (stat & 0x00000001)
785 nvd0_display_unk1_handler(dev);
786 if (stat & 0x00000002)
787 nvd0_display_unk2_handler(dev);
788 if (stat & 0x00000004)
789 nvd0_display_unk4_handler(dev);
790 stat &= ~0x00000007;
791 }
792
793 if (stat) {
794 NV_INFO(dev, "PDISP: unknown intr24 0x%08x\n", stat);
795 nv_wr32(dev, 0x6100ac, stat);
796 }
797
798 intr &= ~0x00100000;
799 }
800
4600522a
BS
801 if (intr & 0x01000000) {
802 u32 stat = nv_rd32(dev, 0x6100bc);
803 nv_wr32(dev, 0x6100bc, stat);
804 intr &= ~0x01000000;
805 }
806
807 if (intr & 0x02000000) {
808 u32 stat = nv_rd32(dev, 0x6108bc);
809 nv_wr32(dev, 0x6108bc, stat);
810 intr &= ~0x02000000;
811 }
812
813 if (intr)
814 NV_INFO(dev, "PDISP: unknown intr 0x%08x\n", intr);
815}
26f6d88b
BS
816
817/******************************************************************************
818 * Init
819 *****************************************************************************/
820static void
821nvd0_display_fini(struct drm_device *dev)
822{
823 int i;
824
825 /* fini cursors */
826 for (i = 14; i >= 13; i--) {
827 if (!(nv_rd32(dev, 0x610490 + (i * 0x10)) & 0x00000001))
828 continue;
829
830 nv_mask(dev, 0x610490 + (i * 0x10), 0x00000001, 0x00000000);
831 nv_wait(dev, 0x610490 + (i * 0x10), 0x00010000, 0x00000000);
832 nv_mask(dev, 0x610090, 1 << i, 0x00000000);
833 nv_mask(dev, 0x6100a0, 1 << i, 0x00000000);
834 }
835
836 /* fini master */
837 if (nv_rd32(dev, 0x610490) & 0x00000010) {
838 nv_mask(dev, 0x610490, 0x00000010, 0x00000000);
839 nv_mask(dev, 0x610490, 0x00000003, 0x00000000);
840 nv_wait(dev, 0x610490, 0x80000000, 0x00000000);
841 nv_mask(dev, 0x610090, 0x00000001, 0x00000000);
842 nv_mask(dev, 0x6100a0, 0x00000001, 0x00000000);
843 }
844}
845
846int
847nvd0_display_init(struct drm_device *dev)
848{
849 struct nvd0_display *disp = nvd0_display(dev);
efd272a7 850 u32 *push;
26f6d88b
BS
851 int i;
852
1d6e7a59
BS
853 /*XXX: wrong, and wtf is it for? */
854 for (i = 0; i < 3; i++) {
855 u32 dac = nv_rd32(dev, 0x61a000 + (i * 0x800));
856 nv_wr32(dev, 0x6101c0 + (i * 0x800), dac);
857 }
858
859 /*XXX: wrong, and wtf is it for? SOR_MODE_CTRL is an error without.. */
860 for (i = 0; i < 4; i++) {
861 u32 sor = nv_rd32(dev, 0x61c000 + (i * 0x800));
862 nv_wr32(dev, 0x6301c4 + (i * 0x800), sor);
863 }
864
26f6d88b
BS
865 if (nv_rd32(dev, 0x6100ac) & 0x00000100) {
866 nv_wr32(dev, 0x6100ac, 0x00000100);
867 nv_mask(dev, 0x6194e8, 0x00000001, 0x00000000);
868 if (!nv_wait(dev, 0x6194e8, 0x00000002, 0x00000000)) {
869 NV_ERROR(dev, "PDISP: 0x6194e8 0x%08x\n",
870 nv_rd32(dev, 0x6194e8));
871 return -EBUSY;
872 }
873 }
874
875 nv_wr32(dev, 0x610010, (disp->mem->vinst >> 8) | 9);
270a5747 876 nv_mask(dev, 0x6100b0, 0x00000307, 0x00000307);
26f6d88b
BS
877
878 /* init master */
51beb428 879 nv_wr32(dev, 0x610494, (disp->evo[0].handle >> 8) | 3);
26f6d88b 880 nv_wr32(dev, 0x610498, 0x00010000);
efd272a7 881 nv_wr32(dev, 0x61049c, 0x00000001);
26f6d88b
BS
882 nv_mask(dev, 0x610490, 0x00000010, 0x00000010);
883 nv_wr32(dev, 0x640000, 0x00000000);
884 nv_wr32(dev, 0x610490, 0x01000013);
885 if (!nv_wait(dev, 0x610490, 0x80000000, 0x00000000)) {
886 NV_ERROR(dev, "PDISP: master 0x%08x\n",
887 nv_rd32(dev, 0x610490));
888 return -EBUSY;
889 }
890 nv_mask(dev, 0x610090, 0x00000001, 0x00000001);
891 nv_mask(dev, 0x6100a0, 0x00000001, 0x00000001);
892
893 /* init cursors */
894 for (i = 13; i <= 14; i++) {
895 nv_wr32(dev, 0x610490 + (i * 0x10), 0x00000001);
896 if (!nv_wait(dev, 0x610490 + (i * 0x10), 0x00010000, 0x00010000)) {
897 NV_ERROR(dev, "PDISP: curs%d 0x%08x\n", i,
898 nv_rd32(dev, 0x610490 + (i * 0x10)));
899 return -EBUSY;
900 }
901
902 nv_mask(dev, 0x610090, 1 << i, 1 << i);
903 nv_mask(dev, 0x6100a0, 1 << i, 1 << i);
904 }
905
efd272a7
BS
906 push = evo_wait(dev, 0, 32);
907 if (!push)
908 return -EBUSY;
909 evo_mthd(push, 0x0088, 1);
910 evo_data(push, MEM_SYNC);
911 evo_mthd(push, 0x0084, 1);
912 evo_data(push, 0x00000000);
913 evo_mthd(push, 0x0084, 1);
914 evo_data(push, 0x80000000);
915 evo_mthd(push, 0x008c, 1);
916 evo_data(push, 0x00000000);
917 evo_kick(push, dev, 0);
918
26f6d88b
BS
919 return 0;
920}
921
922void
923nvd0_display_destroy(struct drm_device *dev)
924{
925 struct drm_nouveau_private *dev_priv = dev->dev_private;
926 struct nvd0_display *disp = nvd0_display(dev);
51beb428 927 struct pci_dev *pdev = dev->pdev;
26f6d88b
BS
928
929 nvd0_display_fini(dev);
930
51beb428 931 pci_free_consistent(pdev, PAGE_SIZE, disp->evo[0].ptr, disp->evo[0].handle);
26f6d88b 932 nouveau_gpuobj_ref(NULL, &disp->mem);
4600522a 933 nouveau_irq_unregister(dev, 26);
51beb428
BS
934
935 dev_priv->engine.display.priv = NULL;
26f6d88b
BS
936 kfree(disp);
937}
938
939int
940nvd0_display_create(struct drm_device *dev)
941{
942 struct drm_nouveau_private *dev_priv = dev->dev_private;
efd272a7 943 struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
83fc083c
BS
944 struct dcb_table *dcb = &dev_priv->vbios.dcb;
945 struct drm_connector *connector, *tmp;
51beb428 946 struct pci_dev *pdev = dev->pdev;
26f6d88b 947 struct nvd0_display *disp;
83fc083c
BS
948 struct dcb_entry *dcbe;
949 int ret, i;
26f6d88b
BS
950
951 disp = kzalloc(sizeof(*disp), GFP_KERNEL);
952 if (!disp)
953 return -ENOMEM;
954 dev_priv->engine.display.priv = disp;
955
438d99e3
BS
956 /* create crtc objects to represent the hw heads */
957 for (i = 0; i < 2; i++) {
958 ret = nvd0_crtc_create(dev, i);
959 if (ret)
960 goto out;
961 }
962
83fc083c
BS
963 /* create encoder/connector objects based on VBIOS DCB table */
964 for (i = 0, dcbe = &dcb->entry[0]; i < dcb->entries; i++, dcbe++) {
965 connector = nouveau_connector_create(dev, dcbe->connector);
966 if (IS_ERR(connector))
967 continue;
968
969 if (dcbe->location != DCB_LOC_ON_CHIP) {
970 NV_WARN(dev, "skipping off-chip encoder %d/%d\n",
971 dcbe->type, ffs(dcbe->or) - 1);
972 continue;
973 }
974
975 switch (dcbe->type) {
976 case OUTPUT_TMDS:
977 nvd0_sor_create(connector, dcbe);
978 break;
979 default:
980 NV_WARN(dev, "skipping unsupported encoder %d/%d\n",
981 dcbe->type, ffs(dcbe->or) - 1);
982 continue;
983 }
984 }
985
986 /* cull any connectors we created that don't have an encoder */
987 list_for_each_entry_safe(connector, tmp, &dev->mode_config.connector_list, head) {
988 if (connector->encoder_ids[0])
989 continue;
990
991 NV_WARN(dev, "%s has no encoders, removing\n",
992 drm_get_connector_name(connector));
993 connector->funcs->destroy(connector);
994 }
995
4600522a
BS
996 /* setup interrupt handling */
997 nouveau_irq_register(dev, 26, nvd0_display_intr);
998
51beb428 999 /* hash table and dma objects for the memory areas we care about */
efd272a7
BS
1000 ret = nouveau_gpuobj_new(dev, NULL, 0x4000, 0x10000,
1001 NVOBJ_FLAG_ZERO_ALLOC, &disp->mem);
26f6d88b
BS
1002 if (ret)
1003 goto out;
1004
efd272a7
BS
1005 nv_wo32(disp->mem, 0x1000, 0x00000049);
1006 nv_wo32(disp->mem, 0x1004, (disp->mem->vinst + 0x2000) >> 8);
1007 nv_wo32(disp->mem, 0x1008, (disp->mem->vinst + 0x2fff) >> 8);
1008 nv_wo32(disp->mem, 0x100c, 0x00000000);
1009 nv_wo32(disp->mem, 0x1010, 0x00000000);
1010 nv_wo32(disp->mem, 0x1014, 0x00000000);
1011 nv_wo32(disp->mem, 0x0000, MEM_SYNC);
1012 nv_wo32(disp->mem, 0x0004, (0x1000 << 9) | 0x00000001);
1013
1014 nv_wo32(disp->mem, 0x1020, 0x00000009);
1015 nv_wo32(disp->mem, 0x1024, 0x00000000);
1016 nv_wo32(disp->mem, 0x1028, (dev_priv->vram_size - 1) >> 8);
1017 nv_wo32(disp->mem, 0x102c, 0x00000000);
1018 nv_wo32(disp->mem, 0x1030, 0x00000000);
1019 nv_wo32(disp->mem, 0x1034, 0x00000000);
1020 nv_wo32(disp->mem, 0x0008, MEM_VRAM);
1021 nv_wo32(disp->mem, 0x000c, (0x1020 << 9) | 0x00000001);
1022
1023 pinstmem->flush(dev);
1024
51beb428
BS
1025 /* push buffers for evo channels */
1026 disp->evo[0].ptr =
1027 pci_alloc_consistent(pdev, PAGE_SIZE, &disp->evo[0].handle);
1028 if (!disp->evo[0].ptr) {
1029 ret = -ENOMEM;
1030 goto out;
1031 }
1032
26f6d88b
BS
1033 ret = nvd0_display_init(dev);
1034 if (ret)
1035 goto out;
1036
1037out:
1038 if (ret)
1039 nvd0_display_destroy(dev);
1040 return ret;
1041}